Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
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.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
Shelter — Ofuscación de suspensión basada en ROP para evadir escáneres de memoria | Kitploit
Herramientas/GitHubGitHub/kudaes/shelter
Frameworks de ExploitsForensia de MemoriaRed Teaming
GitHubkudaes/shelter

Shelter

Ofuscación de suspensión basada en ROP para evadir escáneres de memoria

Ver Repositorio
390484hace 1 añoRevisado 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

Shelter

Shelter es una técnica de ofuscación de suspensión completamente armada que permite cifrar por completo tu payload en memoria haciendo un uso extensivo de ROP.

Este crate viene con las siguientes características:

  • Cifrado AES-128.
  • Capacidad de cifrar el PE completo.
  • Eliminación del permiso de ejecución durante el tiempo de suspensión.
  • Sin uso de APC/HWBP/Timers, uso exclusivo de ROP para lograr la ofuscación.
  • Uso de Unwinder para lograr el spoofing de la pila de llamadas antes de ejecutar la cadena ROP.
  • Diferentes métodos de ejecución para adaptarse a diversas circunstancias.
  • Otras consideraciones OPSEC: DInvoke_rs, llamadas indirectas al sistema, cifrado de literales de cadena, etc.

Contenido

  • Uso
  • Ejemplos
    • fluctuate
    • fluctuate_from_address
    • fluctuate_from_pattern
  • Pruebas del módulo
  • TO-DO

Uso

Importa este crate en tu proyecto añadiendo la siguiente línea a tu cargo.toml:

root@kitploit:~
[dependencies]
shelter = "=0.1.2"

Luego, compila tu proyecto en modo --release.

Descargar herramienta

La funcionalidad principal de este crate se ha envuelto en tres funciones:

  • fluctuate() permite cifrar tanto la región de memoria actual como todo el PE. Esta función requiere que los bytes MZ del PE estén presentes para recuperar dinámicamente su dirección base.
  • fluctuate_from_address() cifra completamente el PE. Esta función espera como parámetro de entrada la dirección base del PE.
  • fluctuate_from_pattern() también cifra completamente el PE. Esta función espera como parámetro de entrada un conjunto personalizado de dos bytes para usar y determinar la dirección base del PE. Estos bytes mágicos personalizados reemplazan el patrón MZ clásico.

Siempre que se cifra todo el PE, las protecciones de memoria de las secciones originales se almacenan en el heap para restaurarlas posteriormente.

Shelter utiliza NtWaitForSingleObject para dormir. Además de indicar cuántos segundos quieres dormir, también puedes pasar un handle de evento y señalarlo en cualquier momento para regresar antes de que expire el tiempo de espera (usando SetEvent por ejemplo). Ten en cuenta que si tu payload completo está cifrado (que es la idea principal, supongo), necesitarás una forma alternativa de señalizar el evento en caso de que hayas dormido indefinidamente.

Ejemplos

fluctuate

La función espera los siguientes parámetros:

  • Un valor booleano que indica si cifrar todo el PE o solo la región de memoria actual. Pasar true requiere que los bytes MZ estén presentes en memoria.
  • El número de segundos que el programa dormirá. Si se deja como None, el tiempo de espera será infinito, lo que significa que la ejecución no regresará hasta que se señalice el evento pasado a NtWaitForSingleObject.
  • Un handle de evento para pasar a NtWaitForSingleObject. Este parámetro puede ser None. El programa se bloqueará si configuras este parámetro y el tiempo de espera ambos a None.
root@kitploit:~
let time_to_sleep = Some(10); // Sleep for 10 seconds
let _ = shelter::fluctuate(false, time_to_sleep, None); // Encrypt only the current memory region
root@kitploit:~
let time_to_sleep = Some(10); // Sleep for 10 seconds
let _ = shelter::fluctuate(true, time_to_sleep, None); // Encrypt the whole PE
root@kitploit:~
pub type CreateEventW = unsafe extern "system" fn (*const SECURITY_ATTRIBUTES, i32, i32, *const u16) -> HANDLE;

let k32 = dinvoke_rs::dinvoke::get_module_base_address("kernel32.dll"); 
let create_event: CreateEventW;
let event_handle: Option<HANDLE>;
dinvoke_rs::dinvoke::dynamic_invoke!(k32,"CreateEventW",create_event,event_handle,ptr::null_mut(),0,0,ptr::null());
let time_to_sleep = None; // Sleep indefinitely
let _ = shelter::fluctuate(true, time_to_sleep, event_handle); // Encrypt the whole PE until the event is signaled

fluctuate_from_address

La función espera los siguientes parámetros:

  • El número de segundos que el programa dormirá. Si se deja como None, el tiempo de espera será infinito, lo que significa que la ejecución no regresará hasta que se señalice el evento pasado a NtWaitForSingleObject.
  • Un handle de evento para pasar a NtWaitForSingleObject. Este parámetro puede ser None. El programa se bloqueará si configuras este parámetro y el tiempo de espera ambos a None.
  • La dirección base desde la cual se mapea el PE.

