Skip to content
KitploitKITPLOIT
HerramientasExploitsBlog
Log in
Enviar
HerramientasExploitsBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

FeedsContactoPrivacidad© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
lacuna-rs — Crate de Rust para suplantación de pila de llamadas con ghost-frame, syscalls indirectos en tiempo de ejecución e inyección APC en Windows x64. Proporciona resolución de SSN, emisión de stubs JIT y cifrado de parámetros basado en VEH para evasión de EDR. | Kitploit
Herramientas/GitHubGitHub/karkas66/lacuna-rs
ShellcodePost-ExplotaciónRed TeamingDesarrollo de PayloadsExplotación de Binarios
GitHubkarkas66/lacuna-rs

lacuna-rs

Crate de Rust para suplantación de pila de llamadas con ghost-frame, syscalls indirectos en tiempo de ejecución e inyección APC en Windows x64. Proporciona resolución de SSN, emisión de stubs JIT y cifrado de parámetros basado en VEH para evasión de EDR.

Ver Repositorio
18172hace 19 díasRevisado por Kitploit

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

lacuna-rs

Suplantación de pila de llamadas mediante ghost-frame + syscalls indirectas en tiempo de ejecución para Windows x64 — portado a Rust.

Portado desde LACUNA Chain (lacuna_chain.c) por Mohamed Alzhrani (0xmaz).

lacuna-rs es un crate de Rust reutilizable que proporciona las mismas primitivas que el TTP original en C, estructurado para poder integrarse en cualquier proyecto Rust — como wsyscall-rs o syscalls-rs, pero con resolución de SSN en tiempo de ejecución, apuntado a syscall;ret por función y suplantación de pila mediante ghost-frame.


Crítico: Requisito de puntero de marco

La característica stack-spoof fallará silenciosamente si el crate consumidor no se compila con punteros de marco.

Las primitivas de stack-stomping en chain.rs localizan la ranura de dirección de retorno del llamador mediante el ensamblado en línea mov rbp, {x}. Esto requiere que la cadena RBP esté intacta. Rust (y la mayoría de los compiladores en modo release) omiten los punteros de marco por defecto.

build.rs establece force-frame-pointers=yes para la generación de código de este crate, pero Cargo no puede propagar los flags del compilador a los crates dependientes. Debes añadir esto a tu propio proyecto:```toml

.cargo/config.toml (in YOUR crate, not in lacuna-rs)

[build] rustflags = ["-C", "force-frame-pointers=yes"]

Sin esto, `stomp_plant()` leerá basura de RBP y o bien no hará nada (en el mejor de los casos) o corromperá la pila (en el peor de los casos). El crate no tiene forma de detectar en tiempo de ejecución si los punteros de marco están habilitados — simplemente no funcionará.

Si solo necesitas las primitivas de escaneo, resolución de SSN o inyección (sin el spoofing de pila), puedes omitir la característica `stack-spoof` y este requisito no aplica.

---

## Qué hace

| Primitiva | Función C | Módulo Rust |
|---|---|---|
| Análisis de secciones PE + exportaciones | `pe_section()`, `pe_export()` | `pe` |
| Escaneo de regiones fantasma en `.pdata` | `scan_ghosts()`, `best_ghost()` | `scan` |
| Descubrimiento de ghost-gadgets (`jmp [rbx]`) | `scan_ghost_gadgets()` | `scan` |
| Buscador de huecos NOP en `win32u` | `win32u_nop_gap()` | `scan` |
| Buscador de anclas BYOUD-MF | `find_mf_target()` | `scan` |
| Resolución de SSN (Hell's Gate / Halo's Gate) | `resolve_ssn()` | `nt` |
| Localizador de `syscall;ret` por función | `find_func_syscall()` | `nt` |
| Emisión de stub de syscall indirecta JIT | `alloc_stub()` | `stub` |
| Redirección de stub de ghost-gadget | (en `alloc_stub()`) | `stub` |
| Cifrado de parámetros con VEH + breakpoint de hardware | `param_encrypt_veh()`, `pcrypt_arm()` | `veh` |
| VEH de protección de cadena | `chain_veh()` | `veh` |
| Construcción de cadena LACUNA | `build_chain()` | `chain` |
| Stack stomp (BYOUD-RT) | `stomp_plant()`, `stomp_restore()` | `chain` |
| Recorredor de cadena (verificación) | `lacuna_walk_chain()` | `chain` |
| Inyección APC basada en secciones | `do_inject_sapc()` | `inject` |

---

## Indicadores de características```toml
[dependencies]
lacuna-rs = { version = "0.4", features = ["inject", "stack-spoof", "veh"] }
CaracterísticaDescripción¿Requiere punteros de marco?
syscalls (predeterminado)Resolución de SSN + emisión de stub JITNo
inject (predeterminado)Inyección APC basada en secciones (inject::inject_sapc)No
vehCifrado de parámetros VEH + punto de interrupción por hardwareNo
stack-spoofCadena de marcos fantasma LACUNA + stack stompSí
no-stdModo no_std (experimental)No

