Skip to content
KitploitKITPLOIT
ツールブログ
Log in
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
lacuna-rs — Windows x64向けのRustクレート: ghost-frame call-stack spoofing、runtime indirect syscalls、APC injectionを提供。SSN resolution、JIT stub emission、VEH-based parameter encryptionを提供し、EDR evasionを実現。 | Kitploit
ツール/GitHubGitHub/karkas66/lacuna-rs
シェルコードポストエクスプロイトレッドチーミングペイロード開発バイナリエクスプロイト
GitHubkarkas66/lacuna-rs

lacuna-rs

Windows x64向けのRustクレート: ghost-frame call-stack spoofing、runtime indirect syscalls、APC injectionを提供。SSN resolution、JIT stub emission、VEH-based parameter encryptionを提供し、EDR evasionを実現。

リポジトリを見る
181633ヶ月前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

lacuna-rs

Ghost-frame コールスタック偽装 + ランタイム間接システムコール for Windows x64 — Rust に移植済み。

Mohamed Alzhrani (0xmaz) による LACUNA Chain (lacuna_chain.c) からの移植。

lacuna-rs は、再利用可能な Rust クレートであり、元の C TTP と同じプリミティブを提供します。構造化されているため、任意の Rust プロジェクトにドロップインできます。wsyscall-rs や syscalls-rs と似ていますが、ランタイム SSN 解決、関数ごとの syscall;ret ターゲティング、および ghost-frame スタックスプーフィング を備えています。


重要: フレームポインタの要件

stack-spoof 機能は、利用側クレートがフレームポインタ付きでコンパイルされていない場合、サイレントに失敗します。

chain.rs のスタック破壊プリミティブは、mov rbp, {x} インライン asm を介して呼び出し元のリターンアドレススロットを特定します。これには RBP チェーンがそのままである必要があります。Rust(およびほとんどのリリースモードコンパイラ)はデフォルトでフレームポインタを省略します。

build.rs はこのクレート自身のコード生成に対して force-frame-pointers=yes を設定しますが、Cargo はコンパイラフラグをダウンストリームクレートに伝播できません。 自身のプロジェクトに以下を追加する必要があります:

# .cargo/config.toml  (lacuna-rs 内ではなく、YOUR クレート内)
[build]
rustflags = ["-C", "force-frame-pointers=yes"]

これがないと、stomp_plant() は RBP からガベージを読み取り、最良の場合は何もせず、最悪の場合はスタックを破損します。このクレートは実行時にフレームポインタが有効かどうかを検出できません。単に動作しません。

スキャン、SSN 解決、またはインジェクションプリミティブのみが必要で(スタックスプーフィングなし)、stack-spoof 機能を省略すれば、この要件は適用されません。


機能概要

プリミティブC 関数Rust モジュール
PE セクション + エクスポート解析pe_section(), pe_export()pe
.pdata ゴースト領域スキャンscan_ghosts(), best_ghost()scan
ゴーストガジェット発見 (jmp [rbx])scan_ghost_gadgets()scan
win32u NOP ギャップ検出win32u_nop_gap()scan
BYOUD-MF アンカー検出find_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
チェーンガード VEHchain_veh()veh
LACUNA チェーン構築build_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-spoofLACUNA ghost-frame チェーン + スタック破壊はい
no-stdno_std モード (実験的)いいえ

機能が何も有効でない場合、スキャン/PE/NT レイヤーのみが利用可能です。


クイックスタート

ゴースト領域のスキャン

cargo run --example scan

ghost-frame チェーンの構築と検証

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) — 主要なアクティビティ指標
  • CPU 時間 — NtQueryInformationThread(ThreadTimes) — カーネル + ユーザー時間
  • サスペンドカウント — NtQueryInformationThread(ThreadSuspendCount) — 非サスペンドスレッドは +300 ボーナス;サスペンドスレッドはサスペンドカウントごとに -150
  • 優先度 — NtQueryInformationThread(ThreadBasicInformation) — 優先度 8-10 のスレッドは +150 ボーナス;範囲外の優先度は -100 ペナルティ

