
मैलवेयर विश्लेषकों को निराश/हराने के लिए POC
नीचे दिया गया कार्य एक POC (प्रूफ ऑफ कॉन्सेप्ट) है जो मैलवेयर को किसी विशेष पीड़ित के लिए स्वयं को "की" करने में सक्षम बनाता है, ताकि मैलवेयर विश्लेषकों के प्रयासों को विफल किया जा सके।
मैं इस परियोजना में निहित किसी भी विचार या कोड के दुर्भावनापूर्ण उपयोग के लिए कोई जिम्मेदारी नहीं लेता हूँ। मैं यह शोध इन्फोसेक पेशेवरों को और शिक्षित करने तथा मैलवेयर विश्लेषकों, रिवर्स इंजीनियर्स और ब्लू टीमर्स के लिए अतिरिक्त प्रशिक्षण/विचारणीय विषय प्रदान करने के लिए प्रस्तुत कर रहा हूँ।
पहली बार जब मैलवेयर किसी पीड़ित पर चलता है, तो यह उस पीड़ित के पर्यावरणीय डेटा का उपयोग करके वास्तविक पेलोड (एक RDLL) को AES एन्क्रिप्ट करता है। हर बार जब मैलवेयर बाद में चलाया जाता है, तो यह वही पर्यावरणीय जानकारी एकत्र करता है, मैलवेयर के भीतर बाइट ऐरे के रूप में संग्रहीत पेलोड को AES डिक्रिप्ट करता है, और उसे चलाता है। यदि डिक्रिप्शन विफल हो जाता है/पेलोड चलने में विफल हो जाता है, तो मैलवेयर स्वयं को डिलीट कर देता है। रिवर्स इंजीनियर्स और मैलवेयर विश्लेषकों से सुरक्षा।