Una forma de usar esta función sería mapear manualmente nuestro payload con Dinvoke_rs. De esta manera, el loader puede enviar al payload su propia dirección base, para que el payload pueda usarla para ofuscarse cuando sea necesario. Así, el loader puede eliminar de forma segura los encabezados del PE para lograr un cierto nivel de sigilo.

Ejemplo de loader:

root@kitploit:~
let payload: Vec<u8> = your_download_function();
let mut m = dinvoke_rs::manualmap::manually_map_module(payload.as_ptr(), true).unwrap();
println!("The dll is loaded at base address 0x{:x}", m.1);
let dll_exported_function = dinvoke::get_function_address(m.1, "run");

let run: unsafe extern "Rust" fn (usize) = std::mem::transmute(dll_exported_function);
run(m.1 as usize);

Ejemplo de payload:

root@kitploit:~
#[no_mangle]
fn run(base_address: usize)
{
	...
	let time_to_sleep = Some(10); // Sleep for 10 seconds
	let _ = shelter::fluctuate_from_address(time_to_sleep, None, base_address); // Encrypt the entire PE from this specific base address
	...
}

fluctuate_from_pattern

La función espera los siguientes parámetros:

  • El número de segundos que el programa dormirá. Si se deja como None, el tiempo de espera será infinito, lo que significa que la ejecución no regresará hasta que se señalice el evento pasado a NtWaitForSingleObject.
  • Un handle de evento para pasar a NtWaitForSingleObject. Este parámetro puede ser None. El programa se bloqueará si configuras este parámetro y el tiempo de espera ambos a None.
  • Un array [u8;2] que contiene bytes mágicos personalizados para buscar y así obtener la dirección base del PE.

El propósito de crear esta función es permitir que el loader elimine el encabezado del PE y otras firmas, incluidos los clásicos bytes MZ. De esta manera, esos bytes pueden ser reemplazados por un patrón personalizado que Shelter buscará para recuperar la dirección base del PE.

root@kitploit:~
let time_to_sleep = Some(10); // Sleep for 10 seconds
let pattern = [0x29,0x07];
let _ = shelter::fluctuate_from_pattern(time_to_sleep, None, pattern); // Encrypt the whole PE using custom pattern as magic bytes

Pruebas del módulo

Para probar la implementación de la técnica, se ha utilizado principalmente PE-sieve. Por defecto, PE-sieve busca implants dentro de regiones de memoria ejecutables, lo que significa que incluso ofuscando exclusivamente la región de memoria actual (.text) es suficiente para evitar detecciones:

Ofuscación de la región de memoria actual. Ofuscación de la región de memoria actual (Process Hacker).

Nota que, dado que estamos usando Unwinder, la pila de llamadas es falseada y por lo tanto la bandera /threads tampoco detecta la dll mapeada.

Ahora, PE-sieve permite inspeccionar regiones de memoria no ejecutables también usando la bandera /data. Según la documentación oficial de la herramienta, esta bandera configurada como always puede "producir mucho ruido/falsos positivos". A pesar de ello, decidimos usarla para comprobar la efectividad de la capacidad de cifrado completo del PE, ya que permite ocultar regiones de datos del PE que podrían contener indicadores de la presencia de un implant en memoria.

Ofuscación de la región de memoria actual detectada por PE-sieve. La ofuscación completa del PE permanece sin detectar.

Como se puede ver, en la primera imagen se muestra cómo ofuscar solo la sección .text no es suficiente cuando PE-sieve escanea páginas de memoria no ejecutables, ya que algunas regiones podrían contener cadenas que revelen la presencia de una DLL (MZ, encabezado DOS, nombres de sección, etc.). Por otro lado, la segunda imagen muestra cómo este problema puede resolverse usando el mecanismo de ofuscación completa del PE de Shelter. En cualquier caso, y como se indica en la wiki de PE-sieve, esta opción conduce a toneladas de falsos positivos ya que la mera presencia en el heap de cadenas como ".data" o "rdata" ya advierte de un posible PE implantado, a pesar de que no es capaz de volcar nada de la memoria (ya que no hay contenido real de PE en esa región).

Finalmente, PE-sieve tiene una opción bastante nueva para detectar la presencia de implants ofuscados buscando regiones de memoria de alta entropía. Esta opción (/obfusc) en combinación con /data es capaz de detectar la presencia del payload debido a la alta entropía de la región de memoria que lo contiene (aunque no puede recuperar el PE ya que está completamente cifrado):

Detección de ofuscación completa del PE. Ofuscación completa del PE (Process Hacker).

TO-DO

Aunque Shelter está listo para usar y se ha desarrollado pensando en OPSEC, todavía quedan algunas mejoras que se añadirán en un futuro cercano:

  • Reducir la entropía cuando se cifra todo el PE.
  • Reemplazar BCryptEncrypt/BCryptDecrypt con la función Nt correspondiente.
  • Añadir algo de aleatoriedad al proceso de selección de gadgets.

Trabajo previo

  • Gargoyle
  • Ekko
  • Cronos