Voltar às atualizações
New releaseSep 16, 2026

SindriKit v2.0.0

Uma biblioteca C fundamental para construir capacidades ofensivas operacionalmente críveis.

Compartilhar

SindriKit

O Desenvolvimento Ofensivo Merece uma Arquitetura Melhor.
Uma biblioteca C para construir capacidades ofensivas.


Conceito Central

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:

  1. A Lógica da Técnica: (ex.: loaders, injeções, patchers) lida com rastreamento de estado e orquestração de dados. Ela não tem conhecimento de como a memória é alocada ou como as threads são criadas.
  2. Os Mecanismos de Execução: (ex.: Win32 API, NTAPI Nativa, Syscalls Diretas) ficam dentro de tabelas de API independentes e são injetados na técnica em tempo de execução.

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.


Arquitetura de Design

  • Perfis de Execução Desacoplados: Troque mecânicas de memória, módulo, mapeamento, processo, thread e arquivo por meio de tabelas independentes de ponteiros de função (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.
  • Cobertura de Técnicas: Carregamento reflexivo de PE (EXE/DLL) e COFF/BOF, injeção clássica e early-bird APC sobre shellcode/PE/COFF, além de FFI ciente de arquitetura e Heaven's Gate — tudo sobre os mesmos perfis componíveis.
  • Pipeline de Syscalls em Cascata: Resolvedores de SSN plugáveis (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).
  • Status Codificado por Facility: Toda chamada sujeita a falha retorna 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.
  • Ofuscação em Tempo de Compilação: Algoritmos de hash de strings e APIs (DJB2, FNV1A) podem ser trocados globalmente via CMake. A compilação randomiza automaticamente a seed global para alterar assinaturas estáticas.
  • Motor de Mutação: Habilita polimorfismo profundo via 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.
  • Builds de Release: Um tier silencioso remove todas as strings de diagnóstico, descritores de arquivo e frames de rastreamento; builds SND_CRTLESS vão além com /NODEFAULTLIB, sem header do SDK, um frontend PEB e apenas backends nativos.

Início Rápido

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.


Integrando o SindriKit

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.


O Motor

Camada de Abstração de API

        ┌────────────────────────────────────────────────────────────────────────────┐
        │                          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);

Pipeline de Syscalls em Cascata

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.

Agilidade de Algoritmos em Tempo de Compilação

Categorias