ADCS-003: ESC2 - Any Purpose Extended Key Usage
- Platform
- Active Directory
- Category
- AD Certificate Services
- Severity
- Critical
- Zero Trust pillar
- Identity (weight 3)
- Golden fixtures
- 3
- Branch coverage
- Observed: fixtures prove the verdicts they exercise
- Provenance
- baseline
What it checks
For every certificate template object under CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=domain,DC=tld the check reads: - pKIExtendedKeyUsage (multi-valued OID list) - msPKI-Certificate-Name-Flag (subject construction flags, in particular CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT 0x00000001) - msPKI-Enrollment-Flag (CT_FLAG_PEND_ALL_REQUESTS 0x00000002 indicates CA Manager approval) - msPKI-RA-Signature (number of authorized signatures required) - nTSecurityDescriptor (DACL: who holds Enroll and AutoEnroll) - msPKI-Template-Schema-Version, flags, and pKIDefaultKeySpec for context A template fails ADCS-003 when either pKIExtendedKeyUsage contains 2.5.29.37.0 (Any Purpose) or the attribute is absent / empty (treated as Any Purpose by the CA, matching the default SubCA template behavior), AND the DACL grants Enroll or AutoEnroll to a principal outside the Tier-0 set (Domain Admins, Enterprise Admins, SYSTEM, Enterprise PKI Admins, the CA computer account), AND msPKI-RA-Signature is 0 or 1 with no manager approval flag. The check also enumerates which Enterprise CAs publish the template via the certificateTemplates attribute on CN=Enrollment Services so a finding is only raised for templates actually issuable.
Why it matters
The Any Purpose EKU collapses the entire EKU access-control model of ADCS. Microsoft uses EKUs to gate which certificates a CA, a domain controller, or the LSA will accept for a given operation. Client Authentication (1.3.6.1.5.5.7.3.2) and Smart Card Logon (1.3.6.1.4.1.311.20.2.2) let a holder authenticate to Active Directory via PKINIT or Schannel. Certificate Request Agent (1.3.6.1.4.1.311.20.2.1) lets a holder co-sign enrollment requests on behalf of any other principal under templates that accept Enrollment Agent signatures (ESC3 chain). A single Any Purpose certificate satisfies all of these checks at once. Combined with enrollee-supplied SAN (ESC1) it is identical in impact to ESC1; combined with an enrollment-agent-accepting template it is a complete ESC3 attack without needing a separate Certificate Request Agent template; combined with code signing it lets the holder forge driver, script, and binary signatures trusted by every domain-joined endpoint. The blast radius is forest-wide, and the certificate validity period (often 1-2 years) creates a persistence primitive that survives password rotation of every account it impersonates, because PKINIT keys are decoupled from passwords.
Attack path
1. Reconnaissance: the attacker enumerates published templates with Certipy (certipy find -u user@corp.contoso.com -p Password -dc-ip 10.0.0.10 -vulnerable) or Certify (Certify.exe find /vulnerable). Both tools flag ESC2 directly by parsing pKIExtendedKeyUsage for the Any Purpose OID and cross-checking the DACL. 2. Target selection: the attacker picks an ESC2-vulnerable template where Domain Users or Authenticated Users hold Enroll, and where no CA Manager approval is required. 3. Enrollment for ESC3 chaining: if the template is ESC2 the attacker requests a certificate as themselves, then uses it as an Enrollment Agent to enroll on behalf of a Domain Admin against any template that accepts Enrollment Agent signatures. Certipy: certipy req -u user@corp.contoso.com -p Password -ca CORP-CA -template AnyPurposeTemplate, then certipy req -ca CORP-CA -template User -on-behalf-of "CORP\Administrator" -pfx user.pfx. 4. PKINIT authentication: the attacker uses the resulting Administrator PFX to perform Kerberos PKINIT and obtain a TGT for the Domain Admin. Certipy: certipy auth -pfx administrator.pfx. The output includes the NT hash recovered via UnPAC-the-Hash plus a usable TGT. 5. Domain Admin actions: with the TGT or the NT hash the attacker performs DCSync (secretsdump.py -just-dc), creates a Golden Ticket from the krbtgt hash, or simply logs on interactively. 6. Persistence: the issued certificate remains valid for the full template lifetime regardless of password changes. The attacker can re-authenticate as the impersonated principal at any point until the certificate is revoked AND the revocation reaches NTAuth-side CRL or OCSP checking, which many environments do not enforce strictly. 7. Optional code-signing pivot: the same certificate can be used to sign malicious PowerShell scripts, MSI installers, or kernel drivers that AppLocker, WDAC, or kernel signing policies will accept as trusted publisher content.
How Guerrilla assesses it
Guerrilla queries the Configuration NC over LDAP for objectClass=pKICertificateTemplate beneath CN=Certificate Templates,CN=Public Key Services,CN=Services. For each template it reads pKIExtendedKeyUsage, msPKI-Certificate-Name-Flag, msPKI-Enrollment-Flag, msPKI-RA-Signature, and nTSecurityDescriptor. The OID list is evaluated for the literal Any Purpose value 2.5.29.37.0 and for empty / null state. The DACL is parsed via the .NET ActiveDirectorySecurity surface and every ACE granting the Certificate-Enrollment extended right (GUID 0e10c968-78fb-11d2-90d4-00c04f79dc55) or Certificate-AutoEnrollment (GUID a05b8cc2-17bc-4802-a710-e7c15ab866a2) is resolved to a principal. Templates are intersected with the list pulled from CN=Enrollment Services so unpublished templates are reported as informational rather than critical. The check returns the template CN, displayName, OID, the offending EKU state, the principals with enroll rights, manager-approval state, RA signature count, and the issuing CA(s). The detection mirrors the logic used by Certipy find and Certify so output is directly comparable to red-team tool runs.
Recommended value
No certificate templates with Any Purpose EKU or empty EKU that allow low-privileged enrollment
Remediation
Identify templates where pKIExtendedKeyUsage contains the Any Purpose OID (2.5.29.37.0) or is empty, and enrollment is permitted for non-admin users. Replace the Any Purpose EKU with specific required EKUs (e.g., Client Authentication only). If a SubCA template, restrict enrollment to Enterprise Admins only. Implement CA Manager approval for any remaining templates with broad EKUs.
Fixture-proven verdicts
Every verdict below is proven by a golden fixture in the module's gating test suite. This table derives from the last green run; it cannot be edited by hand.
| Scenario | Expected verdict |
|---|---|
| clean | PASS |
| known-bad | FAIL |
| throttled | Not Assessed |
Framework mappings
- NIST SP 800-53
- AC-6, IA-5(2), CM-6
- ANSSI
- vuln_adcs_esc2
- MITRE ATT&CK
- T1649, T1556