
CobaltStrike Beacons में अप्रबंधित Windows निष्पादन योग्य फ़ाइलों को निष्पादित करें
Inline-Execute-PE CobaltStrike के लिए Beacon Object Files (BOF's) और एक संगत Aggressor स्क्रिप्ट का एक सूट है जो ऑपरेटरों को अप्रबंधित Windows निष्पादन योग्य फ़ाइलों को Beacon मेमोरी में लोड करने और उन्हें निष्पादित करने, आउटपुट प्राप्त करने और Beacon कंसोल में प्रस्तुत करने में सक्षम बनाता है।
यह ऑपरेटरों को कई तृतीय-पक्ष टूल्स (Mimikatz, Dsquery, Sysinternals टूल्स, आदि) का उपयोग करने में सक्षम बनाता है, बिना उन्हें डिस्क पर डालने, Donut जैसे टूल का उपयोग करके पोजीशन-इंडिपेंडेंट कोड में सुधारने, या उन्हें चलाने के लिए एक नई प्रक्रिया बनाने की आवश्यकता के।
ये निष्पादन योग्य फ़ाइलें Beacon मेमोरी में मैप की जाती हैं ताकि उन्हें बार-बार चलाया जा सके, बिना उन्हें नेटवर्क पर भेजने, नई मेमोरी आवंटित करने, और हर बार एक नया conhost.exe प्रक्रिया बनाने की आवश्यकता के।
Beacons में लोड की गई निष्पादन योग्य फ़ाइलें CobaltStrike Team Server से जुड़े सभी CobaltStrike Clients द्वारा सुलभ और चलाने योग्य होती हैं।
Inline-Execute-PE को x64 Beacons और Mingw या Visual Studio का उपयोग करके संकलित x64 Windows C या C++ निष्पादन योग्य फ़ाइलों के लिए डिज़ाइन किया गया था। यह प्रोजेक्ट x86 निष्पादन योग्य फ़ाइलों या किसी भिन्न भाषा में लिखी गई या किसी भिन्न कंपाइलर का उपयोग करके संकलित x64 निष्पादन योग्य फ़ाइलों का समर्थन नहीं करता है।

रिपॉजिटरी को क्लोन करें और BOF's को पुनः संकलित करने के लिए वैकल्पिक रूप से make चलाएं।
CobaltStrike क्लाइंट में Inline-Execute-PE.cna लोड करें। सुनिश्चित करें कि जिस निर्देशिका से CobaltStrike चल रहा है वह आपके उपयोगकर्ता द्वारा लिखने योग्य है; Inline-Execute-PE वहां एक टेक्स्ट फ़ाइल (petable.txt) बनाता है ताकि Inline-Execute-PE के कार्य करने के लिए आवश्यक डेटा की उपलब्धता सुनिश्चित हो सके।
Inline-Execute-PE में 3 लक्ष्य-मुखी कमांड होते हैं जो BOF's चलाते हैं, और 3 आंतरिक कमांड होते हैं जो प्रोजेक्ट डेटा-संरचना में हेरफेर करते हैं:
लक्ष्य-मुखी:
आंतरिक डेटा-संरचना:
peload Inline-Execute-PE की शुरुआत है। इस कमांड का उपयोग PE को Beacon मेमोरी में लोड करने के लिए किया जाता है। यह निम्नलिखित प्रमुख क्रियाएं करता है:
perun Inline-Execute-PE में दूसरा चरण है। यह निम्नलिखित प्रमुख क्रियाएं करता है:
peunload को तब कॉल किया जाता है जब कोई ऑपरेटर PE के साथ काम पूरा कर लेता है या कोई भिन्न PE लोड करना चाहता है। यह निम्नलिखित प्रमुख क्रियाएं करता है:
petable का उपयोग वर्तमान में Beacons में लोड सभी PE के बारे में जानकारी प्रदर्शित करने के लिए किया जाता है।
प्रत्येक CobaltStrike क्लाइंट का अपना petable होता है; Inline-Execute-PE अपने डेटा की सिंक्रोनिटी सुनिश्चित करने के लिए बहुत प्रयास करता है ताकि PE का उपयोग सभी ऑपरेटरों द्वारा किया जा सके। इसके बारे में अधिक जानने के लिए, "Design Considerations and Commentary" देखें।

peconfig का उपयोग Inline-Execute-PE के कार्य करने के तरीके से संबंधित विकल्पों को कॉन्फ़िगर करने के लिए किया जाता है। दो वर्तमान विकल्प जिन्हें बदला जा सकता है वे हैं:
pebroadcast का उपयोग किसी क्लाइंट के petable की सामग्री को मैन्युअल रूप से अन्य सभी जुड़े CobaltStrike क्लाइंट्स को प्रसारित करने के लिए किया जा सकता है।
अन्य सभी CobaltStrike क्लाइंट प्रसारित डेटा के साथ अपने petable को अपडेट करेंगे। यह वास्तव में कभी भी आवश्यक नहीं होना चाहिए, लेकिन यह सुविधा केवल मामले में मौजूद है।
PE को Beacon मेमोरी में लोड करने के लिए peload का उपयोग करें

वैकल्पिक रूप से, यदि लक्ष्य मशीन पर कोई PE है जिसे आप एक नई प्रक्रिया बनाए बिना उपयोग करना चाहते हैं, तो पथ और --local स्विच प्रदान करें

perun को कॉल करें, लोड किए गए PE को कोई भी तर्क पास करें

तर्कों में डबल कोट्स को बैकस्लैश का उपयोग करके एस्केप किया जाना चाहिए

यदि आपने पहचान लिया है कि एक PE अनलोड के दौरान DLL को मुक्त करने का प्रयास करने पर समस्याएं पैदा करता है, तो unloadlibraries को false पर सेट करने के लिए peconfig का उपयोग करें

एक बार जब आप PE का उपयोग कर लेते हैं, तो इसे Beacon से साफ करने के लिए peunload को कॉल करें

अब एक अलग PE को Beacon में लोड किया जा सकता है

आपको PE को पास किए जाने वाले कमांड लाइन तर्कों के बारे में सावधान रहना चाहिए; कुछ PE गलत तर्क दिए जाने पर सीधे क्रैश हो जाते हैं, जबकि अन्य अंतहीन रूप से चलते रहते हैं और Beacon कभी वापस कॉल नहीं करता, भले ही प्रक्रिया अभी भी चल रही हो।
यह Mimikatz.exe के साथ देखा जा सकता है जब 'exit' तर्कों की सूची के अंत में निर्दिष्ट नहीं किया जाता है

...

Inline-Execute-PE निर्दिष्ट टाइमआउट मान तक पहुंचने के बाद चल रहे PE के थ्रेड को समाप्त कर देगा। यह Beacon को सामान्य संचार फिर से शुरू करने में सक्षम बनाता है (perun BOF के निष्पादन को पूरा करने तक Beacon वापस कॉल नहीं करता है)। जबकि इस Beacon में सामान्य CobaltStrike कमांड और अन्य BOF का अभी भी उपयोग किया जा सकता है, Inline-Execute-PE अब अक्षम हो जाता है; जब किसी चल रहे PE को इस तरह से समाप्त किया जाता है, तो ऐसा लगता है कि यह Beacon प्रक्रिया में stdout और stderr को तोड़ देता है, और बाद में लोड किए गए PE ठीक से काम नहीं करते हैं।
PE को अभी भी Beacon मेमोरी से अनलोड किया जा सकता है (और किया जाना चाहिए), हालांकि petable को देखने पर पता चलेगा कि इस Beacon में अब अतिरिक्त PE लोड नहीं किए जा सकते हैं। 
यह अनिवार्य है कि आप Inline-Execute-PE का उपयोग करके चलाने के इच्छुक PE का परीक्षण करें, और perun को कमांड लाइन तर्क देते समय सावधानी बरतें। कुछ PE दूसरों की तुलना में अधिक क्षमाशील होते हैं।
नीचे कुछ विशिष्ट PE के बारे में परीक्षण और विकास के दौरान किए गए अवलोकन दिए गए हैं जिन्हें उपयोगकर्ता Beacon में लोड करना चाह सकते हैं, बिना किसी विशेष क्रम के।
Inline-Execute-PE से जुड़े IOC में शामिल हैं लेकिन इन्हीं तक सीमित नहीं हैं:
मैंने विकास के दौरान एक EDR के खिलाफ इसका पूर्ण-बैटरी परीक्षण नहीं किया, आंशिक रूप से आलस्य के कारण और आंशिक रूप से परीक्षण वातावरण की अनुपलब्धता के कारण। हालाँकि, इसका परीक्षण नवीनतम पैच Windows Defender (जो मेरे अनुभव में एक काफी अच्छा AV उत्पाद है) के खिलाफ किया गया था।
Mimikatz.exe शायद सबसे संदिग्ध और प्रसिद्ध PE है जो Inline-Execute-PE के साथ उपयोग के लिए उम्मीदवार के रूप में दिमाग में आता है। मैंने पाया कि Windows Defender की Inline-Execute-PE का उपयोग करके चल रहे Mimikatz का पता लगाने की क्षमता उस प्रक्रिया पर निर्भर करती थी जिसमें Beacon चल रहा था।
एक स्टैंडअलोन निष्पादन योग्य (beacon.exe जिसमें आर्टिफैक्ट किट है ताकि यह निष्पादित हो सके और सामान्य रूप से Defender से आगे चल सके) में चलने वाला एक बीकन Inline-Execute-PE के साथ Mimikatz.exe का उपयोग करने पर पकड़ा जाएगा।
एक Windows प्रक्रिया (Explorer.exe, notepad.exe, आदि में इंजेक्ट किया गया या DLL को एक वैध प्रक्रिया में साइडलोड किया गया) में चलने वाला एक बीकन Inline-Execute-PE के साथ Mimikatz.exe का उपयोग करने पर नहीं पकड़ा जाएगा।
यूज़रलैंड हुकिंग करने वाले EDR के संबंध में, जैसा कि मैंने कहा, मैंने परीक्षण नहीं किया है, लेकिन मेरे पास निम्नलिखित सामान्य विचार हैं:
चूंकि PE Beacon प्रक्रिया के अंदर चल रहा है, जिसमें आपने संभवतः पहले से ही NTDLL को अनहुक/रिफ्रेश कर लिया है, मुझे लगता है कि PE द्वारा किए गए API कॉल के फ्लैग होने में आपको बहुत अधिक समस्याएं नहीं होनी चाहिए। PE वास्तव में जो करता है (प्रक्रियाओं को छूना, रेजिस्ट्री कुंजियों को बदलना, आदि) उससे संबंधित वही मुद्दे अभी भी लागू होते हैं।### PE टाइमआउट और बचाव जिन लोगों ने कभी BOF लिखने की कोशिश की है, वे जानते हैं कि इसके सभी फायदों के बावजूद, एक बड़ा खतरा इस तथ्य में निहित है कि आपके BOF में कोई त्रुटि या क्रैश आपके Beacon को मार सकता है। इस परियोजना में, उपयोगकर्ताओं के पास Inline-Execute-PE को डेटा देने पर जितना नियंत्रण है, और मेरे (डेवलपर) द्वारा आसानी से या विश्वसनीय रूप से कितने सुरक्षा उपाय लागू किए जा सकते हैं, उसके स्वभाव से खतरा और बढ़ जाता है। उपयोगकर्ता, उदाहरण के लिए, x86 PE को x64 Beacon में लोड करके अपने Beacon को क्रैश कर सकते हैं, या इससे भी अधिक सामान्य रूप से, जैसा कि मैंने पहले बताया, मैप किए गए PE को गलत तर्क दे सकते हैं। जबकि मैं उपयोगकर्ताओं को उनके PE को गलत तर्क देकर Beacon को क्रैश करने से नहीं रोक सकता, मैं अंतहीन रूप से चल रहे PE के मामले में उनके Beacon को बचाने की कोशिश कर सकता हूँ, जैसे कि Mimikatz के मामले में जब 'exit' निर्दिष्ट नहीं किया गया हो।
आदर्श रूप से, मैं PE के निष्पादन को रोक पाऊंगा, जिससे Beacon सामान्य कार्य फिर से शुरू कर सके, और फिर तुरंत उपयोगकर्ता को (उम्मीद है कि इस बार सही तर्कों के साथ) फिर से प्रयास करने दे सकूं। व्यवहार में, मैंने पाया कि PE को समाप्त करने से stdout/stderr से जुड़े FILE* टूट जाते हैं, और PE को पूरी तरह से अनलोड करके फिर से लोड करने से भी यह समस्या हल नहीं होती; वे पूरी प्रक्रिया में टूट जाते हैं।
एक PE को समाप्त करने के लिए जो 'timeout' विकल्प के बाद भी चलता रहता है, CreateThread से लौटाए गए हैंडल पर TerminateThread कॉल किया जाता है। यह थ्रेड को किसी भी चीज़ से सुरुचिपूर्ण ढंग से बाहर निकलने की अनुमति नहीं देता है, इसलिए यह समझ में आता है कि कुछ चीज़ें टूट सकती हैं। मैंने thread hijacking लागू करके इसे कम करने की कोशिश की, जिसका लक्ष्य PE थ्रेड को निलंबित करना और उसके निष्पादन को ExitThread() API पर पुनर्निर्देशित करना था। यहाँ उम्मीद थी कि यदि यह वह थ्रेड है जिसने बाहर निकलने की प्रक्रिया शुरू की है (बजाय बलपूर्वक बाहरी रूप से समाप्त किए जाने के), तो इसके परिणामस्वरूप stdout/stderr काम करता रह सकता है, लेकिन मुझे वही समस्या हुई (साथ ही Mimikatz के मामले में PE थ्रेड को निलंबित करने में असमर्थता का अनुभव हुआ)।
इस समस्या को कम करने में असमर्थ, मैं केवल उपयोगकर्ताओं को प्रभावित Beacon में PE को चलाने या अतिरिक्त PE लोड करने से रोकने पर उतर आया (जिसके परिणामस्वरूप निश्चित रूप से क्रैश होगा)। यह Inline-Execute-PE का एक और उदाहरण है जहाँ यह मेरी इच्छित स्थिति से कम है, लेकिन मैं इस तथ्य पर सहमत हो गया कि ऑपरेटर के पास कम से कम उनका Beacon तो होगा और वे इसका उपयोग सामान्य कार्यक्षमता के लिए कर सकते हैं।
इस परियोजना का एक चुनौतीपूर्ण हिस्सा टीम सर्वर से जुड़े सभी CobaltStrike क्लाइंट के लिए Beacon में लोड किए गए PE की उपलब्धता सुनिश्चित करना था। Inline-Execute-PE का डेटा Inline-Execute-PE.cna द्वारा बनाई गई संरचनाओं में संग्रहीत होता है, जिसे टूल का उपयोग करने वाले प्रत्येक क्लाइंट में लोड किया जाना चाहिए; परिणामस्वरूप, ये डेटा संरचनाएँ प्रत्येक क्लाइंट में रहती हैं, टीम सर्वर पर नहीं। यदि यह डेटा एक ही केंद्रीय स्थान (TS) में होता, तो प्रत्येक क्लाइंट से इसे प्राप्त करना आसान होता और यह पूरी बात कोई मुद्दा नहीं होती; यदि CobaltStrike टीम औपचारिक रूप से Inline-Execute-PE जैसी क्षमता को CobaltStrike में एकीकृत करती, तो मुझे पूरा विश्वास है कि वे इसी दिशा में जाएंगे। लेकिन चूँकि यह एक सामुदायिक ऐड-ऑन है, हम जो कुछ भी हमारे पास है, उसी में काम चलाते हैं।
जब हमें यह सुनिश्चित करने की बात आती है कि प्रत्येक CobaltStrike क्लाइंट के पास Beacon में लोड किए गए PE के बारे में नवीनतम, सटीक डेटा हो, तो हमें कुछ अलग-अलग परिदृश्यों के बारे में चिंता करनी होती है:
इन परिदृश्यों को संबोधित करने के लिए एक बहु-आयामी दृष्टिकोण अपनाया गया। ऐसे मामले को संभालने के लिए जहाँ केवल एक CobaltStrike क्लाइंट TS से जुड़ा है (और इस प्रकार वही एकमात्र इकाई है जिसके पास petable डेटा है), हर बार जब क्लाइंट petable में बदलाव करता है (peload, peconfig, peunload, आदि), यह अपने petable की सामग्री को CobaltStrike निर्देशिका में स्थित एक स्थानीय टेक्स्ट फ़ाइल में भी लिखता है। यदि क्लाइंट बाहर निकलता/पुनः आरंभ होता है, या जब Inline-Execute-PE.cna पुनः लोड होता है, तो यह पहले अपने इन-मेमोरी petable को आबाद करने के लिए स्थानीय petable.txt फ़ाइल से पढ़ने का प्रयास करेगा।
जब TS से कई क्लाइंट जुड़े होते हैं और एक नया क्लाइंट शामिल होता है (जैसा कि इवेंट लॉग में बताया गया है), प्रत्येक क्लाइंट TS से जुड़े सभी उपयोगकर्ताओं की एक सूची प्राप्त करता है और उसे वर्णमाला क्रम में क्रमबद्ध करता है। उस सूची में पहला क्लाइंट "ब्रॉडकास्ट" क्लाइंट के रूप में चुना जाता है, और 5 सेकंड प्रतीक्षा करने के बाद (नए क्लाइंट को प्रारंभ करने और अपना स्थानीय petable.txt पढ़ने की अनुमति देने के लिए) यह अपने petable में प्रत्येक प्रविष्टि के लिए इवेंट लॉग में संदेश (Actions) भेजेगा। सभी क्लाइंट (ब्रॉडकास्ट करने वाले को छोड़कर) इन संदेशों को पढ़ेंगे और प्रसारित जानकारी के साथ अपने petables को अपडेट करेंगे; इसमें मौजूदा प्रविष्टियों को अपडेट करना और साथ ही उन अतिरिक्त प्रविष्टियों को जोड़ना शामिल है जो उनके संबंधित petables में नहीं हैं।
Inline-Execute-PE से जुड़े सामान्य संचालन भी इवेंट लॉग में संदेश भेजने पर निर्भर करते हैं। जब क्लाइंट A peload चलाता है, तो सभी प्रासंगिक petable जानकारी वाला एक संदेश प्रसारित किया जाता है; ALL क्लाइंट "on Event_Action" हुक का उपयोग करके इन प्रसारित इवेंट लॉग संदेशों को पार्स करके अपने संबंधित petables को अपडेट करते हैं। जब peload और peunload अपने BOF का निष्पादन पूरा करते हैं, तो Inline-Execute-PE डेटा में भी परिवर्तन किए जाते हैं; ये परिवर्तन Beacon द्वारा वापस संप्रेषित किए जाते हैं (उदा. peload चलाने के बाद, Beacon pMemAddrs संरचना के मेमोरी स्थान के साथ वापस कॉल करता है) और इस प्रकार सभी जुड़े क्लाइंट को दिखाई देते हैं, जो "on Beacon_Output" हुक का उपयोग करके अपने संबंधित petables को अपडेट करते हैं।
ये अलग-अलग प्रयास मिलकर Inline-Execute-PE को कई क्लाइंट के बीच महत्वपूर्ण डेटा को कुशलतापूर्वक और विश्वसनीय रूप से सिंक्रनाइज़ करने में सक्षम बनाते हैं।
यह परियोजना निम्नलिखित परियोजनाओं और संसाधनों के बिना संभव नहीं होती, जिनका भारी संदर्भ लिया गया और जिनसे इस परियोजना के मुख्य भागों की उत्पत्ति हुई। उनके कोड और उनकी दृष्टि के लिए लेखकों को बहुत-बहुत धन्यवाद।