← All articles
Active DirectoryAug 7, 202612 min read

ResetNightmare (CVE-2026-27912): Full Domain Takeover Through the Kerberos Change Password Protocol

Forestall Research TeamSecurity ResearchLinkedIn

Executive Summary

  • ResetNightmare (CVE-2026-27912) lets an attacker who holds write access over a single account, or the ability to create accounts, reset the password of any other account, including a Domain Admin. That is a direct path from a low-privileged foothold to full domain compromise. It was discovered and disclosed by Semperis.
  • The bug lives in the interaction between three things: the userPrincipalName (UPN) attribute, the NT-ENTERPRISE Kerberos name type, and the Kerberos change password protocol (RFC 3244, port 464).
  • In late 2021 Microsoft added a PAC_REQUESTOR SID check to close the sAMAccountName-spoofing chain (CVE-2021-42278 and CVE-2021-42287). That check runs when a ticket-granting ticket (TGT) is used at the TGS-REQ step.
  • The change password protocol goes straight from a TGT to an AP-REQ, with no TGS-REQ in between. So the SID check never runs, and a TGT minted for the wrong identity is accepted to change a victim's password.
  • Microsoft patched it in April 2026. The precondition, write access over an account, is something Forestall already surfaces as attack-path exposure, and the post-abuse indicator is a single anomalous attribute that you can hunt for today.

The Vulnerability

To see why this works, you have to look at what the 2021 fix actually changed.

The sAMAccountName-spoofing chain of 2021 abused a rename. An attacker created a computer account, renamed its sAMAccountName to match a Domain Controller (dropping the trailing $), requested a TGT, renamed the account back, and then used the TGT to request service tickets. The KDC, resolving the ticket, mapped it to the still-privileged name and issued tickets as the DC.

Microsoft's fix added a field called PAC_REQUESTOR to the Privilege Attribute Certificate carried inside the ticket. It records the SID of the account that actually requested the ticket. When that TGT is later presented at a TGS-REQ to obtain a service ticket, the KDC compares the PAC_REQUESTOR SID against the account the ticket now resolves to. If they disagree, the request fails with KDC_ERR_TGT_REVOKED. A renamed or mismatched ticket is caught at that gate.

ResetNightmare's insight, from the Semperis research, is that the gate is only on one road. The check happens during TGS-REQ processing. The Kerberos change password protocol never issues a TGS-REQ. A client presents its TGT directly in an AP-REQ to the change password service on port 464, wrapped with the new password in a KRB-PRIV message. Because there is no TGS-REQ, there is no PAC_REQUESTOR comparison, and a ticket whose cleartext identity no longer matches its requestor is accepted anyway.

That turns a subtle identity mismatch into a password reset primitive.

How the Attack Works

The attacker controls one account (call it m.chen) and wants to take over sqladmin, a Domain Admin. They need write access over m.chen (or any account they can bend to this purpose). The steps, as described by Semperis:

1. Point the UPN at the victim. Set m.chen.userPrincipalName to sqladmin, the victim's sAMAccountName. This does not trip UPN uniqueness, because the real admin's UPN is a suffixed value like [email protected], and the bare sqladmin is considered distinct.

2. Get a TGT under the victim's name. Send an AS-REQ with username sqladmin and name type NT-ENTERPRISE, authenticating with m.chen's own password. The NT-ENTERPRISE name type tells the KDC to locate the account by userPrincipalName rather than sAMAccountName, so the request resolves to m.chen and the password check passes. The KDC returns a TGT whose visible name reads sqladmin, while the embedded PAC_REQUESTOR still records m.chen's SID.

3. Cover the tracks in the ticket. Clear m.chen's userPrincipalName. From this point a normal TGS-REQ with the ticket would fail with KDC_ERR_TGT_REVOKED, exactly because of the 2021 patch. That is fine, because the attack never uses TGS-REQ.

4. Reset the victim's password. Send the TGT to the change password service on port 464 inside an AP-REQ, with a KRB-PRIV message carrying the new password. There is no TGS-REQ, so PAC_REQUESTOR is never validated. The service changes the password of the identity named in the ticket, sqladmin, to a value the attacker chose.

5. Log in as the real admin. Authenticate normally as sqladmin with the new password. The attacker now holds a legitimate Domain Admin session.

The Semperis team notes the technique can be combined with Shadow Credentials against a writable computer account for a stealthier path that avoids a visible password reset. A proof-of-concept, ResetNightmare.ps1, is published by Semperis Community and drives the full flow with Rubeus and the ActiveDirectory PowerShell module.

Prerequisites and Scope

  • Write access over one account, specifically the ability to set its userPrincipalName, or the rights to create an account. Generic write, full control, or account-creation rights all qualify. No Domain Admin access is required to start.
  • The victim's password must be at least one day old, because a domain's default minimum password age is one day and the protocol will not change a password inside that window.
  • On-premises Active Directory. This is a Kerberos and directory bug. It does not involve AD CS.
  • Forest-wide reach. Any account the attacker can eventually target, including Tier 0, is in scope once the primitive works.

Detection and Hunting

