AD-ADCS-002: ESC2: any-purpose or no-EKU template¶
high Certificate services MITRE ATT&CK T1649 Reads: LDAP
A published certificate template that broad groups can enroll in has the Any Purpose EKU or no EKU at all, so its certificates are valid for any use.
Also known as: esc2
Why it matters¶
The extended key usage (EKU) of a certificate says what it may be used for. A template
with the Any Purpose EKU (2.5.29.37.0) issues certificates that every application
accepts for every purpose: client and server authentication, code signing and, most
importantly, Certificate Request Agent. A template with no EKU at all issues
what is in effect a subordinate CA certificate, which can sign new certificates of its
own.
The requester's own identity is still built from Active Directory, so the danger is in what the certificate can do next:
- An Any Purpose certificate acts as an enrollment agent: its holder can request certificates on behalf of other users, including a domain admin, through any template that accepts agent-signed requests (the second half of ESC3, see AD-ADCS-003).
- A no-EKU certificate can sign certificates for any name. Those are not in
NTAuthCertificates, so domain controllers refuse them for Kerberos logon, but every system that trusts the enterprise root for TLS or code signing accepts them.
When the same template also lets the enrollee supply the subject, it is plain ESC1 and is also reported by AD-ADCS-001.
How ad-doctor detects it¶
ad-doctor reads every certificate template and the enterprise CAs over LDAP and reports a template when all of these hold:
| Condition | Attribute |
|---|---|
| Published on at least one enterprise CA | certificateTemplates of a CA object |
| No manager approval | msPKI-Enrollment-Flag without CT_FLAG_PEND_ALL_REQUESTS (0x2) |
| No authorized signatures | msPKI-RA-Signature is 0 |
| A broad group can enroll | Enroll or AutoEnroll in the template DACL for Everyone, Anonymous Logon, Authenticated Users, BUILTIN\Users, Pre-Windows 2000 Compatible Access, Domain Users, Domain Guests or Domain Computers |
| Any purpose | the EKU list contains 2.5.29.37.0, or is empty |
The EKU list is msPKI-Certificate-Application-Policy when it is set (schema v2 and
later), otherwise pKIExtendedKeyUsage. Each object names the template and the broad
groups that can enroll, for example LabESC2 (enroll: Domain Users).
Attributes and probes read
pKIExtendedKeyUsagemsPKI-Certificate-Application-PolicymsPKI-Enrollment-FlagmsPKI-RA-SignaturenTSecurityDescriptor (template DACL)certificateTemplates (on pKIEnrollmentService)
Severity¶
Always high: one request gives any domain user a certificate usable as an enrollment agent or a subordinate CA.
False positives and limits¶
- The built-in SubCA template has no EKU, but by default only Domain Admins and Enterprise Admins can enroll, so it is not reported unless a broad group was added.
- Narrower enrollment groups are not reported here; their members can still abuse the template. AD-PATH-001 follows enrollment rights from any principal.
- CA-side controls that LDAP cannot see, such as a policy module that rewrites the extensions, are not taken into account.
Fix¶
Apply at least one of these, in order of preference:
-
Give the template explicit EKUs. In
certtmpl.msc, open the template, Extensions tab, Application Policies, remove Any Purpose and add only what the template is for. Schema v1 templates cannot be edited: duplicate them, fix the copy, and have it supersede the original. -
Restrict enrollment to the group that needs the template. In the Security tab, remove Enroll and Autoenroll from Domain Users, Domain Computers, Authenticated Users and Everyone.
-
Require CA manager approval (sets
CT_FLAG_PEND_ALL_REQUESTS): -
Stop publishing a template nobody needs (run on the CA):
Then review the CA's Issued Certificates for this template and revoke certificates
that were used to request others on someone's behalf (certutil -revoke <serial> 1).
Verify¶
To accept the risk instead, add an entry to the file passed with --accept (see accepted risks):
[[accept]]
check = "AD-ADCS-002"
objects = ["..."] # optional; without it the whole check is accepted
reason = "..."
expires = 2027-03-31
Related checks¶
References¶
Microsoft and vendors
- Defender for Identity: Edit overly permissive certificate template with privileged EKU (ESC2)
- Remove-CATemplate
Research
Tools
MITRE ATT&CK
Available since 0.1.0.