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
Unwinder — Spoofing de pile d'appels pour Rust | Kitploit
Outils/GitHubGitHub/kudaes/unwinder
Évasion IDS/IPSPost-ExploitationRed TeamingDéveloppement de Charges UtilesAttaque Adversariale
GitHubkudaes/unwinder

Unwinder

Spoofing de pile d'appels pour Rust

Voir le dépôt
3843616il 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

Contenu

  • SilentMoonWalk
    • Description
    • Crédits
    • Utilisation
      • Macro call_function!()
      • Macro indirect_syscall!()
      • Passage des paramètres
    • Exemples
      • Appel de kernel32.dll!Sleep()
      • Appel de kernel32.dll!OpenProcess()
      • Appel de NtDelayExecution() en syscall indirect
      • Concaténation des appels de macros
    • Considérations
      • Cadre initial
      • PoC
  • Remplacement de pile
    • Description de la technique
    • Comment l'utiliser
    • Exemple pratique
    • Remarques

SilentMoonWalk

Description

Unwinder fournit une weaponization complète de la technique SilentMoonWalk, permettant d'obtenir un spoofing complet et stable de la pile d'appels en Rust.

Cette technique présente les caractéristiques suivantes :

  • Prise en charge de l'exécution de toute fonction arbitraire avec jusqu'à 11 paramètres.
  • Prise en charge des syscalls indirects (sans allocations de tas supplémentaires) avec jusqu'à 11 paramètres.
  • La crate permet de récupérer la valeur retournée par les fonctions appelées via elle.
  • Le processus de spoofing peut être concaténé un nombre illimité de fois sans augmenter la taille de la pile d'appels.
  • TLS est utilisé pour accroître l'efficacité du processus de spoofing.
  • dinvoke_rs est utilisé pour effectuer tout appel API Windows requis par la crate.

Crédits

Merci aux créateurs de la technique SilentMoonWalk :

  • KlezVirus
  • Waldo-IRC
  • Trickster0

Et bien sûr, un grand merci à namazso pour le fil Twitter qui a inspiré tout ce projet.

Utilisation

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

[dependencies]
unwinder = "=0.1.4"

La fonctionnalité principale de cette crate est encapsulée dans deux macros :

  • La macro call_function!() permet d'exécuter toute fonction arbitraire avec une pile d'appels propre.
  • La macro indirect_syscall!() exécute le syscall (indirect) spécifié avec une pile d'appels propre.

Pour utiliser l'une de ces macros, il est nécessaire d'importer le type std::ffi::c_void.

Les deux macros retournent un *mut c_void qui peut être utilisé pour récupérer la valeur retournée par la fonction exécutée. Des informations plus détaillées se trouvent dans la section des exemples.

Macro call_function!()

Cette macro est utilisée pour appeler n'importe quelle fonction souhaitée avec une pile d'appels propre. La macro attend les paramètres suivants :

  • Le premier paramètre est l'adresse mémoire à appeler après avoir usurpé la pile d'appels. Ce paramètre doit être passé comme usize, isize ou un pointeur.
  • Le deuxième paramètre est un booléen indiquant s'il faut conserver ou non le cadre de la fonction de départ. Si vous n'êtes pas sûr, définissez-le sur false, ce qui garantit toujours une pile d'appels correcte.
  • Les paramètres suivants sont les arguments à envoyer à la fonction une fois la pile d'appels usurpée.

Macro indirect_syscall!()

Cette macro est utilisée pour effectuer n'importe quel syscall indirect souhaité avec une pile d'appels propre. La macro attend les paramètres suivants :

  • Le premier paramètre est une chaîne contenant le nom de la fonction NT dont vous souhaitez exécuter le syscall.
  • Le deuxième paramètre est un booléen indiquant s'il faut conserver ou non le cadre de la fonction de départ. Si vous n'êtes pas sûr, définissez-le sur false, ce qui garantit toujours une pile d'appels correcte.
  • Les paramètres suivants sont les arguments à envoyer à la fonction NT.

