
यह कमजोर हस्ताक्षरित ड्राइवरों को हथियार बनाता है ताकि EDR कर्नेल कॉलबैक, ऑब्जेक्ट कॉलबैक, ETW TI प्रदाता, और यूज़रलैंड हुक्स को बायपास कर LSASS मेमोरी डंपिंग और क्रेडेंशियल निष्कर्षण किया जा सके।
EDRSandBlast एक C में लिखा गया एक उपकरण है जो एक कमजोर हस्ताक्षरित ड्राइवर को हथियार बनाकर EDR डिटेक्शन (Notify Routine कॉलबैक, Object Callbacks और ETW TI प्रदाता) और LSASS सुरक्षाओं को बायपास करता है। उपयोगकर्ता-स्तरीय निगरानी से बचने के लिए कई उपयोगकर्ता-लैंड अनहुकिंग तकनीकें भी लागू की गई हैं।
रिलीज़ के अनुसार, उपयोगकर्ता-लैंड (--usermode) और कर्नेल-लैंड (--kernelmode) तकनीकों के संयोजन का उपयोग EDR जांच के तहत LSASS मेमोरी को डंप करने के लिए किया गया, बिना अवरुद्ध हुए या उत्पाद (क्लाउड) कंसोल में "OS Credential Dumping"-संबंधित घटनाएँ उत्पन्न किए। परीक्षण 3 अलग-अलग EDR उत्पादों पर किए गए और प्रत्येक मामले में सफल रहे।
EDR उत्पाद विंडोज पर कर्नेल "Notify Routines" कॉलबैक का उपयोग करते हैं ताकि कर्नेल को सिस्टम गतिविधि, जैसे प्रक्रिया और थ्रेड निर्माण और छवियों (exe / DLL) के लोड होने की सूचना दी जा सके।
ये कर्नेल कॉलबैक कर्नेल-लैंड से परिभाषित किए जाते हैं, आमतौर पर कॉलबैक को लागू करने वाले ड्राइवर से, कई दस्तावेजित API (nt!PsSetCreateProcessNotifyRoutine, nt!PsSetCreateThreadNotifyRoutine, आदि) का उपयोग करके। ये API कर्नेल-स्पेस में अनिर्दिष्ट रूटीन्स की सरणियों में ड्राइवर-आपूर्ति किए गए कॉलबैक रूटीन्स को जोड़ते हैं:
PspCreateProcessNotifyRoutinePspCreateThreadNotifyRoutinePspLoadImageNotifyRoutineEDRSandBlast उन सरणियों में परिभाषित रूटीन्स को गिनता है और EDR ड्राइवरों की एक पूर्वनिर्धारित सूची से जुड़े किसी भी कॉलबैक रूटीन को हटा देता है (1000 से अधिक सुरक्षा उत्पादों के ड्राइवर समर्थित हैं, EDR ड्राइवर अनुभाग देखें)। गणना और हटाने को एक कमजोर ड्राइवर (देखें कमजोर ड्राइवर अनुभाग) के शोषण द्वारा प्रदान किए गए एक मनमाने कर्नेल मेमोरी पढ़ने/लिखने के प्रिमिटिव के माध्यम से संभव बनाया गया है।
उपरोक्त सरणियों के ऑफसेट को कई तकनीकों का उपयोग करके पुनर्प्राप्त किया जाता है, कृपया ऑफसेट अनुभाग देखें।
EDR (और यहाँ तक कि EPP) उत्पाद अक्सर nt!ObRegisterCallbacks कर्नेल API के उपयोग के माध्यम से "ऑब्जेक्ट कॉलबैक" पंजीकृत करते हैं। ये कॉलबैक सुरक्षा उत्पाद को विशिष्ट ऑब्जेक्ट प्रकारों (प्रक्रियाएँ, थ्रेड और डेस्कटॉप से संबंधित ऑब्जेक्ट कॉलबैक अब विंडोज द्वारा समर्थित हैं) पर प्रत्येक हैंडल निर्माण पर सूचित होने की अनुमति देते हैं। एक हैंडल निर्माण ऑब्जेक्ट खोलने पर हो सकता है (OpenProcess, OpenThread, आदि पर कॉल) साथ ही हैंडल डुप्लिकेशन (DuplicateHandle पर कॉल, आदि)।
इनमें से प्रत्येक संचालन पर कर्नेल द्वारा सूचित होने पर, एक सुरक्षा उत्पाद हैंडल निर्माण की वैधता का विश्लेषण कर सकता है (जैसे, कोई अज्ञात प्रक्रिया LSASS खोलने का प्रयास कर रही है), और यदि कोई खतरा पाया जाता है तो उसे अवरुद्ध भी कर सकता है।
ObRegisterCallbacks का उपयोग करके प्रत्येक कॉलबैक पंजीकरण पर, _OBJECT_TYPE ऑब्जेक्ट में मौजूद CallbackList दोहरी-लिंक्ड सूची में एक नया आइटम जोड़ा जाता है जो कॉलबैक से प्रभावित ऑब्जेक्ट के प्रकार (या तो प्रक्रिया, थ्रेड या डेस्कटॉप) का वर्णन करता है। दुर्भाग्य से, इन आइटमों का वर्णन एक ऐसी संरचना द्वारा किया जाता है जो Microsoft द्वारा दस्तावेजित नहीं है और न ही प्रतीक फ़ाइलों में प्रकाशित है। हालाँकि, विभिन्न ntoskrnl.exe संस्करणों से इसका अध्ययन करने से संकेत मिलता है कि संरचना कम से कम Windows 10 बिल्ड 10240 और 22000 (2015 से 2022) के बीच नहीं बदली।
उल्लिखित संरचना, जो एक ऑब्जेक्ट कॉलबैक पंजीकरण का प्रतिनिधित्व करती है, निम्नलिखित है:```C typedef struct OB_CALLBACK_ENTRY_t { LIST_ENTRY CallbackList; // linked element tied to _OBJECT_TYPE.CallbackList OB_OPERATION Operations; // bitfield : 1 for Creations, 2 for Duplications BOOL Enabled; // self-explanatory OB_CALLBACK* Entry; // points to the structure in which it is included POBJECT_TYPE ObjectType; // points to the object type affected by the callback POB_PRE_OPERATION_CALLBACK PreOperation; // callback function called before each handle operation POB_POST_OPERATION_CALLBACK PostOperation; // callback function called after each handle operation KSPIN_LOCK Lock; // lock object used for synchronization } OB_CALLBACK_ENTRY;
ऊपर उल्लिखित `OB_CALLBACK` संरचना भी अप्रलेखित है, और इसे निम्नलिखित द्वारा परिभाषित किया गया है:```C
typedef struct OB_CALLBACK_t {
USHORT Version; // usually 0x100
USHORT OperationRegistrationCount; // number of registered callbacks
PVOID RegistrationContext; // arbitrary data passed at registration time
UNICODE_STRING AltitudeString; // used to determine callbacks order
struct OB_CALLBACK_ENTRY_t EntryItems[1]; // array of OperationRegistrationCount items
WCHAR AltitudeBuffer[1]; // is AltitudeString.MaximumLength bytes long, and pointed by AltitudeString.Buffer
} OB_CALLBACK;
EDR-पंजीकृत ऑब्जेक्ट कॉलबैक को अक्षम करने के लिए, EDRSandblast में तीन तकनीकें लागू की गई हैं; हालांकि फिलहाल केवल एक ही सक्षम है।
OB_CALLBACK_ENTRY के Enabled फ़ील्ड का उपयोग करनायह EDRSandblast में सक्षम डिफ़ॉल्ट तकनीक है। EDR-संबंधित ऑब्जेक्ट कॉलबैक का पता लगाने और अक्षम करने के लिए, Process और Thread प्रकारों से जुड़े _OBJECT_TYPE ऑब्जेक्ट्स में स्थित CallbackList सूची को ब्राउज़ किया जाता है। दोनों _OBJECT_TYPE कर्नेल में सार्वजनिक ग्लोबल सिंबल, PsProcessType और PsThreadType द्वारा इंगित किए जाते हैं।
सूची के प्रत्येक आइटम को ऊपर वर्णित OB_CALLBACK_ENTRY संरचना में फिट होना माना जाता है (यह धारणा कम से कम इस लेखन के समय सभी Windows 10 बिल्ड में मान्य प्रतीत होती है)। PreOperation और PostOperation फ़ील्ड में परिभाषित फ़ंक्शंस को यह जांचने के लिए स्थित किया जाता है कि वे किसी EDR ड्राइवर से संबंधित हैं या नहीं, और यदि हाँ, तो कॉलबैक को Enabled फ़्लैग को टॉगल करके आसानी से अक्षम कर दिया जाता है।
हालांकि यह काफी सुरक्षित तकनीक है, इसका नुकसान यह है कि यह एक अनिर्दिष्ट संरचना पर निर्भर करती है; इस संरचना के असुरक्षित हेरफेर के जोखिम को कम करने के लिए, यह सत्यापित करने के लिए बुनियादी जाँच की जाती है कि कुछ फ़ील्ड्स के अपेक्षित मान हैं:
Enabled या तो TRUE है या FALSE (हँसें नहीं, एक BOOL एक int है, इसलिए यह 1 या 0 के अलावा कुछ और भी हो सकता है);Operations OB_OPERATION_HANDLE_CREATE, OB_OPERATION_HANDLE_DUPLICATE या दोनों है;ObjectType PsProcessType या PsThreadType पर इंगित करता है।CallbackList को अनलिंक करनाएक अन्य रणनीति जो किसी अनिर्दिष्ट संरचना पर निर्भर नहीं करती है (और इस प्रकार सैद्धांतिक रूप से NT कर्नेल परिवर्तनों के विरुद्ध अधिक मजबूत है) वह प्रक्रियाओं और थ्रेड दोनों के लिए संपूर्ण CallbackList को अनलिंक करना है। _OBJECT_TYPE ऑब्जेक्ट इस प्रकार है:```C
struct _OBJECT_TYPE {
LIST_ENTRY TypeList;
UNICODE_STRING Name;
[...]
_OBJECT_TYPE_INITIALIZER TypeInfo;
[...]
LIST_ENTRY CallbackList;
}
`Flink` और `Blink` पॉइंटर्स को `CallbackList` के `LIST_ENTRY` की ओर इंगित करना, `LIST_ENTRY` को स्वयं की ओर इंगित करके प्रभावी रूप से लिस्ट को खाली कर देता है। चूँकि `_OBJECT_TYPE` संरचना कर्नेल के सिंबल में प्रकाशित होती है, यह तकनीक हार्डकोडेड ऑफ़सेट/स्ट्रक्चर पर निर्भर नहीं करती। हालाँकि, इसकी कुछ कमियाँ हैं।
पहली कमी यह है कि केवल EDR के कॉलबैक को अक्षम करना संभव नहीं है; वास्तव में, यह तकनीक सभी ऑब्जेक्ट कॉलबैक को प्रभावित करती है जो "वैध" सॉफ़्टवेयर द्वारा पंजीकृत किए गए होंगे। फिर भी, यह ध्यान दिया जाना चाहिए कि विंडोज 10 पर (इस लेखन के समय) कोई भी पूर्व-स्थापित घटक ऑब्जेक्ट कॉलबैक का उपयोग नहीं करता है, इसलिए उन्हें अक्षम करने से मशीन की स्थिरता प्रभावित नहीं होनी चाहिए (और भी अधिक यदि अक्षमीकरण केवल अस्थायी हो)।