Zurück zu den Updates
New releaseSep 16, 2026

SindriKit v2.0.0

Eine grundlegende C-Bibliothek zur Erstellung operativ glaubwürdiger offensiver Fähigkeiten

Teilen

SindriKit

Offensive Development verdient eine bessere Architektur.
Eine C-Bibliothek zum Aufbau offensiver Fähigkeiten.


Kernkonzept

Die meisten offensiven Werkzeuge kodieren ihre Ausführungsmechanik fest in die Logik der Technik. Ein reflektiver Loader mappt nicht einfach ein Image; er mappt es unter Verwendung einer bestimmten, fest kodierten Kette von VirtualAlloc- oder nativen NTAPI-Aufrufen. Wenn eine EDR beginnt, diese spezifische Kette zu überwachen, sind Sie gezwungen, das gesamte Werkzeug neu zu schreiben.

SindriKit löst dies, indem es eine Trennung der Belange durch Interface-Abstraktionstabellen erzwingt:

  1. Die Technik-Logik: (z. B. Loader, Injektionen, Patcher) befasst sich mit Zustandsverfolgung und Datenorchestrierung. Sie hat keine Kenntnis davon, wie Speicher zugewiesen oder Threads erstellt werden.
  2. Die Ausführungsmechanik: (z. B. Win32-API, Native NTAPI, Direct Syscalls) befindet sich in unabhängigen API-Tabellen und wird zur Laufzeit in die Technik injiziert.

Indem die Ausführungsmechanik auf Laufzeit-Funktionszeiger verlagert wird, können Sie Ihre gesamte Strategie von Win32-Aufrufen auf rohe Direct Syscalls mit einer einzigen Codezeile umstellen – ohne Ihre Payload-Ausführungslogik zu ändern.


Design-Architektur

  • Entkoppelte Ausführungsprofile: Tauschen Sie zugrunde liegende Speicher-, Modul- und Thread-Manipulationsverhalten über Funktionszeigertabellen aus, ohne die aufrufende Technik zu brechen.
  • Kaskadierende Syscall-Fallbacks: Austauschbare SSN-Resolver (snd_syscall_resolve_ssn_scan, snd_syscall_resolve_ssn_sort) mit einer Prioritätskette – tauschen Sie Strategien aus oder erweitern Sie sie, ohne den Domänencode zu berühren.
  • Compile-Time-Obfuskation: String- und API-Hashing-Algorithmen (DJB2, FNV1A) können global über CMake ausgetauscht werden. Das Kompilieren randomisiert automatisch den globalen Seed, um statische Signaturen zu verändern.
  • Mutations-Engine: Ermöglicht tiefe Polymorphie über SND_MORPH. Generiert bei jedem Build einzigartige binäre Signaturen, indem volatile opake Prädikate in C-Code, funktional äquivalente Math/NOPs in Assembly-Stubs injiziert und das Speicherlayout der Kernstrukturen verwürfelt wird.
  • Release-Builds: Eine stille Stufe entfernt alle diagnostischen Strings, Dateideskriptoren und Tracking-Frames aus der finalen Binärdatei und reduziert Ihren statischen Footprint auf bloße Primitive.

SindriKit integrieren

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...


Die Engine

API-Abstraktionsschicht

        ┌────────────────────────────────────────────────────────────────────────────┐
        │                          JEDE OFFENSIVE ABSICHT                            │
        │    Loader · Injector · Spoofer · Patcher · Bypasser · Harvester · ...      │
        ├────────────────────────────────────────────────────────────────────────────┤
        │                     SINDRIKIT API-ABSTRAKTIONSSCHICHT                       │
        │      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  │
        │      [ zukünftige Tabellen ] ->  thread · object · ...                     │
        ├──────────────────┬──────────────────────┬──────────────────────────────────┤
        │   Win32-Profil   │    Natives Profil    │    Eigene Mechanik mitbringen    │
        │  VirtualAlloc    │  NtAllocateVirtual   │  Driver · ROP · Exotisch         │
        │  LoadLibraryA    │  PEB Walk + EAT      │  Operator-definierte Funktionen  │
        └──────────────────┴──────────────────────┴──────────────────────────────────┘

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);

Kaskadierende Syscall-Pipeline

SindriKit behandelt die Syscall-Auflösung als eine injizierbare Mechanik, die Strategien in Prioritätsreihenfolge stapelt. Die Engine fällt durch, bis eine erfolgreich ist:

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);

