ADCS Misconfigurations: Understanding ESC1 and ESC3
Two of the most common Active Directory Certificate Services escalation paths, why they exist, and how they map onto certificate template permissions.
Active Directory Certificate Services (ADCS) is, by default, deeply trusted: a valid certificate can be used to authenticate as the identity it names, via PKINIT. That trust is exactly what makes misconfigured certificate templates so dangerous — a template that lets the wrong people request the wrong kind of certificate becomes a direct path to impersonating anyone in the domain, including Domain Admins.
ESC1 through ESC11 is a naming convention introduced by the original ADCS research (Certified Pre-Owned) to catalog distinct misconfiguration classes. ESC1 and ESC3 are two of the most frequently encountered in real environments.
ESC1 — client authentication + attacker-supplied SAN
A template is vulnerable to ESC1 when all of the following are true:
- The template allows client authentication (has the Client Authentication or Smart Card Logon EKU).
- Enrollee-supplied subject is enabled, meaning the requester can specify the Subject Alternative Name (SAN) on the certificate request rather than it being derived from their own AD identity.
- A low-privileged principal has enrollment rights on the template.
Put together: any domain user who can enroll can request a certificate that names someone else — including a Domain Admin — as the subject, and then authenticate as that identity.
certipy find -u user@domain.local -p 'Passw0rd!' -dc-ip 10.10.10.10 -vulnerable
Certipy’s find -vulnerable flag flags templates matching known ESC patterns directly, which is almost
always the starting point rather than manually diffing template ACLs.
certipy req -u user@domain.local -p 'Passw0rd!' -ca CORP-CA -template VulnTemplate \
-upn administrator@domain.local
The resulting certificate can be used with PKINIT to obtain a TGT for the impersonated principal.
Requesting a certificate in someone else’s name is a high-impact action in a live environment. This is squarely the kind of step that belongs in an authorized, scoped engagement with clear rules of engagement — not something to test against infrastructure you don’t have explicit permission to assess.
ESC3 — enrollment agent templates
ESC3 revolves around certificate request agent templates — templates meant for legitimate use cases like smart card issuance, where an enrollment agent requests a certificate on behalf of another user.
The misconfiguration: if a low-privileged principal has enrollment rights on an agent template, and a second template exists that permits enrollment agents to request on behalf of any user, that principal can chain the two — enroll as an agent, then request a certificate on behalf of a privileged account.
certipy req -u user@domain.local -p 'Passw0rd!' -ca CORP-CA -template AgentTemplate
certipy req -u user@domain.local -p 'Passw0rd!' -ca CORP-CA -template UserTemplate \
-on-behalf-of 'DOMAIN\administrator' -pfx agent.pfx
The distinction from ESC1 matters operationally: ESC3 doesn’t require enrollee-supplied SANs at all — it abuses the agent mechanism, which is designed to act on behalf of others.
Comparing the two
| ESC1 | ESC3 | |
|---|---|---|
| Root cause | Enrollee-supplied SAN + client auth EKU | Enrollment agent template chaining |
| Requires two templates | No | Yes |
| Typical trigger | Over-permissive single template | Agent template + target template combo |
| Detection surface | Certificate requests with mismatched requester/subject | Certificates issued via on-behalf-of requests |
Hardening ADCS
- Audit template permissions with
certipy findor the PSPKI module — enrollment rights should map to an explicit business need, not “Domain Users” by default. - Disable enrollee-supplied subject on any template with a client authentication EKU unless there’s a specific, documented reason it’s needed.
- Restrict agent templates to a small, monitored set of principals — agent enrollment is powerful by design and should be treated like a Tier 0 capability.
- Enable ADCS auditing (CA role auditing plus Event ID 4886/4887) to catch unusual issuance patterns,
particularly
on-behalf-ofrequests against high-value UPNs.
ADCS findings are consistently high-severity precisely because certificates don’t expire the way a password reset would fix — once a template is fixed, previously issued rogue certificates still need to be explicitly revoked to fully close the path.