完全にアイドル状態のスレッド(サイクルと CPU 時間がゼロ)はスキップされます。残りの候補はスコア(高い順、同点の場合はサイクル)でソートされ、上位 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]
// (または build_chain が呼ばれていれば、jmp [ghost_gadget] -> JMP [RBX] -> syscall;ret)
let stub = stub::make_stub(ssn, syscall_ret).expect("stub alloc failed");

// 対応する関数ポインタ型にキャストして呼び出し
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()) };

ghost-frame チェーンの構築 + VEH 登録

// ntdll/kernelbase/wow64/win32u をスキャンしてゴースト領域を探し、
// 6層の偽呼び出しスタックを構築します。G_GHOST_GADGET を設定し、
// スタブが署名付き DLL 内の JMP [RBX] を経由するようにします。
lacuna::chain::build_chain();

// VEH ハンドラの登録 (パラメータ暗号化 + チェーンガード)
let _veh = lacuna::veh::VehGuard::register().expect("VEH registration failed");

// オプション: 実行時に詳細診断を有効化
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();

// syscall;ret に DR0 を設定 — VEH が境界でパラメータを XOR 復号
lacuna::veh::pcrypt_arm(key, syscall_ret, true);

// 間接スタブを通じて呼び出し — RIP は ntdll 内のカーネルエントリに到達
let _status = unsafe { open_proc(/* XOR 暗号化されたパラメータ */) };

// 保護されていない呼び出しの前に必ず解除
lacuna::veh::pcrypt_disarm();
lacuna::chain::stomp_restore();

OPSEC: ゴーストフレームの背後に隠すべきもの

すべての API 呼び出しに完全な LACUNA 処理が必要なわけではありません。重要な原則は、EDR がインジェクションやポストエクスプロイトアクティビティとして相関させる呼び出しを隠すことです。

間接システムコール + ゴーストフレーム + パラメータ暗号化の背後に置くべきもの

これらは EDR がフックして相関させる「クラウン・ジュエル」NT システムコールです:

呼び出し機密性の理由
NtOpenProcess別のプロセスへのハンドルを開く — インジェクションの第一歩
NtCreateSection + NtMapViewOfSection (リモート)セクションベースのインジェクションシグネチャ
NtWriteVirtualMemoryプロセス間書き込み — 古典的なインジェクション指標
NtCreateThreadExリモートスレッド作成 — 最高シグナルのインジェクションプリミティブ
NtQueueApcThreadAPC インジェクション — 高シグナル
NtProtectVirtualMemoryRWX 権限変更 — シェルコードステージング指標
NtAllocateVirtualMemory (リモート)リモート割り当て — インジェクションの前段階
NtSetInformationThreadスレッド隠蔽 (HideFromDebugger) — 回避指標

これらのそれぞれについて:

  1. nt::resolve(ntdll, b"NtXxx\0") で解決
  2. stub::make_stub(ssn, syscall_ret) でスタブを生成
  3. veh::pcrypt_arm(key, syscall_ret, true) で機密パラメータを XOR 暗号化
  4. 呼び出しを chain::stomp_plant() と chain::stomp_restore() でラップ

直接呼び出し可能(ゴーストフレーム不要)

呼び出し安全な理由
NtQueryInformationThreadクエリのみ、めったにフックされず、プロセス間書き込みなし
NtDelayExecutionスリープ — 良性、すべてのアプリケーションで使用
NtCloseハンドルクローズ — 良性、非常に一般的
GetModuleHandleA / GetProcAddressモジュール解決 — システムコールではなく、EDR ユーザーランドフックでフック不可
CreateToolhelp32Snapshot / Thread32First / Thread32Nextスレッド列挙 — kernel32、ntdll システムコールではない
OpenThread / CloseHandle標準ハンドル操作 — kernel32
GetThreadContext / SetThreadContextDR0 に必要 — kernel32、自己プロセスのみ

重要な原則

ツールをダウンロード