Certighost: patch the CA, then kill the chase fallback
The AD CS flaw where the requester picked which server the CA phoned to verify them. Patch, then disable the chase fallback on anything that doesn't need it.
01 The Big PictureFor leadership · no jargon
Okay, so Certighost: the one where your certificate authority takes identity advice from the person asking for the certificate. This guide walks through what it actually is, how to check you're not exposed, and the tidy-up that comes after patching: switching off the fallback behaviour that made it possible.
Active Directory Certificate Services (AD CS) is the bit of Windows that issues digital certificates, signed ID cards that machines and users present to prove who they are. When a request comes in, the CA sometimes has to look the requester up in a different corner of the directory, so it phones another server to ask. Certighost, disclosed on July 24, 2026, is the discovery that the requester got to pick the phone number. Any low-privileged employee (or one phished laptop) could say "to verify me, call this server", point the CA at a machine they controlled, and have that machine answer in the voice of a domain controller. The CA believed the answer and printed an ID card naming the domain controller. Yikes.
That card is not decorative. Present it to the network's ticket office and you're handed the domain controller's credentials, and a domain controller is allowed to ask for every account secret in the organisation, including the master key all the other keys are cut from. One ordinary login became the entire directory, no admin rights, no user interaction, and working exploit code is public. The hole was closed in the July 2026 security updates, so on a maintained estate the job is: confirm the update, then decide whether the phone-a-friend fallback should still be switched on at all. There's also a one-line stopgap for CAs that can't patch this week. Minutes per CA, no data loss, and the only real trade-off is that the stopgap breaks a legitimate enrollment quirk in some multi-DC setups, which is why it gets tested, not blindly applied.
02 Technical BreakdownFor engineers
The root cause sits in the AD CS enrollment path, specifically a fallback known as a chase during directory-object resolution. Two request attributes drive it: cdc (Client DC), which names the host the CA should contact, and rmd (Remote Domain), which names the principal to look up. When both are present, the CA opens SMB and LDAP connections to the cdc host and queries it for the rmd principal, then uses whatever comes back as directory data while building the certificate.
The vulnerable builds of certpdef.dll (the policy module inside certsrv.exe) never proved that the cdc target was what it claimed. In CRequestInstance::_LoadPrincipalObject, the requester-supplied cdc string flowed straight into _GetDSObject(..., chase = 1, cdc), so an attacker could stand up rogue LDAP and LSA services on their own host, relay the CA's authentication challenge to a real DC to look legitimate, and return directory data for a chosen victim: the target DC's objectSid and dNSHostName. Those values landed in the issued certificate's identity material, the strong-mapping SID and DNS fields the KDC trusts during certificate authentication (PKINIT). From there the chain writes itself: certificate as the DC, Kerberos TGT as the DC, DCSync, krbtgt. The PoC's only other ingredient is a machine account, which the default ms-DS-MachineAccountQuota of 10 hands out to any domain user. Not a great default, as defaults go.
The July 2026 update fixes the trust boundary in two places, gated behind a servicing feature flag (Feature_3185813818). A new function, _ValidateChaseTargetIsDC, runs before the chase: it rejects IP literals, overlong names and LDAP filter metacharacters, then requires the supplied hostname to resolve to exactly one computer object whose userAccountControl carries SERVER_TRUST_ACCOUNT (8192), i.e. a real domain controller. After resolution, a new SID comparison rejects substituted objects. One wrinkle worth knowing: if that feature gate isn't active, the patched binary still contains the old branch, so "the DLL version bumped" and "the protection is on" are not quite the same statement. On a normally patched and rebooted CA the gate should be on, but afaik it's worth verifying rather than assuming.
03 Affected
Microsoft classes the flaw as improper authorization with a CVSS of 8.8, and the NVD record lists Windows Server 2012 through 2025 (Server Core included), plus Windows 10 versions 1607 and 1809: anything running a vulnerable AD CS enterprise CA before the July 14, 2026 updates. The researchers tested against a 2016-or-later functional level forest. As of disclosure on July 24, no confirmed exploitation in the wild and no CISA KEV listing, though with a full public PoC that comfort has a shelf life.
Exploitation needs one valid low-privilege domain credential, network reachability from the CA to the attacker's SMB/LDAP listeners, a certificate template the account may enroll in (the default Machine template sufficed in the PoC), and a machine account to work with, which the default ms-DS-MachineAccountQuota of 10 provides (or one the attacker already controls, via --computer-name). Any cumulative update from July 2026 onward remediates the CVE; the exposure that remains is the chase fallback staying enabled where nothing legitimate uses it, and free machine-account creation still being on.
04 Detection
Before we change anything, let's see what we're dealing with. First, is the chase fallback even on?
certutil -getreg policy\EditFlags certutil decodes the flags symbolically; EDITF_ENABLECHASECLIENTDC in the output means the vulnerable path is armed. On an unpatched CA, that's live exposure.
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4886,4887} -MaxEvents 500 | Where-Object {$_.Message -match 'cdc|rmd'}Events 4886/4887 are certificate requests and issuances (needs "Audit Certification Services" enabled). Request attributes aren't always in the message text, but if the chase attributes show up anywhere, it's here; treat a hit as a smoking gun, an absence as nothing conclusive.
Get-ADComputer -Filter {whenCreated -gt (Get-Date).AddDays(-7)} | Select-Object Name,DNSHostName,whenCreated A fresh machine account followed shortly by a certificate request is the PoC's exact opening move. The public PoC defaults to names like GHOST* (trivially changed, obviously, so don't rely on the pattern alone).
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4887} -MaxEvents 200 | Where-Object {$_.Message -match (Get-ADDomain).PDCEmulator.Split('.')[0]}A certificate carrying a DC's identity where the requester isn't that DC is the fraud you're hunting; substitute your DC names and eyeball anything issued to them.
One network-level tell worth a firewall query, no command needed: the CA host making outbound SMB (445) and LDAP (389) connections to non-DC addresses during enrollment. CAs talk to DCs; they should not be phoning random member servers.
05 Remediation
01 Install the July 2026 security update
Any cumulative update from July 14, 2026 onward closes the path on the CA side. On a maintained estate this may already be done (go on, check, I'll wait). Patch every CA, not just the busy ones.
Install-Module PSWindowsUpdate; Get-WindowsUpdate -Install -AcceptAllOr push via WSUS/SCCM rings. Reboot afterwards: the new validation is gated behind a servicing feature flag, and you want that flag active, not just the DLL replaced.
02 Can't patch yet? Disable the chase fallback
If the update can't land this week, the vulnerable path is an optional fallback, not code that runs on every request, so it can be switched off outright. This is the researchers' own documented stopgap.
certutil -setreg policy\EditFlags -EDITF_ENABLECHASECLIENTDC
Restart-Service CertSvc -Force Kills the cdc chase entirely; the CA restarts in seconds.
Two honest caveats. First, it's a mitigation, not a patch: if anything (an admin, an image, a GPO) re-enables that flag on an unpatched CA, the vulnerability is back. Second, the researchers validated it in a lab, not on a production CA: if any legitimate enrollment in your environment relies on the cross-DC chase, those requests will start failing once the flag is cleared. Test on a staging CA if you have one; monitor 4886 failures if you don't.
03 Stop handing out free machine accounts
The PoC's opening move relies on the default ms-DS-MachineAccountQuota of 10, which lets any domain user create machine accounts at will. Setting it to 0 doesn't close the CVE (an attacker can reuse a machine account they already control), but it removes the easiest version of the chain and is standard AD hardening anyway.
Set-ADDomain -Identity (Get-ADDomain).DNSRoot -Replace @{'ms-DS-MachineAccountQuota'=0}Expect complaints from any workflow where helpdesk or users join machines with ordinary accounts; pre-stage those computer objects instead.
06 Verification
Patched and flagged? Let's prove it rather than assume it.
Get-HotFix | Sort-Object InstalledOn -Descending | Select-Object -First 5 HotFixID,InstalledOnThe newest cumulative update must be July 2026 or later. Patched build floors: 26100.33158 (Server 2025), 20348.5386 (2022), 17763.9020 (2019), 14393.9339 (2016).
certutil -getreg policy\EditFlags If you applied the stopgap, EDITF_ENABLECHASECLIENTDC should no longer appear. Re-check after GPO refreshes and reboots, not just once: config drift is the whole risk here.
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4886} -MaxEvents 100 | Where-Object {$_.Message -match 'fail|denied'} After patching, chase-style requests with bogus cdc targets should be failing validation, not issuing. A quiet lab test with the public PoC against a patched CA is the cleanest proof; it should now error before issuance.
07 Rollback
The realistic rollback is re-enabling the chase fallback if the stopgap broke legitimate enrollment in a genuinely multi-DC setup. Patch first, then re-enable only where the chase is actually needed.
certutil -setreg policy\EditFlags +EDITF_ENABLECHASECLIENTDC
Restart-Service CertSvc -ForceRe-enables the fallback; only acceptable on a patched CA.
Rolling back the security update itself is almost never justified, it reopens a known public-exploit RCE that hands out the domain. If the July update breaks enrollment, fix forward or clear the chase flag while you troubleshoot, rather than uninstalling.
wusa /uninstall /kb:5099535 /norestartExample: uninstall the July 2026 cumulative update on Server 2016. The July 14, 2026 KBs are KB5099536 (Server 2025), KB5099540 (Server 2022), KB5099538 (Server 2019) and KB5099535 (Server 2016); 2012/2012 R2 need their ESU packages. Re-apply the chase-flag stopgap immediately if you do this.
08 References
- Certighost technical writeup (h0j3n & aniqfakhrul)
- Public PoC: CVE-2026-54121
- Microsoft Security Update Guide: CVE-2026-54121
- MS-WCCE: Windows Client Certificate Enrollment Protocol
If I've got anything wrong here, or you've hit an edge case I haven't covered, do say: corrections and questions are always welcome and thank you Urose for pointing out this vulnerability :)
Ship the fix. Prove it’s closed.
If this runbook doesn’t fit your stack, send the CVE — an operator writes a verified path, usually within a business day. Or contribute your own and get co-authored credit.