Skip to content
KitploitKITPLOIT
उपकरणब्लॉग
जमा करें
उपकरणब्लॉग
जमा करें

हैकिंग, पेनटेस्ट और साइबर सुरक्षा उपकरण आपके सुरक्षा शस्त्रागार के लिए!

Kitploit हैकिंग, साइबर सुरक्षा और पेंटेस्टिंग टूल्स की एक निर्देशिका है। कमजोरियों को खोजने, सिस्टम का विश्लेषण करने, परीक्षण को स्वचालित करने और अपनी सुरक्षा को मजबूत करने के लिए नवीनतम प्रोजेक्ट अपडेट खोजें।

··फ़ीड·संपर्क·गोपनीयता·© 2026 Kitploit

टूल निर्देशिका

श्रेणियाँ

सभी श्रेणियाँ देखें
Loading categories
BYOVD-DriverKiller — ड्राइवर रिवर्स और एक्सप्लॉइटेशन | Kitploit
उपकरण/GitHubGitHub/alex3o/byovd-driverkiller
शोषणरिवर्स इंजीनियरिंगपोस्ट-शोषणबाइनरी विश्लेषणलर्निंग और शिक्षारेड टीमिंग
GitHubalex3o/byovd-driverkiller

BYOVD-DriverKiller

ड्राइवर रिवर्स और एक्सप्लॉइटेशन

रिपॉजिटरी देखें
831431 साल पहलेKitploit द्वारा समीक्षित

सबसे लोकप्रिय

सभी देखें →

हमारे समुदाय द्वारा सबसे अधिक उपयोग किए जाने वाले उपकरण खोजें।

सभी उपकरण खोजें

हमारे उपकरणों का संग्रह ब्राउज़ करें

सभी उपकरण देखें →
साझा करें

BYOVD-DriverKiller

⚠️ चेतावनी : यह प्रोजेक्ट पूर्णतः शैक्षिक और प्रदर्शनात्मक है। इसका दुर्भावनापूर्ण संदर्भ में उपयोग करने का कोई इरादा नहीं है। उद्देश्य reverse engineering की पद्धति और Windows ड्राइवर के शोषण के चरणों को सीखना है।


मैं यहाँ उस प्रक्रिया को समझा रहा हूँ जो मैंने d1rk(SaadAhla) https://github.com/SaadAhla द्वारा प्रस्तावित अभ्यास को हल करने के लिए अपनाई थी, जिसमें एक वैध, हस्ताक्षरित ड्राइवर पर reverse engineering और शोषण करना शामिल है जो blocklists (HVCI, LOLBIN...) में नहीं है। एक C प्रोग्राम उपलब्ध है जो इस Kernel-mode ड्राइवर के माध्यम से सिस्टम पर किसी भी सक्रिय प्रोसेस को समाप्त कर सकता है; मैं इसके संचालन का विवरण थोड़ा नीचे दे रहा हूँ।

POC-BYOD

📃 उपयोग : DriverKiller.exe <प्रोसेस_नाम.exe> [-d]

विकल्प -d : शोषण के बाद सिस्टम से सेवा और ड्राइवर को हटाने की अनुमति देता है।

लक्ष्य मशीन पर testsigning मोड सक्षम होना चाहिए क्योंकि ड्राइवर का प्रमाणपत्र समाप्त हो चुका है।


भाग 1 - रिवर्स इंजीनियरिंग :

अभ्यास में एक .sys फ़ाइल दी गई है, जिसका नाम उसके SHA-256 हैश के साथ रखा गया है। पहला चरण इस फ़ाइल को IDA के साथ खोलना है।
IDA निःशुल्क उपलब्ध है। लाइसेंस उत्पन्न करने और सॉफ़्टवेयर डाउनलोड करने के लिए बस Hex-Rays की वेबसाइट पर जाना होगा।

हम ड्राइवर की IAT (Import Address Table) को सूचीबद्ध करके शुरू करते हैं और उस API कॉल की खोज करते हैं जिसमें हमारी रुचि है : ZwTerminateProcess।

screen1-git

ZwTerminateProcess पर डबल-क्लिक करने पर, IDA हमें इस फ़ंक्शन के संकलित कोड पर पुनर्निर्देशित करता है। एंट्री का चयन करके और cross-references प्रदर्शित करके, हमें ड्राइवर के उन फ़ंक्शनों की सूची मिलती है जो इसे कॉल करते हैं।

