Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
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
39048il 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 :

root@kitploit:~
[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.
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 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 :

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

Exemple 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 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.

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

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

Remarquez que, comme nous utilisons Unwinder, la pile d'appels est usurpée et donc le drapeau /threads ne détecte pas non plus la DLL mappée.

Maintenant, PE-sieve permet également d'inspecter les régions mémoire non exécutables en utilisant le drapeau /data. Selon la documentation officielle de l'outil, ce drapeau mis à always peut "produire beaucoup de bruit/faux positifs". Malgré cela, nous avons décidé de l'utiliser pour vérifier l'efficacité de la capacité de chiffrement complet du PE, car elle permet de masquer les régions de données du PE qui pourraient contenir des indicateurs de la présence d'un implant en mémoire.

Obfuscation de la région mémoire actuelle détectée par PE-sieve. L'obfuscation complète du PE reste non détectée.

Comme on peut le voir, sur la première image, il est montré qu'obfusquer uniquement la section .text ne suffit pas lorsque PE-sieve scanne les pages mémoire non exécutables, car certaines régions peuvent contenir des chaînes qui révèlent la présence d'une DLL (MZ, en-tête DOS, noms de sections, etc.). D'autre part, la deuxième image montre comment ce problème peut être résolu en utilisant le mécanisme d'obfuscation complète du PE de Shelter. Dans tous les cas et comme indiqué dans le wiki de PE-sieve, cette option conduit à des tonnes de faux positifs car la simple présence dans le tas de chaînes comme ".data" ou "rdata" signale déjà la possibilité d'un PE implanté, bien qu'il ne soit pas capable de vider quoi que ce soit de la mémoire (car il n'y a pas de contenu réel du PE dans cette région).

Enfin, PE-sieve dispose d'une option assez récente pour détecter la présence d'implants obfusqués en cherchant les régions mémoire à haute entropie. Cette option (/obfusc) combinée avec /data est capable de détecter la présence du payload en raison de la haute entropie de la région mémoire qui le contient (bien qu'elle ne puisse pas récupérer le PE car il est entièrement chiffré) :

Détection de l'obfuscation complète du PE. Obfuscation complète du PE (Process Hacker).

À FAIRE

Bien que Shelter soit prêt à être utilisé et ait été développé en tenant compte de l'OPSEC, il reste encore quelques améliorations qui seront ajoutées dans un avenir proche :

  • Réduire l'entropie lorsque l'intégralité du PE est chiffrée.
  • Remplacer BCryptEncrypt/BCryptDecrypt par la fonction Nt correspondante.
  • Ajouter un peu d'aléatoire au processus de sélection des gadgets.

Travaux antérieurs

  • Gargoyle
  • Ekko
  • Cronos
Télécharger l’outil