
Un générateur de chargeur de shellcode prenant en charge plusieurs techniques d'injection, conçu pour les engagements d'équipe rouge.
hollow est un générateur de chargeurs de shellcode. Vous lui fournissez un binaire de shellcode brut et un profil, et il produit un chargeur PE Windows compilé avec votre shellcode chiffré à l'intérieur.
Les binaires sont disponibles sur la page des versions, ou vous pouvez compiler depuis les sources :
go build -o hollow .
Nécessite x86_64-w64-mingw32-gcc pour la compilation croisée.
Sur Arch Linux : pacman -S mingw-w64-gcc
Sur Debian/Ubuntu : apt install gcc-mingw-w64-x86-64
./hollow -shellcode payload.bin -profile profiles/new_process_injection_sc.json
| Drapeau | Description |
|---|---|
-shellcode | Chemin vers le shellcode brut (.bin) |
-profile | Chemin vers un fichier de profil JSON |
-templates | Répertoire des modèles (par défaut : ./templates) |
hollow suit un pipeline en trois étapes : chiffrer, substituer, compiler.
Votre shellcode est chiffré avec AES-256-CBC en utilisant une clé et un IV générés aléatoirement à chaque exécution. Les deux sont intégrés dans le binaire de sortie. Le modèle C choisi voit ensuite ses espaces réservés remplacés par le shellcode chiffré, la clé et l'IV, et le résultat est compilé en un PE lié statiquement et épuré par MinGW.
À l'exécution, le chargeur déchiffre le shellcode en utilisant BCrypt de Windows et l'exécute selon la technique d'injection implémentée par le modèle.
Les modèles sont les fichiers source C qui implémentent la logique d'injection réelle. Chacun se trouve dans templates/ et contient des jetons d'espace réservé (${SHELLCODE}, ${KEY}, ${IV}, ${TARGET_PROCESS}) que hollow remplit avant compilation. Vous sélectionnez un modèle via votre profil.
hollow est livré avec six modèles :
| Modèle | Technique |
|---|---|
new_process_injection | Injection de thread distant dans un processus fraîchement lancé |
new_process_injection_sc | Identique, via des appels système directs (Hell's Gate) |
remote_thread_injection | Injection classique de thread distant dans un processus existant |
remote_thread_injection_sc | Identique, via des appels système directs (Hell's Gate) |
earlybird_apc | Injection APC Early Bird |
dll_sideload | Détournement de DLL, produit une DLL au lieu d'un EXE |
Vous pouvez écrire vos propres modèles et les placer dans templates/ — hollow les détectera automatiquement tant que votre profil y fait référence.
Les profils sont des fichiers JSON qui indiquent à hollow quel modèle utiliser, quel processus cibler et comment compiler la sortie. Ils se trouvent dans profiles/ et sont destinés à être personnalisés par engagement.
{
"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 est soit exe soit dll. Mettez automatic: false pour écrire le code C substitué sur le disque au lieu de le compiler, utile si vous voulez modifier le code avant la construction.
Le fichier de sortie est écrit dans output_dir, nommé {template}_loader.{exe|dll}.
Modèle : new_process_injection
Technique : Injection de thread distant dans un processus fraîchement lancé.
Lance le processus cible avec CREATE_BREAKAWAY_FROM_JOB | CREATE_NO_WINDOW, attend deux secondes qu'il s'initialise, puis alloue de la mémoire dans son espace d'adressage, écrit le shellcode déchiffré, le marque comme exécutable et crée un thread distant pointant dessus. Le drapeau BREAKAWAY est nécessaire lorsque le chargeur est lancé depuis WinRM, qui encapsule tous les processus dans un objet travail (job). La cible est un chemin d'exécutable complet.
Appels Win32 : CreateProcessA, VirtualAllocEx, WriteProcessMemory, VirtualProtectEx, CreateRemoteThread.
Modèle : new_process_injection_sc
Technique : Injection de thread distant dans un processus fraîchement lancé, via des appels système directs (Hell's Gate).
Même comportement que new_process_injection, mais chaque appel d'allocation et de thread contourne complètement la couche Win32. Les SSN sont résolus depuis ntdll à l'exécution et exécutés via l'instruction syscall brute. Voir la section benchmark.
Modèle : remote_thread_injection
Technique : Injection classique de thread distant dans un processus existant.
Trouve un processus en cours d'exécution par son nom en utilisant CreateToolhelp32Snapshot, ouvre un handle sur celui-ci, puis alloue de la mémoire, écrit le shellcode et crée un thread distant. Aucun nouveau processus n'est lancé. Idéal contre des processus de longue durée comme explorer.exe. La cible est un nom d'image de processus, pas un chemin complet.
Appels Win32 : OpenProcess, VirtualAllocEx, WriteProcessMemory, VirtualProtectEx, CreateRemoteThread.
Modèle : remote_thread_injection_sc
Technique : Injection classique de thread distant dans un processus existant, via des appels système directs (Hell's Gate).
Même comportement que remote_thread_injection, contournant la couche Win32. Voir la section benchmark.
Modèle : earlybird_apc
Technique : Injection APC Early Bird (CyberArk, 2018).
Lance le processus cible en état suspendu (CREATE_SUSPENDED | CREATE_BREAKAWAY_FROM_JOB | CREATE_NO_WINDOW), écrit le shellcode déchiffré dans son espace d'adressage, puis place un appel de procédure asynchrone (APC) dans la file d'attente du thread principal pointant vers le shellcode via QueueUserAPC, et reprend avec ResumeThread. Comme l'APC se déclenche avant que le point d'entrée du processus ne s'exécute, le shellcode s'exécute avant que tout outil défensif du processus ne soit initialisé. Évite complètement la triade VirtualAllocEx + WriteProcessMemory + CreateRemoteThread.
Modèle : dll_sideload
Technique : Détournement de DLL / Exécution de shellcode in-process.
Produit une DLL au lieu d'un EXE. Lors de DLL_PROCESS_ATTACH, un thread est lancé qui déchiffre et exécute le shellcode in-process : VirtualAlloc, memcpy, VirtualProtect, puis un appel direct de fonction dans le shellcode. Le processus hôte doit rester vivant pendant que la charge utile s'initialise (environ 10 secondes pour un beacon Sliver). Déployez en plaçant la DLL dans un emplacement où un binaire légitime la chargera via un chemin de recherche de DLL manquant.
Testé sur Windows 10 Build 19041, protection en temps réel de Windows Defender activée, définitions 1.453.354.0, avec un beacon Sliver enveloppé dans Donut de 17 Mo comme charge utile :
| Modèle | Alerte comportementale Defender | Session établie |
|---|---|---|
| new_process_injection | Trojan:Win64/AsyncRat.RPY!MTB | oui |
| remote_thread_injection | Trojan:Win64/AsyncRat.RPY!MTB | oui |
| earlybird_apc | aucune | oui |
| dll_sideload | aucune | oui |
| new_process_injection_sc | aucune | oui |
| remote_thread_injection_sc | aucune | oui |