
Ein Shellcode-Loader-Generator mit Unterstützung für mehrere Injektionstechniken, entwickelt für Red-Team-Einsätze.
hollow ist ein Shellcode-Loader-Generator. Sie geben ihm eine rohe Shellcode-Binärdatei und ein Profil, und es gibt einen kompilierten Windows-PE-Loader aus, der Ihren verschlüsselten Shellcode enthält.
Binärdateien sind auf der Releases Seite verfügbar, oder bauen Sie aus dem Quellcode:
go build -o hollow .
Erfordert x86_64-w64-mingw32-gcc für die Kreuzkompilierung.
Auf Arch Linux: pacman -S mingw-w64-gcc
Auf Debian/Ubuntu: apt install gcc-mingw-w64-x86-64
./hollow -shellcode payload.bin -profile profiles/new_process_injection_sc.json
| Flagge | Beschreibung |
|---|---|
-shellcode | Pfad zur rohen Shellcode-Datei (.bin) |
-profile | Pfad zu einer Profil-JSON-Datei |
-templates | Vorlagenverzeichnis (Standard: ./templates) |
hollow folgt einer dreistufigen Pipeline: verschlüsseln, ersetzen, kompilieren.
Ihr Shellcode wird bei jedem Durchlauf mit AES-256-CBC unter Verwendung eines zufällig generierten Schlüssels und IV verschlüsselt. Beide werden in der Ausgabebinärdatei eingebettet. Die gewählte C-Vorlage hat dann ihre Platzhalter durch den verschlüsselten Shellcode, den Schlüssel und das IV ersetzt, und das Ergebnis wird von MinGW zu einem gestrippten, statisch gelinkten PE kompiliert.
Zur Laufzeit entschlüsselt der Loader den Shellcode mit Windows BCrypt und führt ihn mit der Injektionstechnik aus, die die Vorlage implementiert.
Vorlagen sind die C-Quelldateien, die die eigentliche Injektionslogik implementieren. Jede befindet sich in templates/ und enthält Platzhalter-Token (${SHELLCODE}, ${KEY}, ${IV}, ${TARGET_PROCESS}), die hollow vor der Kompilierung ausfüllt. Sie wählen eine Vorlage über Ihr Profil aus.
hollow wird mit sechs Vorlagen geliefert:
Sie können eigene Vorlagen schreiben und in templates/ ablegen – hollow erkennt sie automatisch, solange Ihr Profil auf sie verweist.
Profile sind JSON-Dateien, die hollow mitteilen, welche Vorlage verwendet werden soll, welcher Prozess anvisiert wird und wie die Ausgabe kompiliert werden soll. Sie befinden sich in profiles/ und sollen für jeden Einsatz angepasst werden.
{
"name": "New Process Injection via Direct Syscalls",
"author": "",
"template": "new_process_injection_sc",
"target_process": "C:\\Windows\\System32\\cmd.exe",
"arch": "x64",
"compile": {
"automatic": true,
"gcc": "x86_64-w64-mingw32-gcc",
"strip": true,
"output_type": "exe"
},
"output_dir": "./output"
}
output_type ist entweder exe oder dll. Setzen Sie automatic: false, um die ersetzte C-Quelle auf die Festplatte zu speichern, anstatt sie zu kompilieren. Nützlich, wenn Sie den Code vor dem Bauen ändern möchten.
Die Ausgabedatei wird in output_dir geschrieben, benannt als {template}_loader.{exe|dll}.
Vorlage: new_process_injection
Technik: Remote-Thread-Injektion in einen neu gestarteten Prozess.
Startet den Zielprozess mit CREATE_BREAKAWAY_FROM_JOB | CREATE_NO_WINDOW, wartet zwei Sekunden auf seine Initialisierung, allokiert dann Speicher in seinem Adressraum, schreibt den entschlüsselten Shellcode, markiert ihn als ausführbar und erstellt einen Remote-Thread, der darauf zeigt. Das BREAKAWAY-Flag ist erforderlich, wenn der Loader von WinRM gestartet wird, das alle Prozesse in ein Job-Objekt einschließt. Das Ziel ist ein vollständiger ausführbarer Pfad.
Win32-Aufrufe: CreateProcessA, VirtualAllocEx, WriteProcessMemory, VirtualProtectEx, CreateRemoteThread.
Vorlage: new_process_injection_sc
Technik: Remote-Thread-Injektion in einen neu gestarteten Prozess, über direkte Syscalls (Hell's Gate).
Gleiches Verhalten wie new_process_injection, aber jeder Allokations- und Threading-Aufruf umgeht die Win32-Ebene vollständig. SSNs werden zur Laufzeit aus ntdll aufgelöst und über die rohe syscall-Anweisung ausgeführt. Siehe den Abschnitt Benchmark.
Vorlage: remote_thread_injection
Technik: Klassische Remote-Thread-Injektion in einen vorhandenen Prozess.
Findet einen laufenden Prozess anhand des Namens mit CreateToolhelp32Snapshot, öffnet ein Handle darauf, allokiert dann Speicher, schreibt den Shellcode und erstellt einen Remote-Thread. Es wird kein neuer Prozess gestartet. Am besten für langlebige Prozesse wie explorer.exe geeignet. Das Ziel ist ein Prozess-Image-Name, kein vollständiger Pfad.
Win32-Aufrufe: OpenProcess, VirtualAllocEx, WriteProcessMemory, VirtualProtectEx, CreateRemoteThread.
Vorlage: remote_thread_injection_sc
Technik: Klassische Remote-Thread-Injektion in einen vorhandenen Prozess, über direkte Syscalls (Hell's Gate).
Gleiches Verhalten wie remote_thread_injection, umgeht die Win32-Ebene. Siehe den Abschnitt Benchmark.
Vorlage: earlybird_apc
Technik: Early-Bird-APC-Injektion (CyberArk, 2018).
Startet den Zielprozess im angehaltenen Zustand (CREATE_SUSPENDED | CREATE_BREAKAWAY_FROM_JOB | CREATE_NO_WINDOW), schreibt den entschlüsselten Shellcode in seinen Adressraum, reiht dann einen Asynchronous Procedure Call (APC) an den Hauptthread ein, der auf den Shellcode zeigt, mittels QueueUserAPC, und setzt mit ResumeThread fort. Da der APC ausgelöst wird, bevor der Prozesseinstiegspunkt läuft, wird der Shellcode ausgeführt, bevor defensive Tools im Prozess initialisiert sind. Vermeidet die Triade VirtualAllocEx + WriteProcessMemory + CreateRemoteThread vollständig.
Vorlage: dll_sideload
Technik: DLL-Sideloading / In-Process-Shellcode-Ausführung.
Erzeugt eine DLL anstelle einer EXE. Bei DLL_PROCESS_ATTACH wird ein Thread gestartet, der den Shellcode prozessintern entschlüsselt und ausführt: VirtualAlloc, memcpy, VirtualProtect, dann ein direkter Funktionsaufruf in den Shellcode. Der Host-Prozess muss am Leben bleiben, während das Payload initialisiert (etwa 10 Sekunden für einen Sliver-Beacon). Bereitstellen, indem Sie die DLL an einem Ort ablegen, an dem eine legitime Binärdatei sie über einen fehlenden DLL-Suchpfadeintrag lädt.
Getestet auf Windows 10 Build 19041, Windows Defender-Echtzeitschutz aktiviert, Definitionen 1.453.354.0, mit einem 17 MB Donut-umhüllten Sliver-Beacon als Payload:
Trojan:Win64/AsyncRat.RPY!MTB ist eine maschinelle Bedrohungs-Verhaltensregel, die durch die klassische Remote-Injektionssequenz ausgelöst wird: VirtualAllocEx + WriteProcessMemory + CreateRemoteThread, aufgerufen auf ein entferntes Prozess-Handle über die Win32-API-Ebene. Defender registriert einen Kernel-Callback, der ausgelöst wird, wenn diese drei Aufrufe in Sequenz erscheinen.
Die _sc-Vorlagen umgehen dies, indem sie diese Win32-Funktionen nie aufrufen. Stattdessen lösen sie die entsprechenden Kernel-Syscall-Servicenummern (SSNs) direkt aus ntdll zur Laufzeit unter Verwendung von Hell's Gate auf: jeder nicht gehockte ntdll-Stub beginnt mit dem Vier-Byte-Prolog 4C 8B D1 B8, und die SSN befindet sich bei Offset 4. Der eigentliche Syscall ist eine GCC-Naked-Funktion, die nichts als movq %rcx, %r10 / movl ssn(%rip), %eax / syscall / ret enthält, die exakte Sequenz, die der ntdll-Stub selbst ausführen würde. Defenders Callback wird nie ausgelöst, da die überwachten Win32-Wrapper nie aufgerufen werden.
Auf Systemen, bei denen ntdll-Stubs von einem vollständigen EDR gepatcht werden (Prolog durch einen Sprung ersetzt), schlägt die Clean-Stub-Prüfung fehl und der Loader beendet sich vorzeitig. Halo's Gate (Scannen benachbarter Stubs, um die SSN abzuleiten) ist nicht implementiert.
Der Loader-Code fügt etwa 19 KB Overhead hinzu. Die Ausgabegröße entspricht im Wesentlichen der Größe des eingegebenen Shellcodes. Ein 17 MB Sliver-Beacon erzeugt einen 18 MB Loader. Ein typischer Metasploit-Shellcode (~200 KB) würde einen ~220 KB Loader erzeugen.
Beiträge sind willkommen. Wenn Sie eine Vorlage geschrieben haben und hinzufügen möchten, oder Verbesserungen an bestehenden, können Sie gerne einen PR öffnen. Wenn Sie einen Fehler finden oder einen Vorschlag haben, öffnen Sie ein Issue.
Das Ziel dieses Tools ist es, den Loader-Entwicklungsprozess zu erleichtern, nicht ein fertiges Produkt zu sein. Neue Vorlagen, bessere Profile und Verbesserungen am Kern sind alle willkommen. hollow wurde auch mit der Absicht entwickelt, Menschen zu helfen, die Konzepte hinter Shellcode-Loadern und Injektionstechniken zu verstehen, daher ist klarer und lesbarer Vorlagencode genauso wertvoll wie Funktionalität.
Ich werde die Konzepte hinter jeder Technik und die vollständige Verwendung von hollow sehr bald auf meinem Blog detailliert beschreiben. Bleiben Sie dran.
| Vorlage | Technik |
|---|
new_process_injection | Remote-Thread-Injektion in einen neu gestarteten Prozess |
new_process_injection_sc | Gleiches, über direkte Syscalls (Hell's Gate) |
remote_thread_injection | Klassische Remote-Thread-Injektion in einen vorhandenen Prozess |
remote_thread_injection_sc | Gleiches, über direkte Syscalls (Hell's Gate) |
earlybird_apc | Early-Bird-APC-Injektion |
dll_sideload | DLL-Sideloading, erzeugt eine DLL anstelle einer EXE |
| Vorlage | Defender-Verhaltenswarnung | Sitzung hergestellt |
|---|
| new_process_injection | Trojan:Win64/AsyncRat.RPY!MTB | ja |
| remote_thread_injection | Trojan:Win64/AsyncRat.RPY!MTB | ja |
| earlybird_apc | keine | ja |
| dll_sideload | keine | ja |
| new_process_injection_sc | keine | ja |
| remote_thread_injection_sc | keine | ja |