Der Invoker ist von der SSN-Auflösung entkoppelt – wechseln Sie zwischen direkten und indirekten Syscalls, ohne den Domänencode zu ändern. Der indirekte Aufruf springt zu einem legitimen NTDLL-Gadget und hält die Syscall-Rücksprungadresse innerhalb von ntdll.dll.

Compile-Time-Algorithmus-Agilität

Jeder API-Name und Modul-String 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 Footprint verschiebt sich vollständig zwischen Kompilierungen, ohne eine Zeile C zu berühren.

Architektur-bewusste dynamische FFI

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 für sowohl cdecl- als auch stdcall-Ziele.

Bounds-geprüfter PE-Parser

Ein einheitlicher PE32/PE32+-Parser mit einem is_mapped-Flag, das sowohl rohe On-Disk-Images als auch speichergemappte Views korrekt handhabt. Jeder Datenverzeichniszugriff wird gegen verfolgte Puffergrenzen validiert, bevor dereferenziert wird. Die Export-Auflösung unterstützt Forwarder-Ketten bis zu einer Tiefe von 4 mit hash-basiertem Lookup.

Getestet gegen:

  • Über 40 Kern-Testkombinationen, die auf Edge-Case-EXEs, DLLs, fehlerhafte Argumente, fehlende Exporte und TLS-Callbacks über x86 und x64 abzielen.
  • Über 100 dynamische PE-Mutationen, die vom pe_mutator-Modul generiert wurden: genullte Section-Namen, Integer-Overflows, ungültige e_lfanew-Grenzen, verstümmelte Importe.
  • Vollständiger Corkami-Korpus: lädt gültige Samples sauber, lehnt fehlerhafte ohne Absturz über 99 % der Samples sauber ab.

Zustandsverfolgte Domänen-Kontexte

Jede offensive Operation wird über eine diskrete Kontextstruktur mit Stufen-Enumeration verwaltet. Operationen können zwischen Stufen für Sleep-Obfuskation oder gestaffelten Einsatz pausiert, sauber fortgesetzt und auf den exakten Fehlerpunkt bis hinunter zum Subsystem und Grund inspiziert werden.


Die API-Design-Philosophie

Bootstrapen Sie die Syscall-Pipeline einmal (typisches Muster):

PVOID clean_ntdll = NULL;
snd_om_knowndll_map(&snd_map_nt, L"ntdll.dll", &clean_ntdll);
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);

Der Invoker ist von der SSN-Auflösung entkoppelt – wechseln Sie zwischen direkten und indirekten Syscalls, ohne den Domänencode zu ändern. Der indirekte Aufruf springt zu einem legitimen NTDLL-Gadget und hält die Syscall-Rücksprungadresse innerhalb von ntdll.dll.

Tauschen Sie das Ausführungsprofil mit einer Zuweisung aus:

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 – Importe verwenden PEB Walk + EAT auch in vollständigen _sys-Profilen.


Build-Stufen

Debug-Stufe — SND_ENABLE_DEBUG=ON

Für die lokale Entwicklung. snd_status_t erweitert sich um file, line und einen 128-Byte-context-String-Puffer. 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 auf stdout statt auf die Debug-Konsole umzuleiten.

Stille Stufe — SND_ENABLE_DEBUG=OFF

Die Standard-Deployment-Konfiguration für operative Binärdateien. Jeder diagnostische String, jede Dateireferenz und jede Zeilennummer wird vollständig wegkompiliert. snd_status_t kollabiert auf zwei Integer. Nichts weiter.

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)

Dokumentation

Vollständige Referenz unter docs/:

  • Erste Schritte — CMake, Build-Stufen, DI-Bootstrap, erster Loader-/Injektions-Workflow
  • Architektur — Dependency Injection, Zustandsmaschinen, Status-System
  • Primitive — Speicher, Module, Prozess, Mapping, Syscalls, Ausführung (FFI)
  • Loader — Reflektive PE-Pipeline
  • Injektion — Klassische Shellcode- und PE-Injektion
  • Parser — PE- und Env-(PEB-)Subdomänen
  • Common — CRT-freie Helfer, Puffer, Hashing, Status
  • Beispiele & PoCsunified-Executable-Profile (load, inject, hg)
  • Tests — Integrations-Runner, PE-Mutator

Geplant: Evasion-Domäne.


Haftungsausschluss

SindriKit ist ausschließlich für Bildungs-, Forschungs- und autorisierte Red-Teaming-Zwecke konzipiert. Den vollständigen rechtlichen Haftungsausschluss und Informationen zu OpSec-Überlegungen finden Sie in der Security Policy.


Lizenz

MIT


Kategorien