Passage des paramètres

Afin de passer des arguments de différents types à ces deux macros, les considérations suivantes doivent être prises en compte :

  • Tout type de données de base pouvant être converti en usize (u8-u64, i8-i64, bool, etc.) peut être passé directement aux macros.
  • Les structures et unions de taille 8, 16, 32 ou 64 bits sont passées comme s'il s'agissait d'entiers de même taille.
  • Les structures et unions dont la taille dépasse 64 bits doivent être passées sous forme de pointeur.
  • Les chaînes (&str et String) doivent être passées sous forme de pointeur.
  • Les pointeurs nuls (ptr::null(), ptr::null_mut(), etc.) sont passés comme 0 (peu importe qu'il s'agisse d'un u8, u16, i32 ou autre).
  • Les paramètres à virgule flottante et en double précision ne sont actuellement pas pris en charge.
  • Tout autre type de données doit être passé sous forme de pointeur.

Exemples

Appel de Sleep()

let k32 = dinvoke_rs::dinvoke::get_module_base_address("kernel32.dll");
let sleep = dinvoke_rs::dinvoke::get_function_address(k32, "Sleep"); // Memory address of kernel32.dll!Sleep() 
let miliseconds = 1000i32;
unwinder::call_function!(sleep, false, miliseconds);

Appel de OpenProcess()

let k32 = dinvoke_rs::dinvoke::get_module_base_address("kernel32.dll"); 
let open_process: isize = dinvoke_rs::dinvoke::get_function_address(k32, "Openprocess");
let desired_access: u32 = 0x1000;
let inherit = 0i32;
let pid = 20628i32;
let handle = unwinder::call_function!(open_process, false, desired_access, inherit, pid); // returns *mut c_void
let handle: HANDLE = std::mem::transmute(handle);
println!("Handle id: {:x}", handle.0);

Remarquez que la macro retourne un *mut c_void qui peut être directement converti en HANDLE, car les deux types ont la même taille. Cela permet d'accéder à la valeur retournée par OpenProcess, qui est le nouveau handle du processus cible.

Appel de NtDelayExecution() en syscall indirect

let large = 0x8000000000000000 as u64; // Sleep indefinitely
let large: *mut i64 = std::mem::transmute(&large);
let alertable = false;
let ntstatus = unwinder::indirect_syscall!("NtDelayExecution", false, alertable, large); // returns *mut c_void
println!("ntstatus: {:x}", ntstatus as i32);

Remarquez que la macro retourne un *mut c_void qui peut être utilisé pour récupérer le NTSTATUS retourné par NtDelayExecution.

Concaténation des appels de macros

Le processus de spoofing peut être concaténé un nombre illimité de fois sans augmentation anormale de la taille de la pile d'appels. Le flux d'exécution est également préservé. Le code suivant en est un exemple :

fn main()
{
	function_a();
}

fn function_a()
{
	unsafe
	{
		let func_b = function_b as usize;
		call_function!(func_b, false);
		println!("function_a done.");
	}
}

fn function_b()
{
	unsafe
	{
		let func_c = function_c as usize;
		call_function!(func_c, false);
		println!("function_b done.")
	}
}

fn function_c()
{
	unsafe
	{
		let large = 0x0000000000000000 as u64; // Don't sleep so we return to function_b, allowing to check the execution flow preservation.
		let large: *mut i64 = std::mem::transmute(&large);
		let alertable = false;
		let ntstatus = unwinder::indirect_syscall!("NtDelayExecution", false, alertable, large);
		println!("ntstatus: {:x}", (ntstatus as usize) as i32); //NTSTATUS is a i32, although that second casting is not really required in this case.
	}
}

Considérations

Cadre initial

Si vous définissez le deuxième paramètre sur true (pour les deux macros), le processus de spoofing tentera de conserver le cadre de l'adresse de démarrage du thread dans la pile d'appels afin d'accroître la légitimité.

Télécharger l’outil