← Back to blog

Detecting ADCS ESC1-15 attacks before they happen

2026-04-27 · Research · 12 min read

ESC1 through ESC15 (SpecterOps Certified Pre-Owned) is the canonical attack family against Active Directory Certificate Services. From SAN-supply forgery to EKUwu (CVE-2024-49019), every ESC variant ends the same way: an attacker who could not get past the front door walks out with a Domain-Admin-bearing certificate.

This post walks through how Obexum detects every variant determinístically — no LLM, no fuzzy matching, no false positives on a clean install. The full check catalogue is in /docs/checks; this post is the methodology.

The detection contract

For every ESC variant we needed three things:

Worked example: ESC1 detection

ESC1 is the canonical “requester supplies arbitrary SAN” attack. The probe looks like:

# LDAP filter for ESC1-shape templates
filter = '(&(objectClass=pKICertificateTemplate)' \
       '(msPKI-Certificate-Name-Flag:1.2.840.113556.1.4.803:=1)' \
       '(|(pkiExtendedKeyUsage=1.3.6.1.5.5.7.3.2)' \
        '(pkiExtendedKeyUsage=1.3.6.1.4.1.311.20.2.2)' \
        '(pkiExtendedKeyUsage=2.5.29.37.0)' \
        '(pkiExtendedKeyUsage=1.3.6.1.5.2.3.4)))'

That is the signature. But every version of Server 2022 ships templates that match this filter on the schema side (User, Workstation, Machine, WebServer) without being exploitable — because they are not published by the CA, or because their ACL only grants enroll to high-priv principals.

So the probe adds two gates after the LDAP match:

Only when both gates resolve to true does the check fire. On a clean Server 2022 promotion: zero matches. On a forest with the synthetic OBX_ESC1_AltSAN template installed: 1 match, exactly. No false positives, no missed paths.

The same pattern across ESC1-15

Every variant has its own signature + gates. ESC4 detects ACL tampering with a strict broad-principal allowlist (not a Tier0 negative list, because Tier0 is fluid and easy to miss). ESC8 excludes web-enrollment EPA evaluation when the IIS site is simply not deployed. ESC9 only fires after the published-and- low-priv gate. ESC15 (CVE-2024-49019, "EKUwu") combines schema version 1 + SAN supply + the same gates.

All of this is shipped Go code with full evidence preservation. The probe stdout for every check goes into the engagement directory under artifacts/<rule_id>/ so an auditor can replay the exact LDAP query that produced the finding.

Why this beats vuln scanners

A traditional vulnerability scanner can flag “ADCS template with SAN-supply enabled” based on a registry or LDAP read. That gets you the candidate set. It does not get you the published-and-low-priv intersection — and that is where the noise lives. We see Tenable / Qualys output dozens of “ADCS template misconfigured” findings on every fresh Server 2022 install, all of them legitimate Microsoft templates that simply happen to match the signature. The auditor learns to ignore them. Then the actual ESC1 backdoor sails past in the same noise floor.

Zero false positives is not a vanity number. It is the precondition for the operator to actually read the report.

Read more