
पॉलीमॉर्फिक एन्क्रिप्टर जो शेलकोड, PE और COFF फ़ाइलों को अस्पष्ट, स्थिति-स्वतंत्र पेलोड में बदलता है, जिसमें RC4 और यादृच्छिक ब्लॉक सिफर एन्क्रिप्शन, साथ ही AsmJit लाइब्रेरी का उपयोग करके जंक इंस्ट्रक्शन जनरेशन शामिल है।
प्रस्तुत
Shoggoth एक ओपन-सोर्स प्रोजेक्ट है जो C++ और asmjit लाइब्रेरी पर आधारित है, जिसका उपयोग दिए गए शेलकोड, PE और COFF फ़ाइलों को पॉलीमॉर्फिक रूप से एन्क्रिप्ट करने के लिए किया जाता है।
Shoggoth एक आउटपुट फ़ाइल उत्पन्न करेगा जो पेलोड और उसके संबंधित लोडर को अस्पष्ट रूप में संग्रहीत करता है। चूंकि आउटपुट की सामग्री स्थिति-स्वतंत्र (position-independent) होती है, इसे सीधे शेलकोड के रूप में निष्पादित किया जा सकता है। पेलोड निष्पादित होने के दौरान, यह रनटाइम पर स्वयं को डिक्रिप्ट करता है। एन्क्रिप्शन रूटीन के अलावा, Shoggoth रूटीन के बीच कचरा निर्देश (garbage instructions) भी जोड़ता है, जो कुछ भी नहीं बदलते हैं।
मैंने इस प्रोजेक्ट को विभिन्न डायनामिक इंस्ट्रक्शन जनरेशन दृष्टिकोणों, असेंबली प्रथाओं और सिग्नेचर डिटेक्शन का अध्ययन करने के लिए विकसित करना शुरू किया। मैं अपनी नई सीख के साथ नियमित रूप से रिपॉजिटरी को अपडेट करने की योजना बना रहा हूं।
वर्तमान विशेषताएं नीचे सूचीबद्ध हैं:
एक इनपुट फ़ाइल के लिए Shoggoth का सामान्य निष्पादन प्रवाह नीचे दी गई छवि में देखा जा सकता है। आप इस प्रवाह को डिफ़ॉल्ट कॉन्फ़िगरेशन के साथ देख सकते हैं।
मूल रूप से, Shoggoth पहले चुने गए मोड (COFF या PE फ़ाइल) और इनपुट फ़ाइल के अनुसार प्रीकंपाइल्ड लोडर शेलकोड को मर्ज करता है। फिर यह इस मर्ज किए गए पेलोड में कई कचरा निर्देश जोड़ता है। लोडर, कचरा निर्देश और पेलोड वाले स्टब को पहले RC4 एन्क्रिप्शन और फिर संबंधित डिक्रिप्टरों को जोड़कर यादृच्छिक रूप से उत्पन्न ब्लॉक एन्क्रिप्शन के साथ एन्क्रिप्ट किया जाता है। अंत में, यह परिणामी ब्लॉक में एक कचरा निर्देश जोड़ता है।
जब Shoggoth कचरा स्टब्स या एन्क्रिप्शन रूटीन के लिए निर्देशों को यादृच्छिक रूप से उत्पन्न करता है, तो यह AsmJit लाइब्रेरी का उपयोग करता है।
AsmJit C++ भाषा में लिखी गई मशीन कोड उत्पादन के लिए एक हल्की लाइब्रेरी है। यह X86, X86_64 और AArch64 आर्किटेक्चर के लिए मशीन कोड उत्पन्न कर सकती है और बेसलाइन निर्देशों और सभी हाल के एक्सटेंशनों का समर्थन करती है। AsmJit ऑपरेशन कोड, रजिस्टर, तत्काल ऑपरेंड, कॉल लेबल निर्दिष्ट करने और कोड के अंदर किसी भी ऑफ़सेट पर मनमाना मान एम्बेड करने की अनुमति देता है। AsmJit का उपयोग करके कुछ असेंबली निर्देश उत्पन्न करते समय, असेंबलर क्लास से आवश्यक असेंबली ऑपरेशन के अनुरूप API फ़ंक्शन को असेंबली ऑपरेंड मानों के साथ कॉल करना पर्याप्त है। प्रत्येक API कॉल के लिए, AsmJit अपने आंतरिक CodeHolder संरचना में कोड और स्थानांतरण जानकारी रखता है। उत्पन्न किए जाने वाले सभी असेंबली कमांड के API फ़ंक्शन को कॉल करने के बाद, इसकी JitRuntime क्लास का उपयोग CodeHolder से कोड को निष्पादन योग्य अनुमति के साथ मेमोरी में कॉपी करने और इसे स्थानांतरित करने के लिए किया जा सकता है।
जब मैं कोड उत्पादन लाइब्रेरी की खोज कर रहा था, तो मुझे AsmJit मिला और मैंने देखा कि इसका उपयोग कई लोकप्रिय प्रोजेक्टों द्वारा व्यापक रूप से किया जाता है। यही कारण है कि मैंने इसे अपनी आवश्यकताओं के लिए उपयोग करने का निर्णय लिया। मुझे नहीं पता कि Shoggoth पहला प्रोजेक्ट है जो इसे रेड टीम संदर्भ में उपयोग करता है, लेकिन मेरा मानना है कि यह भविष्य के कार्यान्वयन के लिए एक संदर्भ हो सकता है।
Shoggoth का उपयोग दिए गए PE और COFF फ़ाइलों को एन्क्रिप्ट करने के लिए किया जा सकता है ताकि प्रीकंपाइल्ड स्थिति-स्वतंत्र लोडरों के कारण दोनों को शेलकोड के रूप में निष्पादित किया जा सके। मैंने अपने पुराने प्रोजेक्टों के लिए संशोधित प्रसिद्ध PE और COFF लोडरों का PIC संस्करण प्राप्त करने के लिए C से शेलकोड विधि का उपयोग किया। संकलन के लिए, मैंने HandleKatz प्रोजेक्ट से Makefile का उपयोग किया, जो PIC रूप में एक LSASS डंपर है।
मूल रूप से, C से शेलकोड तकनीक के साथ शेलकोड प्राप्त करने के लिए, मैंने लोडर स्रोत कोड में सभी ग्लोबल वेरिएबल को हटा दिया, सभी स्ट्रिंग्स को स्टैक में संग्रहीत किया, और रनटाइम पर आवश्यक DLLs को लोड और पार्स करके विंडोज API फ़ंक्शनों के पते हल किए। उसके बाद, मैंने एक लिंकर स्क्रिप्ट के साथ एंट्री पॉइंट निर्धारित किया और विभिन्न संकलन फ्लैग के साथ MinGW का उपयोग करके कोड को संकलित किया। मैंने उत्पन्न निष्पादन योग्य फ़ाइल के .text सेक्शन को निकाला और लोडर शेलकोड प्राप्त किया। चूंकि उपरोक्त के अनुसार कोड को संपादित करने के बाद प्राप्त निष्पादन योग्य फ़ाइल में .text सेक्शन के अलावा कोई अन्य सेक्शन नहीं होता है, इसलिए इस सेक्शन में कोड को स्थिति-स्वतंत्र के रूप में उपयोग किया जा सकता है।
इनके स्रोत कोड को COFFLoader और PELoader निर्देशिकाओं से देखा और संपादित किया जा सकता है। साथ ही, इन स्रोत कोडों के संकलित संस्करण stub निर्देशिका में पाए जा सकते हैं। अभी के लिए, यदि आप इन लोडरों को संपादित या बदलना चाहते हैं, तो आपको हस्ताक्षरों का पालन करना चाहिए और stub निर्देशिका से प्रीकंपाइल्ड बाइनरी को बदलना चाहिए।
BOF को तर्क पास करने के लिए, '--coff-arg' विकल्प का उपयोग करें। Shoggoth एक पूर्व-स्वरूपित हेक्स स्ट्रिंग की अपेक्षा करता है जिसमें पैक किए गए तर्क होते हैं, जिसे TrustedSec के beacon_generate.py स्क्रिप्ट का उपयोग करके बनाया जा सकता है। इस स्क्रिप्ट की एक प्रति COFFArgGenerator/beacon_generate.py के रूप में शामिल की गई है। (@Octoberfest7 को बहुत-बहुत धन्यवाद)
Shoggoth पहले अपने द्वारा प्राप्त पेलोड को एन्क्रिप्ट करने के लिए स्ट्रीम सिफरों में से एक, RC4 एल्गोरिथम का उपयोग करता है। यहां उपयोग की जाने वाली कुंजी को यादृच्छिक रूप से उत्पन्न करने के बाद, यह उस कुंजी के साथ पेलोड को एन्क्रिप्ट करता है। डिक्रिप्टर स्टब, जो रनटाइम के दौरान पेलोड को डिक्रिप्ट करता है, AsmJit का उपयोग करके गतिशील रूप से बनाया और असेंबल किया जाता है। स्टब में उपयोग किए जाने वाले रजिस्टर प्रत्येक नमूने के लिए यादृच्छिक रूप से चुने जाते हैं।
मैंने Shoggoth में उपयोग किए गए RC4 एल्गोरिथम के कार्यान्वयन के लिए Nayuki के कोड का संदर्भ लिया।
पहला एन्क्रिप्शन करने के बाद, Shoggoth दूसरे एन्क्रिप्शन का उपयोग करता है जो एक यादृच्छिक रूप से उत्पन्न ब्लॉक सिफर है। दूसरे एन्क्रिप्शन के साथ, यह RC4 डिक्रिप्टर और वैकल्पिक रूप से उस स्टब को एन्क्रिप्ट करता है जिसमें RC4 के साथ एन्क्रिप्ट किया गया पेलोड, कचरा निर्देश और लोडर होता है। यह एन्क्रिप्ट किए जाने वाले चंक को 8-बाइट ब्लॉकों में विभाजित करता है और प्रत्येक ब्लॉक के लिए यादृच्छिक रूप से उत्पन्न निर्देशों का उपयोग करता है। इन निर्देशों में ADD, SUB, XOR, NOT, NEG, INC, DEC, ROL और ROR शामिल हैं। इन निर्देशों के लिए ऑपरेंड भी यादृच्छिक रूप से चुने जाते हैं।