
Um gerador de carregadores de shellcode com suporte para múltiplas técnicas de injeção, construído para engajamentos de red team.
hollow é um gerador de carregadores de shellcode. Você fornece um binário de shellcode bruto e um perfil, e ele gera um carregador PE do Windows compilado com seu shellcode criptografado internamente.
Binários estão disponíveis na página de releases, ou compile a partir do código-fonte:
go build -o hollow .
Requer x86_64-w64-mingw32-gcc para compilação cruzada.
No Arch Linux: pacman -S mingw-w64-gcc
No Debian/Ubuntu: apt install gcc-mingw-w64-x86-64
./hollow -shellcode payload.bin -profile profiles/new_process_injection_sc.json
| Flag | Descrição |
|---|---|
-shellcode | Caminho para o shellcode bruto (.bin) |
-profile | Caminho para um arquivo JSON de perfil |
-templates | Diretório de templates (padrão: ./templates) |
hollow segue um pipeline de três etapas: criptografar, substituir, compilar.
Seu shellcode é criptografado com AES-256-CBC usando uma chave e IV gerados aleatoriamente a cada execução. Ambos são incorporados no binário de saída. O template C escolhido então tem seus placeholders substituídos pelo shellcode criptografado, a chave e o IV, e o resultado é compilado em um PE estaticamente ligado e sem símbolos pelo MinGW.
Em tempo de execução, o carregador descriptografa o shellcode usando o BCrypt do Windows e o executa utilizando a técnica de injeção que o template implementa.
Templates são os arquivos fonte C que implementam a lógica real de injeção. Cada um reside em templates/ e contém tokens de substituição (${SHELLCODE}, ${KEY}, ${IV}, ${TARGET_PROCESS}) que o hollow preenche antes da compilação. Você seleciona um template através do seu perfil.
hollow vem com seis templates:
| Template | Técnica |
|---|---|
new_process_injection | Injeção de thread remota em um processo recém-criado |
new_process_injection_sc | Mesmo, via chamadas de sistema diretas (Hell's Gate) |
remote_thread_injection | Injeção clássica de thread remota em um processo existente |
remote_thread_injection_sc | Mesmo, via chamadas de sistema diretas (Hell's Gate) |
earlybird_apc | Injeção APC Early Bird |
dll_sideload | DLL sideloading, produz uma DLL em vez de um EXE |
Você pode escrever seus próprios templates e colocá-los em templates/ — o hollow os detectará automaticamente desde que seu perfil aponte para eles.
Perfis são arquivos JSON que informam ao hollow qual template usar, qual processo alvo e como compilar a saída. Eles ficam em profiles/ e devem ser personalizados por engajamento.
{
"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 é exe ou dll. Defina automatic: false para despejar o código C substituído no disco em vez de compilá-lo, útil se você quiser modificar o código antes de compilar.
O arquivo de saída é gravado em output_dir, nomeado como {template}_loader.{exe|dll}.
Template: new_process_injection
Técnica: Injeção de Thread Remota em um processo recém-criado.
Cria o processo alvo com CREATE_BREAKAWAY_FROM_JOB | CREATE_NO_WINDOW, aguarda dois segundos para sua inicialização, então aloca memória em seu espaço de endereçamento, escreve o shellcode descriptografado, marca-o como executável e cria uma thread remota apontando para ele. A flag BREAKAWAY é necessária quando o carregador é lançado a partir do WinRM, que envolve todos os processos em um objeto de job. O alvo é um caminho completo do executável.
Chamadas Win32: CreateProcessA, VirtualAllocEx, WriteProcessMemory, VirtualProtectEx, CreateRemoteThread.
Template: new_process_injection_sc
Técnica: Injeção de Thread Remota em um processo recém-criado, via chamadas de sistema diretas (Hell's Gate).
Mesmo comportamento que new_process_injection, mas toda alocação e chamada de thread contorna a camada Win32 completamente. Os SSNs são resolvidos da ntdll em tempo de execução e executados via instrução syscall bruta. Veja a seção de benchmark.
Template: remote_thread_injection
Técnica: Injeção Clássica de Thread Remota em um processo existente.
Encontra um processo em execução pelo nome usando CreateToolhelp32Snapshot, abre um handle para ele, então aloca memória, escreve o shellcode e cria uma thread remota. Nenhum novo processo é criado. Melhor usado contra processos de longa duração como explorer.exe. O alvo é um nome de imagem do processo, não um caminho completo.
Chamadas Win32: OpenProcess, VirtualAllocEx, WriteProcessMemory, VirtualProtectEx, CreateRemoteThread.
Template: remote_thread_injection_sc
Técnica: Injeção Clássica de Thread Remota em um processo existente, via chamadas de sistema diretas (Hell's Gate).
Mesmo comportamento que remote_thread_injection, contornando a camada Win32. Veja a seção de benchmark.
Template: earlybird_apc
Técnica: Injeção APC Early Bird (CyberArk, 2018).
Cria o processo alvo em estado suspenso (CREATE_SUSPENDED | CREATE_BREAKAWAY_FROM_JOB | CREATE_NO_WINDOW), escreve o shellcode descriptografado em seu espaço de endereçamento, então enfileira uma Chamada de Procedimento Assíncrona (APC) para a thread principal apontando para o shellcode via QueueUserAPC, e retoma com ResumeThread. Como a APC é disparada antes que o ponto de entrada do processo seja executado, o shellcode executa antes que qualquer ferramenta defensiva no processo tenha sido inicializada. Evita completamente a tríade VirtualAllocEx + WriteProcessMemory + CreateRemoteThread.
Template: dll_sideload
Técnica: DLL Sideloading / Execução de Shellcode In-Process.
Produz uma DLL em vez de um EXE. Em DLL_PROCESS_ATTACH, uma thread é criada que descriptografa e executa o shellcode no próprio processo: VirtualAlloc, memcpy, VirtualProtect, em seguida uma chamada de função direta para o shellcode. O processo hospedeiro deve permanecer ativo enquanto o payload inicializa (cerca de 10 segundos para um beacon Sliver). Implante colocando a DLL em um local onde um binário legítimo a carregará através de uma entrada de caminho de busca ausente.
Testado no Windows 10 Build 19041, proteção em tempo real do Windows Defender ativada, definições 1.453.354.0, com um beacon Sliver embrulhado com Donut de 17 MB como payload:
| Template | Alerta comportamental do Defender | Sessão estabelecida |
|---|---|---|
| new_process_injection | Trojan:Win64/AsyncRat.RPY!MTB | sim |
| remote_thread_injection | Trojan:Win64/AsyncRat.RPY!MTB | sim |
| earlybird_apc | nenhum | sim |
| dll_sideload | nenhum | sim |
| new_process_injection_sc | nenhum | sim |
| remote_thread_injection_sc | nenhum | sim |