
Windows x64 हस्तनिर्मित टोकन चोरी कर्नेल-मोड शेलकोड
Windows x64 कर्नेल-मोड हस्तनिर्मित शेलकोड जो निष्पादित प्रक्रिया के प्राथमिक एक्सेस टोकन को SYSTEM प्रक्रिया टोकन से बदल देता है, जिससे विशेषाधिकार उन्नयन (EoP) प्राप्त होता है।
Windows 7/Windows Server 2008 R2 Build 7601Windows 8/Windows Server 2012 Build 9200Windows 8.1/Windows Server 2012 R2 Build 9600Windows 10 1507/TS1 Build 10240Windows 10 1511/TS2 Build 10586Windows 10 1607/RS1/Windows Server 2016 Build 14393Windows 10 1703/RS2 Build 15063Windows 10 1709/RS3 Build 16299Windows 10 1803/RS4 Build 17134Windows 10 1809/RS5/Windows Server 2019 Build 17763Windows 10 1903/19H1 Build 18362Windows 10 1909/19H2 Build 18363Windows 10 2004/20H1 Build 19041Windows 10 2009/20H2 Build 19042Windows 10 2104/21H1 Build 19043Windows 10 2110/21H2 Build 19044इस प्रोजेक्ट के निर्माण के लिए आवश्यक शर्तें हैं:
Visual Studio 2019(any edition will do fine)Windows 10 SDK, version 2004Windows 10 WDK, version 2004Python3यहाँ यह ध्यान दिया जाना चाहिए कि आप केवल एक असेंबलर रखकर भी काम चला सकते हैं (यह प्रोजेक्ट MASM का उपयोग कर रहा है) क्योंकि तकनीकी रूप से आपको बस इसी की आवश्यकता है।
उपरोक्त को स्थापित करने के बाद, Visual Studio के साथ समाधान (solution) खोलना और x64 लक्ष्य के लिए निर्माण करना उतना ही आसान होना चाहिए।
सफल निर्माण के बाद, बाइनरी Bin निर्देशिका के अंदर उपयुक्त बिटनेस उप-निर्देशिका में पाई जा सकती हैं।
वैकल्पिक रूप से, आप Releases से तैनाती-योग्य पोजीशन इंडिपेंडेंट शेलकोड डाउनलोड कर सकते हैं।
यदि आप अनिश्चित हैं कि यह कैसे काम करता है, तो कृपया उस मशीन पर पेलोड तैनात करने का प्रयास न करें जिस पर आप काम निपटाने के लिए भरोसा करते हैं।
किसी भी अतिरिक्त जानकारी के लिए Microsoft docs देखें।
परीक्षण उद्देश्यों के लिए, मैं अत्यधिक अनुशंसा करूँगा कि कर्नेल-मोड शेलकोड को एक परीक्षण VM पर तैनात करने के लिए flare-kscldr का उपयोग करें, और पूर्ण कर्नेल डिबगिंग समर्थन के साथ Hyper-V Guest VM स्थापित करने के लिए CodeMachine System setup for kernel development and debugging guide का उपयोग करें।
वैकल्पिक रूप से, आप Vagrant का उपयोग करके पूर्ण कर्नेल डिबगिंग के साथ एक परीक्षण VM को तुरंत तैयार करने के लिए kdbg-driver-vagrant के साथ प्रक्रिया को स्वचालित करने पर भी विचार कर सकते हैं।

जैसा कि Dmytro Oleksiuk(@d_olex) ने मुझे बताया, कोड में कुछ बहुत सूक्ष्म रेस कंडीशन नहीं हैं, जो विशेष रूप से निम्न से संबंधित हैं:
nt!_EPROCESS संरचनाओं को मैन्युअल रूप से ट्रैवर्स करना, बिना किसी सिंक्रोनाइज़ेशन प्रिमिटिव/लॉकिंग तंत्र केवर्तमान में उनके पास उन परिवर्तनों के विरुद्ध कोई सुरक्षा नहीं है जो हमारे कार्य करते समय उनमें किए जा सकते हैं।
क्या यह एक समस्या है? हाँ, रेस कंडीशन हमेशा समस्याग्रस्त होती हैं और सभी प्रकार के अपरिभाषित व्यवहार/बगचेक अप्रियताएँ पैदा कर सकती हैं।
क्या इस पेलोड का उपयोग मेरे एक्सप्लॉइट की स्थिरता को प्रभावित करेगा? यह प्रभावित कर सकता है।
तो, समाधान क्या है? समाधान दो-चरणीय है।
भाग 1 में प्रोसेस सूची को ट्रैवर्स करने से पहले विशेष पहुँच के लिए Pushlocks जैसे वेट-टाइप लॉक - nt!PspActiveProcessLock(pushlock pointer) प्राप्त करना शामिल है, जिसके लिए nt!ExAcquirePushLockExclusive का उपयोग किया जाता है (सामान्य कर्नेल APC डिलीवरी को पहले अक्षम करने की आवश्यकता होती है) और सूची का उपयोग पूरा करने के बाद लॉक को रिलीज़ करने के लिए nt!ExReleasePushLockExclusive का उपयोग किया जाता है, उस बिंदु पर सामान्य कर्नेल APC डिलीवरी को पुनः सक्षम किया जाना चाहिए।
हालाँकि, चूँकि यह वैश्विक चर nt कर्नेल द्वारा निर्यात नहीं किया जाता है, एक अधिक उचित और सुरक्षित दृष्टिकोण nt!ZwQuerySystemInformation API का उपयोग SYSTEM_INFORMATION_CLASS == SystemProcessInformation के साथ करके ImageName से PID ढूँढना और PID से nt!_EPROCESS VA प्राप्त करने के लिए nt!PsLookupProcessByProcessId का उपयोग करना होगा।
यदि आप उत्सुक हैं कि कर्नेल पूर्व वाला कैसे करता है, तो मैं आपसे अनुरोध करूँगा कि आप एक डिसअसेंबलर में nt!PsGetNextProcess को देखें।
भाग 2 में nt!ObReferenceObject APIs परिवार का उपयोग करके ऑब्जेक्ट्स को सुरक्षित रूप से संदर्भित करना शामिल है, ताकि प्रोसेस ऑब्जेक्ट पर रेफरेंस काउंट बढ़ाया जा सके ताकि इसे तब तक हटाया न जा सके जब तक हम nt!ObDereferenceObject का उपयोग करके अंत में स्पष्ट रूप से इसे घटा न दें, एक बार हम इसके साथ पूरा कर लें।
ध्यान दें कि रेफरेंस काउंट को मैन्युअल रूप से बढ़ाना अनावश्यक है, क्योंकि nt!PsLookupProcessByProcessId पर एक कॉल, यदि सफल होती है, तो वह हमारे लिए कर देती है।
हालाँकि, इन सुधारों को लागू करने के लिए ntoskrnl.exe का बेस पता ढूँढना और EAT को ट्रैवर्स करके किसी स्ट्रिंग हैशिंग एल्गोरिदम का उपयोग करके फ़ंक्शन पॉइंटर्स खोजने हेतु उसमें प्रतीकों को हल करना आवश्यक होगा, जिनमें से सभी पेलोड आकार को नाटकीय रूप से बढ़ा देंगे।
मैं किसी दिन उसे लागू करने का निर्णय ले सकता हूँ या बस C में लिख सकता हूँ और कंपाइलर आउटपुट को स्पैम कर सकता हूँ :)
त्रुटि(यों) को इंगित करने और समाधान सुझाने के लिए Dmytro Oleksiuk(@d_olex) और Paul L.(@am0nsec) का धन्यवाद।