Enumeration
Start with Certipy’s vulnerable scan to quickly identify exploitable templates: it checks all known ESC conditions in one pass.ESC1: Enrollee Supplies Subject
Conditions:- Low-priv user can enrol
- No Manager Approval
- No Authorised Signatures
- Client Authentication EKU enabled
- Template allows user to specify SAN (subjectAltName)
ESC2: Any Purpose EKU
Conditions:- Low-priv user can enrol
- No Manager Approval
- No Authorised Signatures
- Template has
Any PurposeEKU or no EKU at all
ESC3: Enrolment Agent
Conditions:- Template has
Certificate Request AgentEKU - Another template allows enrolment agent to enrol on behalf of others
ESC4: Writable Template
Conditions:- You have write rights on a certificate template: Owner, Write Owner, Write DACL, or Write Property
ESC5: Vulnerable PKI Object Access Control
Conditions:- Write permissions on PKI AD objects under
CN=Public Key Services,CN=Services,CN=Configuration,... - Objects in scope: NTAuthCertificates, Enrollment Services objects, CA objects, certificate templates container, AIA/CDP containers
ESC6: EDITF_ATTRIBUTESUBJECTALTNAME2
Conditions:- CA has
EDITF_ATTRIBUTESUBJECTALTNAME2flag set - Any template with Client Authentication EKU is exploitable
ESC7: Vulnerable CA ACL
Conditions:- You have
ManageCAorManageCertificatesrights on the CA
ESC8: Relay to AD CS HTTP
AD CS HTTP enrolment (/certsrv/certfnsh.asp) can be abused via both NTLM and Kerberos relay. The coercion and cert auth steps are the same for both; what differs is the relay tool and the prerequisite.
NTLM Relay
Conditions:- AD CS HTTP enrolment endpoint enabled
- SMB signing disabled on the coerced host
ntlmrelayx.py:
Kerberos Relay (krbrelayx)
Conditions:- AD CS HTTP enrolment endpoint enabled
- EPA (Extended Protection for Authentication) not enforced on certsrv (default on most installs)
- SMB signing state does not matter
CREDENTIAL_TARGET_INFORMATION structure. When the DC tries to connect to that hostname, Windows internally calls CredMarshalTargetInfo which appends a Base64-encoded struct to the SPN, producing a hostname like DC-NETBIOS1UWhRCAA.... DNS resolves that to your listener, so the DC sends its AP-REQ to you instead.
1
Start krbrelayx
2
Add a malicious DNS record
The hostname is the DC’s NetBIOS name with the fixed marshalled CREDENTIAL_TARGET_INFO suffix appended. bloodyAD registers it in AD DNS pointing at your listener.
3
Coerce DC authentication
Trigger the DC to authenticate to the malicious hostname. Any coercion tool works.
ERROR_BAD_NETPATH is the expected response and means the coercion fired successfully.4
Authenticate with the obtained cert
krbrelayx catches the AP-REQ, relays it to certsrv, and writes the PFX to disk.
ESC9: No Security Extension
Conditions:- Template has
CT_FLAG_NO_SECURITY_EXTENSIONflag (NoSecurityExtensionin Certipy output) StrongCertificateBindingEnforcement= 0 (Disabled) or 1 (Compatibility) on DCs — not 2 (Full Enforcement)- You have GenericWrite on a victim account that can enrol on the template
ESC10: Weak Certificate Mapping for Schannel Authentication
Conditions:CertificateMappingMethodson the target DC includes the0x4bit (UPN mapping for Schannel)- You have GenericWrite on a victim account that can enrol for a client auth cert
- The template does not need to be ESC9 — the victim’s cert SID is already present; Schannel’s UPN mapping ignores it when
0x4is set
CertificateMappingMethods registry key (HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\) on the DC governs how TLS client certificates are mapped to accounts. With the 0x4 bit set, the DC maps by UPN — so a cert whose SAN UPN is dc$@corp.local authenticates as the DC machine account even if the cert’s embedded SID belongs to the victim.
The typical target is a DC’s machine account (DC$) because machine accounts don’t have a UPN by default, so their sAMAccountName (DC01$) is free to collide.
ESC10 authenticates via Schannel (LDAPS port 636).
StrongCertificateBindingEnforcement (Kerberos PKINIT enforcement) is irrelevant here — Schannel maps independently via CertificateMappingMethods. A DC with PKINIT in Full Enforcement but CertificateMappingMethods including 0x4 is still vulnerable to ESC10.ESC11: IF_ENFORCEENCRYPTICERTREQUEST
Conditions:- CA has
IF_ENFORCEENCRYPTICERTREQUESTnot set - Allows NTLM relay over RPC (not just HTTP)
ESC12: YubiHSM2 Vulnerability
Conditions:- CA uses a YubiHSM2 for its private signing keys
- Attacker has low-privileged shell access on the CA server
- A flaw in the YubiHSM2 KSP/driver allows a low-priv process to trigger signing operations
General CA compromise (admin/SYSTEM on the CA server via any path) combined with
certipy ca -backup and certipy forge is documented under ESC5 post-exploitation. ESC12 specifically refers to the YubiHSM2 local-privilege flaw researched by Hans-Joachim Knobloch.ESC13: OID Group Link
Conditions:- Principal has enrolment rights on the template
- Template has an issuance policy in
msPKI-Certificate-Policy - That issuance policy has
msDS-OIDToGroupLinkpointing to a privileged universal group - The linked group is empty and has universal scope
- Template has a client authentication EKU
ESC14: Explicit Certificate Mapping
Conditions (ESC14A):- Write access on a target account’s
altSecurityIdentitiesattribute
altSecurityIdentities is the explicit certificate-to-account binding attribute. You map a certificate you control to a target account, then authenticate as that account using your cert. The serial number must be hex-reversed in the mapping format.
ESC15: Arbitrary Application Policy Injection
Conditions:- Template has schema version 1
- Principal has enrolment rights
- No manager approval required
1.3.6.1.4.1.311.20.2.1) into any enrollable v1 template turns it into an enrolment agent cert, enabling the ESC3 step-2 chain.
ESC16: CA-Wide SID Extension Removal
Conditions:- CA has
szOID_NTDS_CA_SECURITY_EXT(OID1.3.6.1.4.1.311.25.2) in itsDisableExtensionList StrongCertificateBindingEnforcementis not 2 on DCs, or KB5014754 not applied