
Un generador de cargadores de shellcode con soporte para múltiples técnicas de inyección, diseñado para operaciones de red team.
hollow es un generador de cargadores de shellcode. Le proporcionas un binario de shellcode sin procesar y un perfil, y genera un cargador PE de Windows compilado con tu shellcode encriptado en su interior.
Los binarios están disponibles en la página de lanzamientos, o puedes compilar desde el código fuente:
go build -o hollow .
Requiere x86_64-w64-mingw32-gcc para compilación cruzada.
En Arch Linux: pacman -S mingw-w64-gcc
En Debian/Ubuntu: apt install gcc-mingw-w64-x86-64
./hollow -shellcode payload.bin -profile profiles/new_process_injection_sc.json
| Bandera | Descripción |
|---|---|
-shellcode | Ruta al shellcode sin procesar (.bin) |
-profile | Ruta a un archivo JSON de perfil |
-templates | Directorio de plantillas (por defecto: ./templates) |
hollow sigue un proceso de tres pasos: encriptar, sustituir, compilar.
Tu shellcode se encripta con AES-256-CBC usando una clave y un IV generados aleatoriamente en cada ejecución. Ambos están incrustados dentro del binario de salida. Luego, la plantilla C elegida reemplaza sus marcadores de posición con el shellcode encriptado, la clave y el IV, y el resultado se compila en un PE enlazado estáticamente y depurado por MinGW.
En tiempo de ejecución, el cargador descifra el shellcode usando BCrypt de Windows y lo ejecuta mediante la técnica de inyección que implementa la plantilla.
Las plantillas son los archivos fuente C que implementan la lógica real de inyección. Cada una reside en templates/ y contiene tokens de marcador de posición (${SHELLCODE}, ${KEY}, ${IV}, ${TARGET_PROCESS}) que hollow completa antes de la compilación. Seleccionas una plantilla a través de tu perfil.
hollow incluye seis plantillas:
| Plantilla | Técnica |
|---|---|
new_process_injection | Inyección de hilo remoto en un proceso recién creado |
new_process_injection_sc | Igual, mediante syscalls directas (Hell's Gate) |
remote_thread_injection | Inyección clásica de hilo remoto en un proceso existente |
remote_thread_injection_sc | Igual, mediante syscalls directas (Hell's Gate) |
earlybird_apc | Inyección Early Bird APC |
dll_sideload | Sideloading de DLL, produce un DLL en lugar de un EXE |
Puedes escribir tus propias plantillas y colocarlas en templates/ — hollow las detectará automáticamente siempre que tu perfil las referencie.
Los perfiles son archivos JSON que le indican a hollow qué plantilla usar, qué proceso atacar y cómo compilar la salida. Residen en profiles/ y están pensados para personalizarse por compromiso.
{
"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 es ya sea exe o dll. Establece automatic: false para volcar el código fuente C sustituido al disco en lugar de compilarlo, útil si deseas modificar el código antes de compilar.
El archivo de salida se escribe en output_dir, con el nombre {template}_loader.{exe|dll}.
Plantilla: new_process_injection
Técnica: Inyección de hilo remoto en un proceso recién creado.
Crea el proceso objetivo con CREATE_BREAKAWAY_FROM_JOB | CREATE_NO_WINDOW, espera dos segundos para que se inicialice, luego asigna memoria en su espacio de direcciones, escribe el shellcode descifrado, lo marca como ejecutable y crea un hilo remoto que apunta a él. La bandera BREAKAWAY es necesaria cuando el cargador se lanza desde WinRM, que envuelve todos los procesos en un objeto de trabajo. El objetivo es una ruta completa de ejecutable.
Llamadas Win32: CreateProcessA, VirtualAllocEx, WriteProcessMemory, VirtualProtectEx, CreateRemoteThread.
Plantilla: new_process_injection_sc
Técnica: Inyección de hilo remoto en un proceso recién creado, mediante syscalls directas (Hell's Gate).
Mismo comportamiento que new_process_injection, pero cada llamada de asignación y de hilo evita completamente la capa Win32. Los SSN se resuelven desde ntdll en tiempo de ejecución y se ejecutan mediante la instrucción syscall sin procesar. Consulta la sección de benchmarks.
Plantilla: remote_thread_injection
Técnica: Inyección clásica de hilo remoto en un proceso existente.
Encuentra un proceso en ejecución por nombre usando CreateToolhelp32Snapshot, abre un identificador hacia él, luego asigna memoria, escribe el shellcode y crea un hilo remoto. No se genera ningún proceso nuevo. Se recomienda su uso contra procesos de larga duración como explorer.exe. El objetivo es un nombre de imagen de proceso, no una ruta completa.
Llamadas Win32: OpenProcess, VirtualAllocEx, WriteProcessMemory, VirtualProtectEx, CreateRemoteThread.
Plantilla: remote_thread_injection_sc
Técnica: Inyección clásica de hilo remoto en un proceso existente, mediante syscalls directas (Hell's Gate).
Mismo comportamiento que remote_thread_injection, evitando la capa Win32. Consulta la sección de benchmarks.
Plantilla: earlybird_apc
Técnica: Inyección Early Bird APC (CyberArk, 2018).
Crea el proceso objetivo en estado suspendido (CREATE_SUSPENDED | CREATE_BREAKAWAY_FROM_JOB | CREATE_NO_WINDOW), escribe el shellcode descifrado en su espacio de direcciones, luego pone en cola una Llamada a Procedimiento Asincrónica (APC) al hilo principal que apunta al shellcode mediante QueueUserAPC, y reanuda con ResumeThread. Debido a que la APC se dispara antes de que se ejecute el punto de entrada del proceso, el shellcode se ejecuta antes de que cualquier herramienta defensiva dentro del proceso se haya inicializado. Evita la tríada VirtualAllocEx + WriteProcessMemory + CreateRemoteThread por completo.
Plantilla: dll_sideload
Técnica: Sideloading de DLL / Ejecución de shellcode en proceso.
Produce un DLL en lugar de un EXE. En DLL_PROCESS_ATTACH, se genera un hilo que descifra y ejecuta el shellcode en el mismo proceso: VirtualAlloc, memcpy, VirtualProtect, y luego una llamada directa a función hacia el shellcode. El proceso anfitrión debe permanecer vivo mientras el payload se inicializa (alrededor de 10 segundos para un beacon de Sliver). Despliega colocando el DLL en una ubicación donde un binario legítimo lo cargará a través de una entrada faltante en la ruta de búsqueda de DLL.
Probado en Windows 10 Build 19041, protección en tiempo real de Windows Defender activada, definiciones 1.453.354.0, con un beacon de Sliver envuelto en Donut de 17 MB como payload:
| Plantilla | Alerta de comportamiento de Defender | Sesión establecida |
|---|---|---|
| new_process_injection | Trojan:Win64/AsyncRat.RPY!MTB | sí |
| remote_thread_injection | Trojan:Win64/AsyncRat.RPY!MTB | sí |
| earlybird_apc | ninguna | sí |
| dll_sideload | ninguna | sí |
| new_process_injection_sc | ninguna | sí |
| remote_thread_injection_sc | ninguna | sí |