
SindriKit v2.0.0
Une bibliothèque C fondamentale pour la construction de capacités offensives opérationnellement crédibles
SindriKit
Le développement offensif mérite une meilleure architecture.
Une bibliothèque C pour construire des capacités offensives.
Concept central
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 :
- La logique de la technique : (par ex., loaders, injections, patchers) gère le suivi d'état et l'orchestration des données. Elle n'a aucune connaissance de la manière dont la mémoire est allouée ou dont les threads sont créés.
- Les mécanismes d'exécution : (par ex., API Win32, NTAPI natif, syscalls directs) résident dans des tables d'API indépendantes et sont injectés dans la technique à l'exécution.
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.
Architecture de conception
- Profils d'exécution découplés : Remplacez les mécanismes de mémoire, module, mapping, processus, thread et fichier via des tables de pointeurs de fonction indépendantes (
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. - Couverture des techniques : Chargement réflexif PE (EXE/DLL) et COFF/BOF, injection classique et early-bird APC sur shellcode/PE/COFF, plus FFI sensible à l'architecture et Heaven's Gate — le tout sur les mêmes profils composables.
- Pipeline de syscalls en cascade : Résolveurs de SSN enfichables (
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). - Statut encodé par facility : Chaque appel susceptible d'échouer retourne
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. - Obfuscation à la compilation : Les algorithmes de hachage de chaînes et d'API (DJB2, FNV1A) peuvent être échangés globalement via CMake. La compilation randomise automatiquement la graine globale pour altérer les signatures statiques.
- Moteur de mutation : Permet un polymorphisme profond via
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. - Builds de release : Un tier silencieux supprime toutes les chaînes de diagnostic, descripteurs de fichiers et trames de suivi ; les builds
SND_CRTLESSvont plus loin avec/NODEFAULTLIB, aucun en-tête SDK, un frontend PEB, et uniquement des backends natifs.
Démarrage rapide
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.
Intégrer 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
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.
Le moteur
Couche d'abstraction d'API
┌────────────────────────────────────────────────────────────────────────────┐
│ 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);
Pipeline de syscalls en cascade
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);