अतः = का पता + 10 * 8 = 80 बाइट्स। इसलिए इस चर में SYSTEM_PROCESS_INFORMATION संरचना से प्राप्त PID ही होता है। क्योंकि = का पता + 8 × 8 = 64 बाइट्स। यह सदस्य के के अनुरूप है, क्योंकि यह सदस्य ऑफ़सेट 56 + 2 (USHORT) + 2 (USHORT) + 4 (padding) = 64 पर स्थित है। जिसका अर्थ है कि यह फ़ंक्शन MajorFunction तालिका की सभी प्रविष्टियों को सौंपा गया है (0x1B = 27, और 28 प्रमुख IRP मौजूद हैं)।
screen2-git

हम देखते हैं कि sub_12EF4 फ़ंक्शन, ऑफ़सेट 1CE पर, ZwTerminateProcess का उपयोग करता है। डबल-क्लिक के बाद, IDA इसका संकलित कोड प्रदर्शित करता है।

screen11-git

डीकंपाइल किया गया कोड ZwOpenProcess (जो लक्ष्य प्रोसेस के लिए एक हैंडल खोलता है) और ZwTerminateProcess (जो इस हैंडल के माध्यम से प्रोसेस को समाप्त करता है) के कॉल प्रकट करता है।

ZwOpenProcess के दस्तावेज़ (https://learn.microsoft.com/fr-fr/windows-hardware/drivers/ddi/ntddk/nf-ntddk-zwopenprocess) को देखने पर, हम पाते हैं कि ClientID पैरामीटर एक पॉइंटर है जो लक्षित प्रोसेस के PID को इंगित करता है।

ऊपर वाली पंक्ति में, ClientId.UniqueProcess को v22 चर के साथ प्रारंभ किया गया है। इसे ठीक ऊपर परिभाषित किया गया है :

root@kitploit:~
v22 = (void )((_QWORD *)i + 10);

इस असाइनमेंट को समझने के लिए, हमें i चर और +10 फ़ील्ड की पहचान करनी होगी।

screen3-git

इस फ़ंक्शन में थोड़ा ऊपर, हम SYSTEM_PROCESS_INFORMATION पैरामीटर के साथ ZwQuerySystemInformation का कॉल देखते हैं। हम यह भी समझते हैं कि i, v6 चर के साथ इस संरचना की प्रविष्टियों पर पुनरावृत्ति करता है।

ZwQuerySystemInformation के दस्तावेज़ के अनुसार : (https://learn.microsoft.com/en-us/windows/win32/sysinfo/zwquerysysteminformation), यह फ़ंक्शन एक सरणी लौटाता है जिसमें सिस्टम पर प्रत्येक सक्रिय प्रोसेस के लिए एक प्रविष्टि होती है।

SYSTEM_PROCESS_INFORMATION संरचना का वर्णन यहाँ किया गया है : https://learn.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntquerysysteminformation

root@kitploit:~
typedef struct _SYSTEM_PROCESS_INFORMATION {
    ULONG NextEntryOffset;
    ULONG NumberOfThreads;
    BYTE Reserved1[48];
    UNICODE_STRING ImageName;
    KPRIORITY BasePriority;
    HANDLE UniqueProcessId;
    PVOID Reserved2;
    ULONG HandleCount;
    ULONG SessionId;
    PVOID Reserved3;
    SIZE_T PeakVirtualSize;
    SIZE_T VirtualSize;
    ULONG Reserved4;
    SIZE_T PeakWorkingSetSize;
    SIZE_T WorkingSetSize;
    PVOID Reserved5;
    SIZE_T QuotaPagedPoolUsage;
    PVOID Reserved6;
    SIZE_T QuotaNonPagedPoolUsage;
    SIZE_T PagefileUsage;
    SIZE_T PeakPagefileUsage;
    SIZE_T PrivatePageCount;
    LARGE_INTEGER Reserved7[6];
} SYSTEM_PROCESS_INFORMATION;

स्मरण : Windows x64 पर कुछ प्रकारों के आकार

  • ULONG = 4 बाइट्स
  • USHORT = 2 बाइट्स
  • HANDLE = 8 बाइट्स
  • PWSTR = 8 बाइट्स
  • KPRIORITY (LONG का typedef) = 4 बाइट्स
  • UNICODE_STRING = 16 बाइट्स क्योंकि इसकी संरचना इस प्रकार है :
root@kitploit:~
  typedef struct _UNICODE_STRING {
    USHORT Length;        -> 2      
    USHORT MaximumLength; -> + 2 = 4
    PWSTR  Buffer;        -> + 8 = 12 (12 n'est pas un multiple de 8 donc padding de 4 ajouté en amont de Buffer) = 16
} UNICODE_STRING;

UniqueProcessId के ऑफ़सेट की गणना :

root@kitploit:~
    ULONG NextEntryOffset;        -> 4
    ULONG NumberOfThreads;        -> + 4 = 8
    BYTE Reserved1[48];           -> + 48 = 56
    UNICODE_STRING ImageName;     -> + 16 = 72
    KPRIORITY BasePriority;       -> + 4 = 76 (76 n'est pas un multiple de 8 donc padding de 4 ajouté) = 80
    HANDLE UniqueProcessId;       -> + 8 = 88

UniqueProcessId सदस्य इस प्रकार ऑफ़सेट 0x50 (80 दशमलव) पर है।

हमारे चर v22 के असाइनमेंट को देखते हुए, हम पाते हैं कि i को QWORD (8 बाइट्स) पॉइंटर में कास्ट किया गया है

root@kitploit:~
v22 = (void )((_QWORD *)i + 10);
v22
i

यह जानने के लिए कि ZwTerminateProcess को कौन सा PID दिया जाएगा, हमें इस असाइनमेंट के आसपास की शर्त का विश्लेषण करना होगा।

screen4-git

हम देखते हैं कि पहले प्रोसेस की इमेज का नाम प्राप्त किया जाता है :

root@kitploit:~
v9 = (wchar_t )((_QWORD *)i + 8);
v9
i
ImageName
Buffer

नीचे दिए गए संचालनों और लूपों को देखते हुए, हम यह परिकल्पना कर सकते हैं कि तर्क के रूप में पारित प्रोसेस के नाम (a2) और सिस्टम पर सक्रिय प्रोसेसेस v9/String के बीच तुलना की जाती है।

root@kitploit:~
sub_1C078(String, v9, (int)v13);
v17 = strupr(a2);
v18 = strupr(String);

इस प्रकार a2 पैरामीटर ही वह है जिसमें ZwTerminateProcess के माध्यम से समाप्त किए जाने वाले प्रोसेस का नाम होना चाहिए। हम ध्यान देते हैं कि a2 फ़ंक्शन sub_12EF4 का एक पैरामीटर है। आगे बढ़ने के लिए, हमें इस फ़ंक्शन के संदर्भों की जाँच करनी होगी (बेहतर पठनीयता के लिए मैंने इसे ZwTerminateProcessCaller नाम दिया है)।

screen5-git

हम देखते हैं कि ZwTerminateProcessCaller को फ़ंक्शन sub_13624 द्वारा ऑफ़सेट 61A पर कॉल किया जाता है।

screen6-git

इस डीकंपाइल किए गए कोड का विश्लेषण करने से पहले, मैं फ़ंक्शन sub_13624 (जिसे ZwTerminateProcessCallerCaller नाम दिया गया है) के संदर्भ खोजूँगा ताकि यह सुनिश्चित हो सके कि इस कोड का उपयोग वास्तव में UserMode से DeviceIoControl के लिए API कॉल के बाद किया जाता है।

screen§-git

हम देखते हैं कि ZwTerminateProcessCallerCaller को फ़ंक्शन sub_14130 द्वारा कॉल किया जाता है (जिसे ZwTerminateProcessCallerCallerCaller नाम दिया गया है... सौभाग्य से हमारे लिए, यह प्रवेश बिंदु से पहले का अंतिम फ़ंक्शन है 😅)।

screen7-git

हम देखते हैं कि ZwTerminateProcessCallerCallerCaller को फ़ंक्शन sub_1A4A8 द्वारा ऑफ़सेट 306 पर कॉल किया जाता है।

screen8-git

हमें फ़ंक्शन ZwTerminateProcessCallerCallerCaller का असाइनमेंट मिलता है :

root@kitploit:~
memset64(DriverObject->MajorFunction, (unsigned __int64)ZwTerminateProcessCallerCallerCaller, 0x1Cu);

screen9-git

फ़ंक्शन sub_13624 (उर्फ ZwTerminateProcessCallerCaller) पर लौटने से पहले, हम Symbolic Name और Device Name (यहाँ समान) प्राप्त करते हैं : Viragtlt।

screen12-git

ZwTerminateProcessCallerCaller पर लौटते हुए, हम ध्यान देते हैं कि इसका दूसरा पैरामीटर (अर्थात a2) MasterIrp->AssociatedIrp.SystemBuffer के अनुरूप है।

screen13-git

ZwTerminateProcessCaller कॉल के ठीक ऊपर हमें IOCTL कोड मिलता है : -2106392528 (हेक्साडेसिमल में : 0x82730030)।

इन जानकारियों की सहायता से, हम यह निष्कर्ष निकाल सकते हैं कि इस ड्राइवर का शोषण करने के लिए, ड्राइवर को DeviceIoControl API कॉल भेजना होगा जिसमें SystemBuffer में समाप्त किए जाने वाले प्रोसेस का नाम हो।


🔷 रिवर्स इंजीनियरिंग के माध्यम से प्राप्त जानकारी :

  • IOCTLCode : 0x82730030
  • Device Name : Viragtlt
  • Symbolic Name : Viragtlt
  • SystemBuffer में लक्ष्य प्रोसेस का नाम होना चाहिए

भाग 2 - शोषण

इस ड्राइवर का शोषण करने के लिए (यदि यह लक्ष्य मशीन पर स्थापित और सक्रिय है), इसके लिए एक हैंडल खोलना आवश्यक है, फिर एक Buffer के साथ DeviceIoControl API कॉल करना होगा जिसमें उस प्रोसेस का नाम हो जिसे आप समाप्त करना चाहते हैं।
इस अभ्यास के लिए, मैंने एक C प्रोजेक्ट विकसित किया है जो :

  • जाँच करता है कि ड्राइवर सिस्टम पर मौजूद और सक्रिय है या नहीं (एक विशिष्ट सेवा नाम के साथ) :
    • यदि हाँ, तो प्रोग्राम DeviceIoControl API कॉल के साथ ड्राइवर का शोषण करता है।
    • यदि नहीं, तो प्रोग्राम ड्राइवर को अपने संसाधनों से निकालता है, उसे उपयोगकर्ता के डेस्कटॉप पर तैनात करता है, एक सक्रिय सेवा बनाता है और फिर DeviceIoControl API कॉल के साथ ड्राइवर का शोषण करता है। (एडमिन अधिकार आवश्यक हैं क्योंकि एक सेवा का निर्माण किया जाता है।)
  • यदि ड्राइवर सिस्टम पर मौजूद है लेकिन सेवा प्रारंभ नहीं हुई है, तो प्रोग्राम सेवा प्रारंभ करने का प्रयास करता है और फिर DeviceIoControl API कॉल के साथ ड्राइवर का शोषण करता है।

मैंने एक -d विकल्प भी जोड़ा है जो शोषण के बाद सिस्टम से सेवा और ड्राइवर को हटाने की अनुमति देता है।

अपने पूर्ण निष्पादन चक्र में C प्रोग्राम का व्यवहार यहाँ दिया गया है :

git

AV/EDR एवेज़न

इस मामले में, DriverKiller.exe को Microsoft Defender द्वारा न तो स्टैटिक रूप से और न ही डायनामिक रूप से पहचाना जाता है। यहाँ एवेज़न का वास्तव में कोई मतलब नहीं है क्योंकि शोषित ड्राइवर के पास एक समाप्त प्रमाणपत्र है, इसलिए वास्तविक परिस्थितियों में इसका उपयोग शायद ही संभव है। लेकिन बेहतर स्टील्थ के लिए, हम इन्हें लागू कर सकते थे :

  • GetProcAddress और GetModuleHandle के कस्टम कार्यान्वयन के माध्यम से IAT तालिका के कुछ API कॉलों को छिपाना
  • API कॉल निष्पादन के लिए Kernel के निकट जाना (Direct/Indirect Syscalls)
  • Anti-VM / Anti-Debug तकनीकें

29/08/2025 को ड्राइवर पर पहचान (परिणाम पहले से मौजूद है, स्पष्ट कारणों से मैंने VirusTotal पर कुछ भी सबमिट नहीं किया) :

image

⚠️ यह प्रोजेक्ट एक सीखने के उद्देश्य से बनाया गया है। इसमें अशुद्धियाँ या त्रुटियाँ हो सकती हैं। कोई भी सुझाव, सुधार या चर्चा का स्वागत है! 😃 d1rk(SaadAhla) को धन्यवाद : https://github.com/SaadAhla !

टूल डाउनलोड करें