Cuando no hay características habilitadas, solo están disponibles las capas de escaneo/PE/NT.


Inicio rápido

Escanear en busca de regiones fantasma```sh

cargo run --example scan

### Construir + verificar la cadena de marcos fantasma```sh
cargo run --example verify --features stack-spoof

Inyectar shellcode mediante sección + APC

Prueba de inyección Prueba de inyección -- el payload se ejecutó dentro del proceso objetivo.```sh cargo run --example inject --features inject,stack-spoof,veh -- <sc.bin>

Añade `--verbose` para habilitar la salida de diagnóstico de VEH (volcados de pila, impresiones de registros):```sh
cargo run --example inject --features inject,stack-spoof,veh -- <pid> <sc.bin> --verbose

Algoritmo de puntuación de hilos

inject_sapc clasifica los hilos del objetivo. La señal de clasificación más fuerte es si un hilo posee una ventana:

  • Posee una ventana (hilo GUI/bomba de mensajes) — EnumWindows + GetWindowThreadProcessId. Un hilo GUI se estaciona en una espera alertable en su bucle de mensajes, por lo que una APC en cola se ejecuta allí primero. +1000.
  • Tiempo de ciclo — NtQueryInformationThread(ThreadCycleTime); recurre a ThreadTimes cuando la clase no está disponible en la compilación en ejecución (ver examples/tprobe.rs). Normalizado y sumado.
  • Tiempo de CPU — NtQueryInformationThread(ThreadTimes) — tiempo de kernel + usuario.
  • Conteo de suspensiones — NtQueryInformationThread(ThreadSuspendCount). Un hilo suspendido no puede ejecutar una APC: −2000 por conteo de suspensión.
  • Prioridad — NtQueryInformationThread(ThreadBasicInformation). Prioridad 8–10 obtiene +150; prioridad fuera de rango obtiene −300.

Filtrado. Los hilos suspendidos y los hilos estacionados en una espera de kernel no alertable — WrDelayExecution (Sleep/NtDelayExecution) o WrSuspended, leídos de NtQuerySystemInformation(SystemProcessInformation) — se descartan directamente (nunca pueden tomar una APC). El motivo de espera por lo demás es solo diagnóstico: se registra por candidato como State: / Reason: / Alert:, pero no influye en la puntuación, porque KWAIT_REASON no codifica la alertabilidad (una espera de objeto alertable y una no alertable reportan el mismo valor — verificado con sondeo estilo examples/tprobe.rs).

Los candidatos se ordenan (mayor puntuación, desempate GUI luego ciclos) y se truncan a MAX_APC_CANDIDATES (10) para enumeración/registro.

Enumerar ≠ inyectar. El número de hilos listados está desacoplado del número inyectados. MAX_APC_CANDIDATES (10) controla cuántos se clasifican y registran; APC_INJECT_THREADS (5) controla cuántos reciben realmente la APC.

Por qué inyectar a varios, luego reintentar: el modo usuario no puede saber qué hilo está en una espera alertable, y un único hilo elegido a menudo nunca entra en una, por lo que la APC nunca se dispararía. inject_sapc por lo tanto encola la APC a varios hilos y luego reencola en un bucle corto (~80 ms) hasta que la palabra de puerta compartida cambie de 0 a 1 — es decir, hasta que algún hilo objetivo realmente ejecute el payload. Registra si eso ocurrió: payload claimed the gate (ejecutado) vs gate NOT claimed.

Por qué ejecutar una vez: el mismo shellcode/contexto se encola a cada hilo, por lo que sin protección un payload no reentrante se ejecutaría concurrentemente y bloquearía el host (medido: 3 ejecuciones simultáneas). La puerta de reentrancia (USE_REENTRANCY_GATE, activada por defecto) hace que el cuerpo del payload se ejecute exactamente una vez independientemente de cuántos hilos (o cuántas rondas de reintento) tomen la APC (medido: exactamente 1). Deja la puerta activada a menos que tu payload sea explícitamente seguro para concurrencia.


Uso como biblioteca

Básico: escaneo + resolución de SSN```rust

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

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

Descargar herramienta