
EDRs को बायपास करने के लिए divide and conquer दृष्टिकोण लागू करें
Divide and Conquer एक एल्गोरिदम है जिसे प्रोग्रामिंग में आमतौर पर किसी जटिल समस्या को कई सरल उप-समस्याओं में विभाजित करके हल करने के लिए लागू किया जाता है। हम इस दृष्टिकोण को एक अलग लक्ष्य के साथ आक्रामक सुरक्षा (offensive security) में लागू कर सकते हैं: EDR को भ्रमित करना ताकि वे हमारी गतिविधियों से नज़र न हटाएं, उन्हें कोई अलर्ट उठाने से रोकना। यह कुछ ऐसा ही है जो हाल ही में लगभग हर फ़िशिंग अभियान (phishing campaign) में देखने को मिलता है: लंबी संक्रमण श्रृंखलाएं, कई फ़ाइलों को चरण-दर-चरण चलाना (जैसे e.g. .url -> .one -> .js -> .bat -> .dll) बजाय सीधे अंतिम पेलोड (payload) को चलाने के। निष्पादित की गई प्रत्येक फ़ाइल एक सरल कार्य करती है (दूसरी फ़ाइल डाउनलोड करना, रजिस्ट्री में कोई बदलाव करना, फ़ाइलों को निर्देशिकाओं के बीच ले जाना या उनके नाम/एक्सटेंशन बदलना आदि) जिसे अपने आप में दुर्भावनापूर्ण (malicious) के रूप में टैग करना कठिन होता है, और यह अंतिम निष्पादन के लिए वातावरण तैयार करती है।
मैंने इस सरल विचार का परीक्षण करने का निर्णय लिया लेकिन इसे कुछ अलग चीज़ पर लागू किया, इस मामले में, एक रिमोट प्रोसेस इंजेक्शन (remote process injection)। इस रिपॉजिटरी में प्रस्तुत कोड कुछ नया नहीं है, इसके विपरीत, यह संभवतः किसी रिमोट प्रोसेस में शेलकोड (shellcode) इंजेक्ट करने के सबसे सामान्य और सीधे तरीकों में से एक है: NtOpenProcess, NtAllocateVirtualMemory, NtWriteVirtualMemory, NtProtectVirtualMemory और NtCreateThreadEx का उपयोग करना। केवल अंतर यह है कि मैं उन प्रत्येक कॉल के बाद NtCreateUserProcess का उपयोग करके प्रोसेस को फोर्क (fork) कर रहा हूं। चूंकि फोर्क की गई प्रोसेस RIP + 1 से निष्पादन जारी रखती है और मेमोरी पूरी तरह से पैरेंट से कॉपी होती है, हम रिमोट प्रोसेस इंजेक्शन 5 अलग-अलग प्रोसेस का उपयोग करके कर सकते हैं, हमें बस यह सुनिश्चित करना होगा कि बाद के API कॉल के लिए आवश्यक कोई भी हैंडल (handle) ठीक से इनहेरिट (inherit) किया गया हो।
इस तरह, हम शेलकोड इंजेक्शन प्रक्रिया को सरल कार्यों में विभाजित करते हैं, और उनमें से प्रत्येक को एक अलग संदर्भ (प्रोसेस) में चलाते हैं।
मैंने इस PoC का परीक्षण आजकल के तीन सबसे आम EDR के विरुद्ध किया है: MDE, CrowdStrike और SentinelOne। परिणाम अपने आप में बोलते हैं: बिना फोर्क के PoC चलाने पर 3 में से 2 EDR ने रिमोट प्रोसेस इंजेक्शन अलर्ट उठाया; इसके विपरीत, एक बार जब मैंने फोर्किंग तंत्र (forking mechanism) पेश किया, तो उनमें से किसी ने भी कोई अलर्ट नहीं उठाया।
बेशक, फोर्क तंत्र के साथ भी हम रॉ टेलीमेट्री (raw telemetry) में प्रोसेस निर्माण, थ्रेड निर्माण और सभी क्रॉस-प्रोसेस व्यवहार के अनुरूप घटनाओं को देख सकते हैं, लेकिन ऐसा प्रतीत होता है कि EDR के लिए गतिविधि को दुर्भावनापूर्ण के रूप में टैग करने के लिए यह पर्याप्त नहीं है, जो इस PoC की बात को सिद्ध करता है। दुर्भावनापूर्ण व्यवहार को सरल कार्यों में विभाजित करके और उनमें से प्रत्येक को एक अलग प्रोसेस से चलाकर हम EDR को भ्रमित कर सकते हैं और उन्हें कोई अलर्ट उठाने से रोक सकते हैं।
यही परिणाम अलग-अलग तरीकों से भी प्राप्त किया जा सकता था, मैंने केवल अपने कोड को सरल बनाने और क्रॉस-प्रोसेस गतिविधि को कम करने के लिए फोर्क तंत्र का उपयोग किया।
यदि आप स्वयं इसका परीक्षण करना चाहते हैं, तो fork() फ़ंक्शन के कॉल के साथ और बिना कॉल के कोड को कंपाइल करें, और फिर दोनों पेलोड को वांछित EDR वाले वातावरण में चलाएं।
चूंकि हम स्ट्रिंग लिटरल (string literals) को अस्पष्ट (obfuscate) करने के लिए LITCRYPT प्लगइन का उपयोग कर रहे हैं (केवल Dinvoke_rs कोड के लिए), इसलिए कोड कंपाइल करने से पहले पर्यावरण चर LITCRYPT_ENCRYPT_KEY को सेट करना आवश्यक है:
C:\Users\User\Desktop\Split> set LITCRYPT_ENCRYPT_KEY="yoursupersecretkey"
उसके बाद, बस कोड कंपाइल करें और टूल चलाएं:
C:\Users\User\Desktop\Split> cargo build --release
C:\Users\User\Desktop\Split\target\release> split.exe -h
यह तकनीक अकेले किसी EDR को बायपास करने के लिए पर्याप्त नहीं है; यदि आपका कोड opsec के दृष्टिकोण से बिल्कुल भी सुरक्षित नहीं है, तो बहुत संभव है कि आप फिर भी पकड़े जाएं। यह कोई जादुई गोली नहीं है, बस बचाव (evasion) की एक और परत है जिसे आप अपने टूल्स में जोड़ सकते हैं। फिर भी, इस रिपॉजिटरी में प्रस्तुत कोड निम्नलिखित कारणों सहित अन्य कारणों से opsec के दृष्टिकोण से बिल्कुल भी सुरक्षित नहीं है:
दूसरी ओर, मैंने इस दृष्टिकोण का परीक्षण केवल उल्लिखित EDR के विरुद्ध किया है, और मुझे नहीं पता कि अन्य EDR भी इसी तरह बायपास होंगे या नहीं। आप इसका परीक्षण कर सकते हैं और मुझे बता सकते हैं कि परिणाम क्या रहा ;)