CVE-2026-54121, tracked publicly as Certighost, lets a standard authenticated domain user impersonate a domain controller through Active Directory Certificate Services and take over the domain. No prior privileges, no user interaction, network access only. Microsoft rated it CVSS 8.8 (high) and shipped a fix on 14 July 2026. A working proof of concept went public ten days later, on 24 July.
The flaw lives in a rarely-discussed corner of AD CS: the cross-DC enrollment fallback, informally called the "chase." A low-privilege account can steer that fallback to a host it controls, convince the CA to trust that host as a domain controller, and walk away with a certificate carrying a real DC's identity. From there the path is the familiar one — PKINIT to a TGT, replication rights, DCSync, krbtgt. Game over.
This piece explains the mechanism, whether the public PoC actually works and under what conditions, how to detect the attack across the full chain, and how to remediate it. Credit for the discovery goes to Muhammad Ali (H0j3n); the public PoC that pushed this from advisory to operational risk was written by Aniq Fakhrul (aniqfakhrul).
MITRE ATT&CK: T1649 — Steal or Forge Authentication Certificates + T1003.006 — OS Credential Dumping: DCSync
What is the AD CS "chase" fallback, and why did it break?
The chase is a cross-DC enrollment fallback in AD CS: when the CA cannot resolve everything it needs about an enrollee from its own domain controller, it "chases" the request to another DC to fetch the missing information. CVE-2026-54121 is an improper-authorization flaw in that fallback — the CA accepted an attacker-nominated host as the DC to chase without verifying it was actually a domain controller.
The cdc and rmd attributes
The chase is driven by two request attributes an enrollee can supply:
cdc(Client DC) — the host the CA should contact to resolve the enrollee. The CA opens SMB and LDAP connections to whatever this points at.rmd(Remote Domain) — the principal the CA should look up on that host.
When both are present, the CA connects to the cdc host over SMB and LDAP, searches for the principal named in rmd, and pulls attributes such as objectSid and dNSHostName back into the certificate it issues. The design intent is legitimate cross-domain and cross-DC enrollment. The problem is what the CA did not check.
The missing DC check
The vulnerable CA never verified that the host in cdc was a genuine domain controller. Its only gate was that the endpoint at cdc authenticated as some valid principal. That bar is trivially cleared: by default, ms-DS-MachineAccountQuota lets any authenticated domain user create up to ten machine accounts, and a machine account authenticates as a valid principal.
So an attacker with a single low-privilege account creates a machine account, stands up rogue LDAP and SMB endpoints that authenticate with that account, and points cdc at their own host. The CA connects, accepts the attacker-controlled LDAP as authoritative, reads back whatever DC identity the attacker serves, and stamps that identity — a real domain controller's objectSid and dNSHostName — into an issued certificate. The check that should have said "that host is not a DC" was never there.
How does the Certighost attack work step by step?
The attack chains machine-account creation, rogue directory services, and a crafted enrollment request into a DC-identity certificate, then converts that certificate into full domain compromise. Each step reuses primitives that are individually well understood; the novelty is the chase abuse in the middle.
- Create a machine account. Using the default
ms-DS-MachineAccountQuota, the low-privilege account creates a computer object it controls. This account is what the rogue endpoints will authenticate as, satisfying the CA's weak "valid principal" check. - Stand up rogue LDAP and SMB/LSA services. The attacker runs a fake LDAP server that serves crafted directory data (the identity of the DC to impersonate) and a fake SMB/LSA endpoint. These listen on the standard ports (389 for LDAP, 445 for SMB), which is why the PoC needs root.
- Send the crafted enrollment request. The attacker requests a certificate against the built-in
Machinetemplate, supplyingcdcpointing at their rogue host andrmdnaming the target DC principal. - The CA chases to the rogue host. The CA connects to the attacker's LDAP and SMB, "resolves" the principal against attacker-controlled data, and issues a certificate carrying the target DC's
objectSidanddNSHostName. - PKINIT to a TGT. The attacker uses the DC-identity certificate for PKINIT (Kerberos public-key pre-authentication) and obtains a Ticket Granting Ticket as the domain controller.
- DCSync and done. A DC machine account holds directory replication rights. With the TGT, the attacker performs a DCSync, pulling the krbtgt hash and every domain secret. This is the same terminal step that turns ESC8 and ESC1 into full domain takeover — the difference here is how the DC certificate is obtained.
The reason this matters as much as the classic ESC family: AD CS is present in roughly 90% of enterprise Active Directory environments, the Machine template is published by default, and ms-DS-MachineAccountQuota is set to 10 out of the box in most domains. The preconditions are common defaults, not exotic misconfigurations.
Does the CVE-2026-54121 PoC actually work?
Yes. The public proof of concept, certighost.py by Aniq Fakhrul, is a working end-to-end exploit that produces a usable DC-identity certificate against an unpatched CA. It was released on 24 July 2026 and verified at the source-code level: it creates the machine account, runs the rogue LDAP and SMB/LSA listeners, sends the crafted request, and writes out the certificate and Kerberos artifacts.
The invocation is straightforward:
sudo python3 certighost.py -d <domain> -u <lowpriv-user> -p <password> --dc-ip <dc-ip> --template MachineIt runs under sudo because the rogue LDAP and SMB services bind to privileged ports 389 and 445. On success it writes a .pfx (the DC-identity certificate and key) and a .ccache (the Kerberos ticket) to disk, ready for the PKINIT-to-DCSync tail.
The exploit is not universal. It works only when every real precondition lines up:
- A valid low-privilege domain account (any authenticated user).
ms-DS-MachineAccountQuotagreater than zero (the default is 10).- The
Machinecertificate template reachable and enrollable. - A CA still running the vulnerable chase logic — that is, unpatched as of 14 July 2026.
Miss any one of these and the PoC does not yield a certificate. A domain with ms-DS-MachineAccountQuota set to 0, or with the July patch applied, is not exploitable by this technique. That distinction — "you have AD CS" versus "you can be compromised via CVE-2026-54121" — is the one that matters when you triage the finding.
One caveat on defaults you may read elsewhere: the PoC creates its machine account with the name GHOST followed by eight random characters (GHOST<8-random>$). That string is a convenience default in the public tool, not a property of the vulnerability. It is trivially changeable, so GHOST$-prefixed account names are not a reliable indicator of compromise. Detection has to key on behaviour, not on the PoC's cosmetic defaults.
How is Certighost detected?
Detection keys on an impossible issuance pattern — a low-privilege enrollee obtaining a certificate that carries a domain controller's identity — corroborated across CA request logs, machine-account creation, and the PKINIT-then-replication tail. No single event proves it; the correlation does.
You can recon your own environment first with Certipy, the standard AD CS enumeration tool, to see which templates and CA settings an attacker would find:
certipy find -u [email protected] -p 'Password123' -dc-ip 10.0.0.1 -vulnerableFor live detection, these are the events worth wiring into a SIEM. Enable CA\AuditFilter on the issuing CA — the certificate-services events below are not fully populated by Group Policy audit settings alone.
| Event ID | Source / meaning | What to look for |
|---|---|---|
| 4886 | CA received a certificate request | Request carrying a cdc: attribute that does not resolve to a real domain controller. |
| 4887 | CA approved and issued a certificate | A certificate with a DC identity, issued via the Machine template to a low-privilege enrollee — an issuance pattern that should never occur legitimately. |
| 4888 | CA denied a request | Requires CA\AuditFilter; GPO audit policy alone does not surface it. |
| 4741 | A computer account was created | New machine account near the enrollment. Note: the name is attacker-controlled, so do not filter on GHOST. |
| 4768 | Kerberos TGT requested (PKINIT) | A TGT for a DC machine account requested from a workstation, using certificate pre-authentication. |
| Sysmon 3 | Network connection | certsrv.exe initiating outbound connections to 389/445 on a host that is not a legitimate DC. |
| 4662 | Directory replication (DCSync) | The distinguisher: legitimate replication shows SID S-1-5-18 (SYSTEM); the attack shows a domain account's SID performing replication. |
The strongest single signal is the pairing of 4886/4887 — a cdc attribute pointing somewhere it should not, followed by a DC-identity certificate issued to an account that has no business receiving one. Microsoft has published a Defender for Identity / Defender XDR detection for CVE-2026-54121, and Nextron shipped a set of seven Sigma rules covering the full chain from enrollment through DCSync. As of this writing there is no confirmed in-the-wild exploitation by threat actors; the public PoC raises the risk rather than confirming active abuse, which is exactly why detection coverage should go in now.
How do you remediate CVE-2026-54121?
Apply the July 2026 security update. That is the fix; everything else is a stopgap. Microsoft's patch (14 July 2026) makes the CA validate that the host named in cdc resolves to a real computer account with the SERVER_TRUST_ACCOUNT flag (0x2000, 8192) set, and adds a SID comparison — so an attacker's machine account can no longer masquerade as a DC in the chase.
Affected platforms span Windows Server 2012 through Windows Server 2025, including Server Core installations. Confirm the exact KB for each build against the MSRC advisory before you schedule the rollout.
If you genuinely cannot patch immediately, there is a registry workaround that disables the chase behaviour outright. Patch first; use this only as a bridge, and test it, because it turns off a real (if rarely used) enrollment feature:
certutil -setreg policy\EditFlags -EDITF_ENABLECHASECLIENTDC
Restart-Service CertSvc -ForceRead that first command carefully. The leading - in front of EDITF_ENABLECHASECLIENTDC clears that flag bit rather than setting it, which is what disables the chase fallback. It is easy to misread as "enable." Restarting CertSvc applies the change. On a CA that relies on cross-DC enrollment, disabling the chase may break legitimate workflows, so validate in a maintenance window.
A defence-in-depth measure worth revisiting regardless of the patch: set ms-DS-MachineAccountQuota to 0 for accounts that have no business creating machine accounts. It does not fix this CVE on its own, but it removes the cheap machine-account primitive that this and several other AD attacks lean on.
How does ADscan test for Certighost and map it to compliance?
ADscan enumerates AD CS as part of its standard post-authentication scan, evaluates the certificate templates, CA settings, and machine-account quota that make CVE-2026-54121 exploitable, and — where you authorize active validation — attempts the chain end to end so the finding you report is a proven path, not a checkbox.
The gap Certighost exposes is the same one every AD CS finding exposes: a scanner tells you the surface exists; it does not tell you whether the path is real from where an attacker actually lands. ADscan flags the AD CS conditions (published Machine template, non-zero machine-account quota, unpatched chase logic) in the attack graph, and traces the route from a low-privilege foothold through the DC-identity certificate to the DCSync terminal — the same graph that shows how a live path to Domain Admin forms out of individually minor issues.
Where ADscan is built to close the loop that BloodHound and PingCastle leave open: BloodHound maps relationships and PingCastle scores posture, but neither executes the vector, writes it into a client report against a compliance framework, and proves remediation on the re-scan. That closing loop is the differentiator for regulated buyers:
- DORA requires ICT vulnerability management and threat-led penetration testing (TLPT). A proven Certighost path, remediated and re-tested, is exactly the evidence a TLPT exercise is meant to produce.
- NIS2 (Article 21) obliges vulnerability handling and identity/access controls. A DC-impersonation path is a direct hit on both, and the report ties the finding to the obligation.
- ENS Alto covers privileged access, vulnerability management, and traceability. Certighost touches all three, and the re-scan demonstrates the control is now effective.
ADscan LITE is free and source-available. Run the AD CS enumeration against your own environment today:
pipx install adscan && adscan installIf you are running AD assessments for clients and want the finding, the CVSS scoring, the framework mapping, and the client-ready report generated automatically, request PRO beta access — 30 days free. If you are a CISO at a regulated organization who needs continuous AD exposure evidence for DORA, NIS2, or ENS, request a free assessment.
FAQ
Is CVE-2026-54121 being exploited in the wild? No confirmed in-the-wild exploitation by threat actors had been reported at the time of writing. What changed the risk profile is the public proof of concept released on 24 July 2026: a working exploit in the open lowers the bar for opportunistic use, which is why patching and detection should not wait for confirmed abuse.
How is Certighost different from ADCS ESC8? Both end at a domain controller certificate, PKINIT, and DCSync. ESC8 gets the DC certificate by relaying a coerced NTLM authentication to the web enrollment endpoint. Certighost gets it by abusing the cross-DC enrollment chase — the CA is tricked into trusting an attacker's host as a legitimate DC. Different entry, same terminal impact.
Do I need admin rights to run the Certighost PoC?
No domain privileges — a standard authenticated user is enough. The sudo the public PoC requires is local, on the attacker's own machine, because its rogue LDAP and SMB services bind to privileged ports 389 and 445.
Does setting ms-DS-MachineAccountQuota to 0 fix CVE-2026-54121? Not on its own. It removes the cheap machine-account primitive the attack uses, which raises the bar, but the real fix is the July 2026 patch that makes the CA verify the chased host is a genuine domain controller.
Is the GHOST$ machine account a reliable indicator of compromise?
No. GHOST<random>$ is the public PoC's default name and is trivially changed. Detect on the behaviour — a low-privilege enrollee obtaining a DC-identity certificate — not on the account name.
- Download ADscan LITE (free, source-available): https://github.com/ADScanPro/adscan
- Request PRO beta access (30 days free): https://adscanpro.com/pro
Sources
- H0j3n (Muhammad Ali), technical write-up: gist.github.com/H0j3n
- Aniq Fakhrul, public PoC
certighost.py: github.com/aniqfakhrul/CVE-2026-54121 - Microsoft Security Response Center advisory: msrc.microsoft.com — CVE-2026-54121
- Microsoft Threat Intelligence: x.com/MsftSecIntel
- Microsoft Defender detection guidance: techcommunity.microsoft.com
- Nextron Systems, Sigma coverage: nextron-systems.com
- BleepingComputer: bleepingcomputer.com
- Help Net Security: helpnetsecurity.com
- Dark Reading: darkreading.com
