A misconfigured signing booth at the corporate ID office that will hand a domain-user badge to anyone who fills the form out sideways
CVE-2026-54121 is an improper authorization bug (CWE-285) in the certificate enrollment pipeline of Active Directory Certificate Services. Any authenticated domain principal — including low-privileged users and low-value machine accounts — can coerce the CA into issuing a certificate that authenticates as a higher-privileged account, up to and including domain controllers. The bug affects the AD CS role on Windows Server 2012 R2, 2016, 2019, 2022, and 2025, plus shared code paths in Windows 10 1607/1809. Fixed builds land in the July 14, 2026 rollups: Server 2025 26100.33158 (KB5099536), Server 2022 20348.5386 (KB5099540), Server 2019 17763.9020 (KB5099538), and Server 2016 14393.9339 (KB5099535); 2012/2012 R2 receive parity fixes via ESU.
Microsoft's 8.8 / HIGH label is defensible on paper — PR:L, AV:N, no UI — but it misses the *role multiplier*. AD CS is the trust root. Every prior AD CS EoP class (ESC1–ESC13, Certifried/CVE-2022-26923, ESC15) has ended in the same place: silver-bullet certificates that unlock Kerberos as any principal. This one behaves the same way. Reassessed to CRITICAL 9.6 because the affected component is a canonical high-value-role component and the chain terminates in domain compromise.
5 steps from start to impact.
Obtain any authenticated domain foothold
ms-DS-MachineAccountQuota=10 by default). No local admin, no interactive session required. Weaponized tooling: impacket-addcomputer.py or StandIn for machine-account creation, or credentials harvested via Rubeus / Mimikatz roasting on any weak SPN.- Network reachability to a domain controller (Kerberos/LDAP)
- One valid domain credential of ANY privilege tier
- MachineAccountQuota hardened to 0 blocks unprivileged machine creation
- Tiered admin model limits initial phishing yield to Tier 2 users
Locate the AD CS enrollment endpoint
pKIEnrollmentService objects under CN=Enrollment Services,CN=Public Key Services,CN=Services,CN=Configuration,DC=… to enumerate every enterprise CA plus its DNS name and published templates. Weaponized tooling: Certipy find or Certify.exe find /vulnerable. This is unauthenticated-once-domain-joined; every domain user can read Configuration NC.- Read access to the Configuration naming context (default for authenticated users)
- Segmented CA tier where CA is not LDAP-visible is rare in the wild
pKIEnrollmentService is trivially loggable but almost never alertedTrigger the improper authorization path in enrollment
ICertRequest::Request over \\CA\pipe\cert or the certsrv web endpoint) crafted to bypass the CA's identity-binding check. The CA issues a certificate whose SAN / UPN / DNS field points at a higher-privileged principal — a Tier-0 user or a domain controller machine account. Weaponized tooling: expect a Certipy module (certipy req -template <T> -upn administrator@…) within weeks, modeled on the ESC1/ESC15 flows.- A published template the low-priv identity can enroll against
- AD CS role unpatched (pre-July 2026 build)
- Templates locked to
msPKI-Certificate-Name-Flag=0and manager-approval requirements slow but historically do not fully stop these classes - CAs behind an internal HSM that logs every issuance
Authenticate as the impersonated principal via PKINIT
- Domain controllers accept PKINIT (default when AD CS is deployed)
- The impersonated principal exists
- Strong Certificate Mapping enforcement mode (May 2022 KB5014754 + 2025 hardening) rejects certificates without the SID extension — this DOES blunt some ESC-class chains, unknown yet whether -54121 evades it
Escalate to DCSync / DA
- TGT for a principal with replication rights or DC identity
- None material once step 4 succeeds — this is the terminal outcome
The supporting signals.
| In-the-wild exploitation | No confirmed campaigns as of 2026-07-24, but AD CS EoP class historically weaponizes within 2–6 weeks of disclosure (see CVE-2022-26923 Certifried, ESC1–ESC13 timeline) |
|---|---|
| Public PoC | None public yet; expect a Certipy module and a SpecterOps writeup on the ESC# taxonomy shortly |
| EPSS | 0.00785 (~50th percentile) — misleadingly low because EPSS lags AD CS-class bugs badly; treat as noise |
| KEV status | Not listed as of 2026-07-24 |
| CVSS vector | CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H — Scope:Unchanged undersells the AD-wide blast radius |
| Affected roles | Windows Server 2012 R2 / 2016 / 2019 / 2022 / 2025 with the AD CS Certification Authority role installed; also Windows 10 1607/1809 shared code |
| Fixed builds | Server 2025 26100.33158 (KB5099536), 2022 20348.5386 (KB5099540), 2019 17763.9020 (KB5099538), 2016 14393.9339 (KB5099535); 2012/2012 R2 via July 2026 ESU |
| Exposure population | AD CS is deployed in an estimated >60% of enterprise AD environments (SpecterOps / TrustedSec surveys); vast majority reachable from any domain-joined host |
| Disclosure | 2026-07-14, Microsoft July Patch Tuesday |
| Reporter | Credit per MSRC advisory (see sources); researchers active in AD CS space include Will Schroeder, Lee Christensen, Oliver Lyak |
noisgate verdict.
Upgraded from HIGH 8.8 to CRITICAL because of the role multiplier: the affected component is Active Directory Certificate Services, a canonical Tier-0 identity-and-trust asset, and the documented chain terminates in domain-controller impersonation via PKINIT — i.e., fleet-scale compromise from any authenticated domain foothold. Every prior improper-authorization bug in AD CS enrollment (Certifried, ESC1, ESC15) has become a reliable domain-takeover primitive within weeks, and there is no reason this class behaves differently.
Why this verdict
- Role multiplier: AD CS IS the Tier-0 trust root. Documented chain succeeds in the canonical high-value role (enterprise CA issuing auth certs for the forest); blast radius is fleet + identity + persistence via silver-bullet certs. Verdict floor is CRITICAL by the deployment-role rule.
- Prerequisite tax is trivial: PR:L means *any* domain principal, and MachineAccountQuota=10 default lets an attacker manufacture that principal from a single phished credential. The 'authenticated' friction that would downgrade a normal EoP does not apply here.
- Historical base rate: Every AD CS improper-authz / template-abuse class since 2021 (Certifried, ESC1, ESC8 relay, ESC15) reached weaponized public tooling within 60 days and became a preferred APT and ransomware primitive.
- Persistence multiplier: Certificates issued during the exploitation window remain valid for years and survive password resets and full krbtgt rotation unless explicitly revoked — this is a compounding downward pressure on time-to-recover.
- No compensating friction on the target side: AD CS is on the LAN by definition; there is no WAF, no email gateway, no MFA layer between a domain user and
\\CA\pipe\cert.
Why not higher?
Not scored a 10.0 because we have not yet confirmed the bypass evades Strong Certificate Mapping enforcement mode (KB5014754 Full Enforcement, mandatory since Feb 2025), which would blunt exploitation on hardened forests. If a public PoC lands showing SCM bypass, this becomes a 10.0.
Why not lower?
Cannot be dropped to HIGH: the deployment-role floor forbids it. AD CS is by definition a Tier-0 asset and the chain terminates in DA in the canonical deployment, so friction cannot pull the verdict below CRITICAL without evidence that <1% of installed AD CS servers are actually exploitable — no such evidence exists.
What to do — in priority order.
- Set
ms-DS-MachineAccountQuotato 0 forest-wide — Removes the cheapest path for a low-priv user to manufacture a fresh principal to enroll from. Deploy within the noisgate CRITICAL 3-day mitigation window via a domain-wideSet-ADDomain -Replace @{'ms-DS-MachineAccountQuota'=0}. Delegate machine-join to a controlled service account. - Enforce Strong Certificate Mapping (KB5014754) Full Enforcement mode — Set
StrongCertificateBindingEnforcement=2on every domain controller andCertificateMappingMethodsto require SID-extension binding. This rejects PKINIT with certificates that lack a bound SID — the same defense that neutered Certifried. Deploy within 3 days. - Disable NTLM and web enrollment on the CA; require HTTPS + EPA where enrollment is exposed — Cut the ESC8 / web-enroll amplification surface. Registry: on the CA,
certutil -setreg CA\InterfaceFlags +IF_ENFORCEENCRYPTICERTREQUEST. Kill IIS binding to HTTP oncertsrvvdir. - Audit and lock every certificate template — Run
Certify.exe find /vulnerableorcertipy findfrom a low-priv account TODAY. Any template withCT_FLAG_ENROLLEE_SUPPLIES_SUBJECT+ client-auth EKU + broad enroll ACL is a bomb regardless of this CVE. Fix inside 3 days. - Enable and forward CA audit logs (event IDs 4886/4887) to SIEM with SAN-mismatch analytics — Get eyes on every issued certificate whose SAN/UPN does not match the requesting principal. This is the highest-fidelity indicator for exploitation of this class.
- Patch every AD CS server to the July 2026 build — This is the remediation, not the mitigation. Apply KB5099536/5099540/5099538/5099535 (or ESU equivalents) to every CA inside the noisgate CRITICAL 90-day remediation SLA, targeting <30 days for CAs given the role.
- EDR on the domain controller — the exploitation traffic is normal Kerberos and normal RPC; there is no shellcode or process anomaly to alert on.
- Perimeter firewall / WAF — attack is fully intra-domain; the perimeter never sees it.
- MFA on user login — a single MFA-protected user account, once compromised, still has the domain rights needed to trigger the chain. MFA does not gate LDAP or RPC to the CA.
- Krbtgt password rotation alone — does NOT invalidate misissued certificates. You must revoke the certs at the CA and rebuild trust if compromise is suspected.
- Rotating the compromised user's password — the attacker persists via the certificate, not the password.
Crowdsourced verification payload.
Run this on each domain controller and each AD CS server as a Domain Admin (or member of local Administrators on the CA). It checks the OS build against the July 2026 patched builds and verifies whether the AD CS role is installed. Invoke: powershell -ExecutionPolicy Bypass -File .\Check-CVE-2026-54121.ps1. Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN.
#requires -RunAsAdministrator
# Check-CVE-2026-54121.ps1
# Verifies patch level for CVE-2026-54121 (AD CS improper authorization, July 2026)
$ErrorActionPreference = 'Stop'
# Fixed build minimums per KB (build.revision)
$fixedBuilds = @{
'10.0.26100' = 33158 # Server 2025 - KB5099536
'10.0.20348' = 5386 # Server 2022 - KB5099540
'10.0.17763' = 9020 # Server 2019 - KB5099538
'10.0.14393' = 9339 # Server 2016 - KB5099535
'6.3.9600' = 23291 # Server 2012 R2 ESU
'6.2.9200' = 26226 # Server 2012 ESU
}
try {
$os = Get-CimInstance Win32_OperatingSystem
$ver = [Version]$os.Version
$key = "{0}.{1}.{2}" -f $ver.Major, $ver.Minor, $ver.Build
# Detect AD CS role
$adcs = $false
try {
$role = Get-WindowsFeature -Name AD-Certificate -ErrorAction SilentlyContinue
if ($role -and $role.Installed) { $adcs = $true }
} catch {}
# Also check for CertSvc service (works on non-server SKUs)
if (-not $adcs) {
$svc = Get-Service -Name CertSvc -ErrorAction SilentlyContinue
if ($svc) { $adcs = $true }
}
Write-Host "Host: $($env:COMPUTERNAME)"
Write-Host "OS Version: $($os.Caption) ($key.$($ver.Revision))"
Write-Host "AD CS role: $adcs"
if (-not $adcs) {
Write-Host "RESULT: NOT_APPLICABLE (AD CS role not present) — still patch as part of monthly rollup." -ForegroundColor Yellow
}
if (-not $fixedBuilds.ContainsKey($key)) {
Write-Host "RESULT: UNKNOWN — unrecognized OS build $key" -ForegroundColor Yellow
exit 2
}
$required = $fixedBuilds[$key]
$actual = [int]$ver.Revision
if ($actual -ge $required) {
Write-Host "RESULT: PATCHED (revision $actual >= required $required)" -ForegroundColor Green
exit 0
} else {
Write-Host "RESULT: VULNERABLE (revision $actual < required $required)" -ForegroundColor Red
if ($adcs) { Write-Host "CRITICAL: AD CS role is installed and unpatched. Apply July 2026 rollup within 3 days." -ForegroundColor Red }
exit 1
}
} catch {
Write-Host "RESULT: UNKNOWN — $($_.Exception.Message)" -ForegroundColor Yellow
exit 2
}
If you remember one thing.
Get-ADObject -SearchBase "CN=Enrollment Services,CN=Public Key Services,CN=Services,$((Get-ADRootDSE).ConfigurationNamingContext)" -Filter *), confirm Strong Certificate Mapping is in Full Enforcement (KB5014754), drop ms-DS-MachineAccountQuota to 0, and audit templates with Certipy/Certify. Under the noisgate mitigation SLA for CRITICAL you have ≤3 days to have those compensating controls in place; under the noisgate remediation SLA you have ≤90 days to fully patch every CA to the July 2026 builds (KB5099536/5099540/5099538/5099535 or ESU equivalents) — but given the role, target every CA inside 21 days. If a Certipy module drops publicly before then, treat as active exploitation and cut the mitigation window to hours.Sources
- NVD — CVE-2026-54121
- CrowdStrike — July 2026 Patch Tuesday Analysis
- Windows News — Microsoft's July 2026 Update Fixes AD CS Flaw
- Windows News — Patch Your Domain Controllers Now
- CrowdStrike — Investigating AD CS Abuse: ESC1
- Wolf & Company — How Attackers Exploit AD CS
- SpecterOps — Certified Pre-Owned (ESC1–ESC8 whitepaper)
- MSRC — KB5014754 Certificate-based Kerberos authentication changes
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.