There are two useful angles: catch the abuse as it happens, and find the exposure before it is abused. To ground the queries below, we planted the indicator in a lab: an account m.chen had its userPrincipalName set to sqladmin, the login name of a separate account standing in for the target. Both a Server 2019 and a Server 2025 Domain Controller accepted the write, and the checks below returned exactly that account.

Catch the abuse (event log). The distinctive artifact is the UPN assignment in step 1. Watch Event ID 5136 (directory object modified) for a userPrincipalName being written to a value that matches an existing account's sAMAccountName. In healthy directories a UPN that is a bare account name with no suffix, and that collides with someone else's login name, is close to nonexistent. Semperis DSP ships an indicator for exactly this pattern.

Hunt it with PowerShell (no extra tooling). Any domain-joined host with the ActiveDirectory module can find the collision. It reads two attributes and compares them, so it is safe to run anywhere:

$objs = Get-ADObject -LDAPFilter '(|(objectClass=user)(objectClass=computer))' -Properties sAMAccountName, userPrincipalName
$sam  = @{}; $objs | Where-Object sAMAccountName | ForEach-Object { $sam[$_.sAMAccountName.ToLower()] = $_.sAMAccountName }
$objs | Where-Object userPrincipalName | ForEach-Object {
  $k = $_.userPrincipalName.ToLower()
  if ($sam.ContainsKey($k) -and $sam[$k] -ne $_.sAMAccountName) {
    "{0}  (UPN '{1}')  impersonates  {2}" -f $_.sAMAccountName, $_.userPrincipalName, $sam[$k]
  }
}

In the lab it returns the planted account and nothing else:

m.chen  (UPN 'sqladmin')  impersonates  sqladmin

Find the exposure (directory state). If you run Forestall ISPM, the same collision is a single query against the scanned graph, because it already stores every account's userPrincipalName and sAMAccountName. Run this in the graph view, or directly against Neo4j:

// Accounts whose UPN matches another account's sAMAccountName (ResetNightmare indicator)
MATCH (x) WHERE (x:User OR x:Computer) AND x.SAMAccountName IS NOT NULL
WITH collect(DISTINCT toLower(x.SAMAccountName)) AS sams
MATCH (a:User)
WHERE a.UserPrincipalName IS NOT NULL AND a.UserPrincipalName <> ''
  AND toLower(a.UserPrincipalName) IN sams
  AND toLower(a.UserPrincipalName) <> toLower(a.SAMAccountName)
RETURN a.SAMAccountName     AS controlledAccount,
       a.UserPrincipalName  AS impersonatedLoginName

Any row is worth investigating, but weight it by the target. A UPN set to a bare login name that belongs to a privileged or Tier 0 account is a live ResetNightmare setup; a collision with an ordinary account is more likely a benign alternate-UPN mistake. False positives are uncommon either way, because a UPN that duplicates another account's login name is not something normal administration produces.

The precondition is already visible too. ResetNightmare needs write access over an account, and Forestall ISPM maps those rights (generic write, full control, write property, and account-creation rights) as attack-path edges. The accounts that can be bent into this attack are the same ones that already show up in your dangerous-permission findings, so the exposure surface is not new even though the technique is.

Mitigation

  1. Install the April 2026 security update on all Domain Controllers. This is the fix. It closes the gap so that the change password path enforces the same identity check as the rest of Kerberos. Confirm the exact KB for each Windows Server version in the Microsoft Security Update Guide entry for CVE-2026-27912.
  2. Reduce write access over accounts. Audit and remove broad GenericWrite, GenericAll, WriteProperty on userPrincipalName, and account-creation rights, especially anything that unprivileged users hold over privileged or Tier 0 accounts. This shrinks the set of accounts that can seed the attack.
  3. Keep the machine account quota in check. Because the attack also works from a newly created or writable computer account, setting ms-DS-MachineAccountQuota to 0 and delegating machine creation removes a convenient starting point.
  4. Monitor for the indicator. Alert on Event 5136 where a userPrincipalName is set to another account's sAMAccountName, and review the graph query above on a schedule.

Conclusion

ResetNightmare works because the 2021 PAC_REQUESTOR check guards only the TGS-REQ path, and the change password protocol never takes that path. That single gap is enough to turn write access over one unprivileged account into a Domain Admin password reset.

The April 2026 update is the real fix and should be prioritized on every Domain Controller. Until it is deployed everywhere, the setup still leaves a clear mark: a UPN set to another account's login name is easy to find in your event pipeline or in a graph of your directory, and the write access the attack depends on is exposure you can measure right now.

References

  1. Semperis: Identity Crisis (KerberLoss and ResetNightmare)
  2. Microsoft Security Update Guide: CVE-2026-27912
  3. Microsoft Security Update Guide: CVE-2021-42287
  4. Semperis Community: ResetNightmare PoC
  5. Microsoft: Description of password-change protocols in Windows
  6. IETF RFC 3244: Microsoft Windows 2000 Kerberos Change Password and Set Password Protocols

Share This Article, Secure Your Friends!

See your identity exposure clearly.

Start with a 1-day Proof of Value in your own environment.

We respect your privacy

We use cookies to keep this site secure and working properly. With your permission, we also use optional cookies to understand usage and improve the experience. Cookie Policy

You can change your choice at any time.

CVE-2026-27912 ResetNightmare: AD Domain Takeover and Detection | Forestall