Skip to content
KitploitKITPLOIT
OutilsExploitsBlog
Log in
Soumettre
OutilsExploitsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
Shelter — Obsuscation du sommeil basée sur ROP pour contourner les scanners mémoire | Kitploit
Outils/GitHubGitHub/kudaes/shelter
Frameworks d'ExploitationCriminalistique MémoireRed Teaming
GitHubkudaes/shelter

Shelter

Obsuscation du sommeil basée sur ROP pour contourner les scanners mémoire

Voir le dépôt
3904815il y a 1 anVérifié par Kitploit

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

Shelter

Shelter est une technique d'obfuscation de veille complètement armée qui permet de crypter entièrement votre payload en mémoire en utilisant abondamment les ROP.

Cette crate offre les caractéristiques suivantes :

  • Chiffrement AES-128.
  • Capacité de chiffrement de l'intégralité du PE.
  • Suppression des permissions d'exécution pendant le sommeil.
  • Aucune utilisation d'APC/HWBP/Timers, utilisation exclusive des ROP pour réaliser l'obfuscation.
  • Utilisation d'Unwinder pour réaliser le spoofing de la pile d'appels avant d'exécuter la chaîne ROP.
  • Différentes méthodes d'exécution pour s'adapter à diverses circonstances.
  • Autres considérations OPSEC : DInvoke_rs, appels système indirects, chiffrement des chaînes littérales, etc.

Contenu

  • Utilisation
  • Exemples
    • fluctuate
    • fluctuate_from_address
    • fluctuate_from_pattern
  • Test du module
  • À FAIRE

Utilisation

Importez cette crate dans votre projet en ajoutant la ligne suivante à votre cargo.toml :

[dependencies]
shelter = "=0.1.2"

Ensuite, compilez votre projet en mode --release.

La fonctionnalité principale de cette crate a été encapsulée dans trois fonctions :

  • fluctuate() permet de chiffrer soit la région mémoire actuelle, soit l'intégralité du PE. Cette fonction nécessite la présence des octets MZ du PE afin de retrouver dynamiquement son adresse de base.
  • fluctuate_from_address() chiffre complètement le PE. Cette fonction attend comme paramètre d'entrée l'adresse de base du PE.
  • fluctuate_from_pattern() chiffre également complètement le PE. Cette fonction attend comme paramètre d'entrée un ensemble personnalisé de deux octets à utiliser pour déterminer l'adresse de base du PE. Ces octets magiques personnalisés remplacent le motif MZ classique.

Lorsque l'intégralité du PE est chiffrée, les protections mémoire des sections d'origine sont stockées dans le tas afin d'être restaurées par la suite.

Shelter utilise NtWaitForSingleObject pour dormir. En plus d'indiquer combien de secondes vous voulez dormir, vous pouvez également passer un handle d'événement et le signaler à tout moment pour revenir avant l'expiration du délai (en utilisant SetEvent par exemple). Gardez à l'esprit que si votre payload entier est chiffré (ce qui est le but, je suppose), vous aurez besoin d'un moyen alternatif pour signaler l'événement au cas où vous auriez dormi indéfiniment.

Exemples

fluctuate

La fonction attend les paramètres suivants :

  • Une valeur booléenne indiquant s'il faut chiffrer l'intégralité du PE ou seulement la région mémoire actuelle. Passer true nécessite que les octets MZ soient présents en mémoire.
  • Le nombre de secondes pendant lesquelles le programme dormira. Si la valeur est None, le délai sera infini, ce qui signifie que l'exécution ne reviendra pas tant que l'événement passé à NtWaitForSingleObject n'est pas signalé.
  • Un handle d'événement à passer à NtWaitForSingleObject. Ce paramètre peut être None. Le programme restera bloqué si vous définissez ce paramètre et le délai tous les deux à None.
let time_to_sleep = Some(10); // Sleep for 10 seconds
let _ = shelter::fluctuate(false, time_to_sleep, None); // Encrypt only the current memory region
let time_to_sleep = Some(10); // Sleep for 10 seconds
let _ = shelter::fluctuate(true, time_to_sleep, None); // Encrypt the whole PE
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 fonction attend les paramètres suivants :

  • Le nombre de secondes pendant lesquelles le programme dormira. Si la valeur est None, le délai sera infini, ce qui signifie que l'exécution ne reviendra pas tant que l'événement passé à NtWaitForSingleObject n'est pas signalé.
  • Un handle d'événement à passer à NtWaitForSingleObject. Ce paramètre peut être None. Le programme restera bloqué si vous définissez ce paramètre et le délai tous les deux à None.
  • L'adresse de base à partir de laquelle le PE est mappé.

Une façon d'utiliser cette fonction serait de mapper manuellement notre payload avec Dinvoke_rs. Ainsi, le chargeur peut envoyer au payload sa propre adresse de base, de sorte que le payload puisse l'utiliser pour s'obfusquer lui-même en cas de besoin. De cette façon, le chargeur peut supprimer en toute sécurité les en-têtes du PE pour atteindre un certain niveau de discrétion.

Exemple de chargeur :

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);

Exemple de payload :

#[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 fonction attend les paramètres suivants :

  • Le nombre de secondes pendant lesquelles le programme dormira. Si la valeur est None, le délai sera infini, ce qui signifie que l'exécution ne reviendra pas tant que l'événement passé à NtWaitForSingleObject n'est pas signalé.
  • Un handle d'événement à passer à NtWaitForSingleObject. Ce paramètre peut être None. Le programme restera bloqué si vous définissez ce paramètre et le délai tous les deux à None.
  • Un tableau [u8;2] contenant des octets magiques personnalisés à rechercher pour obtenir l'adresse de base du PE.

L'intérêt de créer cette fonction est de permettre au chargeur de supprimer l'en-tête du PE et d'autres signatures, y compris les octets MZ classiques. Ainsi, ces octets peuvent être remplacés par un motif personnalisé que Shelter recherchera pour récupérer l'adresse de base du PE.

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

Test du module

Afin de tester l'implémentation de la technique, PE-sieve a été principalement utilisé. Par défaut, PE-sieve cherche les implants dans les régions mémoire exécutables, ce qui signifie que même obfusquer exclusivement la région mémoire actuelle (.text) suffit pour éviter les détections :

Obfuscation de la région mémoire actuelle. Obfuscation de la région mémoire actuelle (Process Hacker).

Télécharger l’outil