मुझे लगा कि यह परियोजना पूरी नहीं हुई है, इसलिए मैं वापस गया और काफी बड़ा पुनर्लेखन किया। मूल शोध और ट्रेडक्राफ्ट यहाँ पाया जा सकता है।
प्रमुख परिवर्तन इस प्रकार हैं:
इस परियोजना के स्रोत कोड से कई अलग-अलग चीजें ली जा सकती हैं जिनका उपयोग कहीं और किया जा सकता है। उम्मीद है कि यह किसी के लिए उपयोगी होगा।
BeatRev की मूल रिलीज़ में कुछ कमियाँ थीं जिन्हें मैंने हल करने का निर्णय लिया।
Stage2 पहले एक स्वतंत्र निष्पादन योग्य था जिसे Stage1 के वैकल्पिक डेटा स्ट्रीम (ADS) के रूप में संग्रहीत किया जाता था। पीड़ित-द्वारा AES एन्क्रिप्शन और उसके बाद डिक्रिप्शन और निष्पादन प्राप्त करने के लिए, हर बार Stage1 चलने पर यह ADS को पढ़ता, डिक्रिप्ट करता, ADS पर वापस लिखता, CreateProcess को कॉल करता, और फिर Stage2 को पुनः एन्क्रिप्ट करके ADS में डिस्क पर वापस लिखता। यह बहुत सारे I/O ऑपरेशन थे और निश्चित रूप से CreateProcess कॉल भी अच्छा नहीं था।
मैं संयोग से Steven Fewer के Reflective DLL पर शोध के पार आया और यह एक अच्छा फिट लगा। Stage2 अब एक RDLL है; हमारा मैलवेयर/शेलकोड रनर/जो कुछ भी हम सुरक्षित रखना चाहते हैं उसे RDLL प्रारूप में पोर्ट किया जा सकता है और Stage1 के भीतर एक बाइट ऐरे के रूप में संग्रहीत किया जा सकता है जो रनटाइम पर डिक्रिप्ट होता है और Stage1 द्वारा निष्पादित किया जाता है। यह संस्करण 1 से सभी I/O ऑपरेशन और CreateProcess कॉल को हटा देता है और एक स्वागत योग्य परिवर्तन है।
Stage1 में किसी भी प्रकार के वास्तविक AV एवेज़न उपाय प्रोग्राम नहीं किए गए थे; यह जानबूझकर किया गया था, क्योंकि यह अतिरिक्त काम है और वास्तव में इस शोध का उद्देश्य नहीं था। पुनर्लेखन के दौरान मैंने इसे एक अतिरिक्त चुनौती के रूप में लिया और Stage1 के इम्पोर्ट एड्रेस टेबल से फ़ंक्शन हटाने के लिए API-हैशिंग जोड़ी। इससे डिटेक्शन में मदद मिली है और VirusTotal पर Stage1 की डिटेक्शन दर 4/66 है। मैं Stage1 को अपलोड करने में सहज था क्योंकि यह पहले से ही उस मूल मशीन से keyed है जिस पर इसे चलाया गया था और होने वाले AES एन्क्रिप्शन के कारण फ़ाइल सिग्नेचर लगातार बदलता रहता है।
मैंने हाल ही में मैलवेयर का पता लगाने के साधन के रूप में एन्ट्रॉपी पर ध्यान देना शुरू किया; एक विशाल AES एन्क्रिप्टेड बाइनरी ब्लॉब के कारण अन्यथा बहुत अधिक एन्ट्रॉपी को कम करने के प्रयास के लिए मैंने UUID के रूप में संग्रहीत शेलकोड को एकीकृत करने पर विचार किया। चूंकि बाइनरी स्ट्रिंग प्रतिनिधित्व में संग्रहीत है, निष्पादन योग्य में समग्र एन्ट्रॉपी कम होती है। इस तकनीक का उपयोग करके Stage0 की एन्ट्रॉपी अब ~6.8 और Stage1 की ~4.5 (अधिकतम पैमाने 8 पर) है।
अंत में, उन सभी टुकड़ों को एकीकृत करना और एक पूर्ण Stage0 तैयार करना एक बहुत बड़ा काम है जिनमें हेरफेर किया जाना चाहिए। इसे आसान बनाने के लिए मैंने एक बिल्डर एप्लिकेशन बनाया है जो एक Stage0.c टेम्पलेट फ़ाइल, एक Stage1 स्टब, एक Stage2 स्टब और एक रॉ शेलकोड फ़ाइल (यह Stage2 के लिए CobaltStrike शेलकोड वाले शेलकोड रनर के आसपास बनाया गया था) को इन्जेस्ट करेगा और लक्ष्य पर उपयोग के लिए एक संकलित Stage0 पेलोड तैयार करेगा।
Stephen Fewer का Reflective DLL कोड कुछ Visual Studio कंपाइलर-विशिष्ट निर्देश शामिल करता है; मुझे यकीन है कि तकनीक को MingW पर पोर्ट करना संभव है लेकिन मेरे पास ऐसा करने का कौशल नहीं है। यहाँ मुख्य समस्या यह है कि CobaltStrike शेलकोड (स्टेजलेस ~265K है) को RDLL के अंदर जाना चाहिए और संकलित होना चाहिए। इससे निपटने और इसे बाकी प्रक्रिया के साथ अच्छी तरह से एकीकृत करने के लिए मैंने अपना Stage2 RDLL लिखा ताकि इसमें CS शेलकोड के आकार की मेमोरी का एक ग्लोबल वेरिएबल चंक हो; मेमोरी के इस ~265K चंक में एक छोटा प्लेसहोल्डर है जिसे संकलित बाइनरी में स्थित किया जा सकता है। src/Stage2 में कोड में यह पहले से ही जोड़ा गया है।
एक बार संकलित होने के बाद, इस Stage2stub को kali में स्थानांतरित किया जाता है जहाँ वास्तविक CS शेलकोड को उस स्थान पर चिपकाने के लिए एक बाइनरी पैच किया जा सकता है जहाँ यह संबंधित है। यह पूर्ण Stage2 तैयार करता है।
पहले वर्णित I/O और CreateProcess फियास्को से बचने के लिए, पूर्ण Stage2 को Stage0 द्वारा संकलित Stage1 में भी पैच किया जाना चाहिए; यह Stage2 को एक बार लक्ष्य पर एन्क्रिप्ट करने की अनुमति देने के अलावा Stage2 को डिस्क पर अलग से संग्रहीत होने से रोकने के लिए आवश्यक है। प्रत्येक स्टब के भीतर प्लेसहोल्डर का पता लगाने के लिए memmem फ़ंक्शन का उपयोग किया जाता है; यह फ़ंक्शन विंडोज़ पर उपलब्ध नहीं है, इसलिए एक कस्टम कार्यान्वयन का उपयोग किया गया था। Foxik384 उनके कोड के लिए धन्यवाद।
बाइनरी पैच करने के लिए, हमें आवश्यक मेमोरी पहले से आवंटित करनी होगी; इसका एक संयुक्त प्रभाव होता है, क्योंकि Stage1 को अब Stage2 को भी शामिल करने के लिए पर्याप्त बड़ा होना चाहिए। Stage2 को UUID स्ट्रिंग में बदलने के अतिरिक्त चरण के साथ, Stage2 आकार में बढ़ जाता है और इसे धारण करने के लिए Stage1 भी बढ़ जाता है। ~290K के संकलित आकार वाला एक Stage2 RDLL ~1.38M के Stage0 पेलोड और ~700K के Stage1 पेलोड में परिणत होता है।
बिल्डर एप्लिकेशन केवल x64 EXE बनाने का समर्थन करता है। हालांकि थोड़ा और काम करके आप सिद्धांत रूप में Stage0 को DLL बना सकते हैं, साथ ही Stage1 को भी, और पूरे जीवनचक्र को एक स्वतंत्र निष्पादन योग्य के बजाय DLL हाइजैक के रूप में मौजूद कर सकते हैं।
ये निर्देश आपको इस POC का उपयोग करने के लिए मार्गदर्शन करेंगे।