Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
Shelter — Offuscamento del sonno basato su ROP per eludere gli scanner di memoria | Kitploit
Strumenti/GitHubGitHub/kudaes/shelter
Framework di ExploitMemory ForensicsRed Teaming
GitHubkudaes/shelter

Shelter

Offuscamento del sonno basato su ROP per eludere gli scanner di memoria

Vedi Repository
390481 anno faRevisionato da Kitploit

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

Shelter

Shelter è una tecnica di offuscamento del sonno completamente armata che permette di crittografare completamente il tuo payload in memoria facendo un uso estensivo di ROP.

Questo crate presenta le seguenti caratteristiche:

  • Crittografia AES-128.
  • Capacità di crittografia dell'intero PE.
  • Rimozione dei permessi di esecuzione durante il periodo di sonno.
  • Nessun APC/HWBP/Timer utilizzato, uso esclusivo di ROP per ottenere l'offuscamento.
  • Uso di Unwinder per realizzare lo spoofing dello stack di chiamate prima di eseguire la catena ROP.
  • Diversi metodi di esecuzione per adattarsi a varie circostanze.
  • Altre considerazioni OPSEC: DInvoke_rs, syscall indiretti, crittografia di stringhe letterali, ecc.

Contenuto

  • Utilizzo
  • Esempi
    • fluctuate
    • fluctuate_from_address
    • fluctuate_from_pattern
  • Test del modulo
  • TO-DO

Utilizzo

Importa questo crate nel tuo progetto aggiungendo la seguente riga al tuo cargo.toml:

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

Quindi, compila il tuo progetto in modalità --release.

La funzionalità principale di questo crate è stata racchiusa in tre funzioni:

  • fluctuate() permette di crittografare sia la regione di memoria corrente che l'intero PE. Questa funzione richiede che i byte MZ del PE siano presenti per recuperare dinamicamente il suo indirizzo di base.
  • fluctuate_from_address() crittografa completamente il PE. Questa funzione si aspetta come parametro di input l'indirizzo di base del PE.
  • fluctuate_from_pattern() crittografa anch'essa completamente il PE. Questa funzione si aspetta come parametro di input un set personalizzato di due byte da utilizzare per determinare l'indirizzo di base del PE. Questi byte magici personalizzati sostituiscono il classico pattern MZ.

Ogni volta che l'intero PE viene crittografato, le protezioni di memoria delle sezioni originali vengono memorizzate nell'heap per essere ripristinate successivamente.

Shelter utilizza NtWaitForSingleObject per dormire. Oltre a indicare per quanti secondi si desidera dormire, è possibile passare anche un handle di evento e segnalarlo in qualsiasi momento per tornare prima della scadenza del timeout (usando SetEvent per esempio). Tieni presente che se l'intero payload è crittografato (che è il punto principale, immagino), avrai bisogno di un modo alternativo per segnalare l'evento nel caso in cui tu abbia dormito indefinitamente.

Esempi

fluctuate

La funzione si aspetta i seguenti parametri:

  • Un valore booleano che indica se crittografare l'intero PE o solo la regione di memoria corrente. Passare true richiede che i byte MZ siano presenti in memoria.
  • Il numero di secondi per cui il programma dormirà. Se lasciato a None, il timeout sarà infinito, il che significa che l'esecuzione non tornerà fino a quando l'evento passato a NtWaitForSingleObject non viene segnalato.
  • Un handle di evento da passare a NtWaitForSingleObject. Questo parametro può essere None. Il programma si bloccherà se imposti questo parametro e il timeout entrambi a None.
root@kitploit:~
let time_to_sleep = Some(10); // Dormi per 10 secondi
let _ = shelter::fluctuate(false, time_to_sleep, None); // Crittografa solo la regione di memoria corrente
root@kitploit:~
let time_to_sleep = Some(10); // Dormi per 10 secondi
let _ = shelter::fluctuate(true, time_to_sleep, None); // Crittografa l'intero 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; // Dormi indefinitamente
let _ = shelter::fluctuate(true, time_to_sleep, event_handle); // Crittografa l'intero PE finché l'evento non viene segnalato

fluctuate_from_address

La funzione si aspetta i seguenti parametri:

  • Il numero di secondi per cui il programma dormirà. Se lasciato a None, il timeout sarà infinito, il che significa che l'esecuzione non tornerà fino a quando l'evento passato a NtWaitForSingleObject non viene segnalato.
  • Un handle di evento da passare a NtWaitForSingleObject. Questo parametro può essere None. Il programma si bloccherà se imposti questo parametro e il timeout entrambi a None.
  • L'indirizzo di base da cui il PE è mappato.

Un modo per utilizzare questa funzione sarebbe quello di mappare manualmente il nostro payload con Dinvoke_rs. In questo modo, il loader può inviare al payload il proprio indirizzo di base, così che il payload possa usarlo per offuscarsi ogni volta che è necessario. In questo modo, il loader può rimuovere in sicurezza le intestazioni del PE per ottenere un certo livello di furtività.

Esempio di 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!("La dll è caricata all'indirizzo di base 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);

Esempio di payload:

root@kitploit:~
#[no_mangle]
fn run(base_address: usize)
{
	...
	let time_to_sleep = Some(10); // Dormi per 10 secondi
	let _ = shelter::fluctuate_from_address(time_to_sleep, None, base_address); // Crittografa l'intero PE da questo specifico indirizzo di base
	...
}

fluctuate_from_pattern

La funzione si aspetta i seguenti parametri:

  • Il numero di secondi per cui il programma dormirà. Se lasciato a None, il timeout sarà infinito, il che significa che l'esecuzione non tornerà fino a quando l'evento passato a NtWaitForSingleObject non viene segnalato.
  • Un handle di evento da passare a NtWaitForSingleObject. Questo parametro può essere None. Il programma si bloccherà se imposti questo parametro e il timeout entrambi a None.
  • Un array [u8;2] contenente byte magici personalizzati da cercare per ottenere l'indirizzo di base del PE.

Lo scopo di creare questa funzione è di permettere al loader di rimuovere l'intestazione del PE e altre firme, inclusi i classici byte MZ. In questo modo, quei byte possono essere sostituiti da un pattern personalizzato che Shelter cercherà per recuperare l'indirizzo di base del PE.

root@kitploit:~
let time_to_sleep = Some(10); // Dormi per 10 secondi
let pattern = [0x29,0x07];
let _ = shelter::fluctuate_from_pattern(time_to_sleep, None, pattern); // Crittografa l'intero PE usando un pattern personalizzato come byte magici

Test del modulo

Per testare l'implementazione della tecnica, è stato utilizzato principalmente PE-sieve. Per impostazione predefinita, PE-sieve cerca impianti all'interno di regioni di memoria eseguibili, il che significa che anche offuscare esclusivamente la regione di memoria corrente (.text) è sufficiente per evitare rilevamenti:

Offuscamento della regione di memoria corrente. Offuscamento della regione di memoria corrente (Process Hacker).

Nota che, poiché stiamo usando Unwinder, lo stack di chiamate viene falsificato e quindi il flag /threads non rileva nemmeno la dll mappata.

Ora, PE-sieve permette di ispezionare anche le regioni di memoria non eseguibili usando il flag /data. Secondo la documentazione ufficiale dello strumento, questo flag impostato su always può "produrre molto rumore/falsi positivi". Nonostante ciò, abbiamo deciso di usarlo per verificare l'efficacia della capacità di crittografia dell'intero PE, poiché permette di nascondere le regioni dati del PE che potrebbero contenere indicatori della presenza di un impianto in memoria.

Offuscamento della regione di memoria corrente rilevato da PE-sieve. L'offuscamento dell'intero PE rimane non rilevato.

Come si può vedere, nella prima immagine viene mostrato come offuscare solo la sezione .text non sia sufficiente quando PE-sieve esegue la scansione delle pagine di memoria non eseguibili, poiché alcune regioni potrebbero contenere stringhe che rivelano la presenza di una DLL (MZ, intestazione DOS, nomi di sezioni, ecc.). D'altra parte, la seconda immagine mostra come questo problema possa essere risolto utilizzando il meccanismo di offuscamento dell'intero PE di Shelter. In ogni caso, come affermato nel wiki di PE-sieve, questa opzione porta a tonnellate di falsi positivi poiché la semplice presenza nell'heap di stringhe come ".data" o "rdata" già avverte di un possibile PE impiantato, nonostante non sia in grado di dumpare nulla dalla memoria (poiché non c'è alcun contenuto reale del PE in quella regione).

Infine, PE-sieve ha un'opzione relativamente nuova per rilevare la presenza di impianti offuscati cercando regioni di memoria ad alta entropia. Questa opzione (/obfusc) in combinazione con /data è in grado di rilevare la presenza del payload a causa dell'alta entropia della regione di memoria che lo contiene (anche se non può recuperare il PE poiché è completamente crittografato):

Rilevamento dell'offuscamento dell'intero PE. Offuscamento dell'intero PE (Process Hacker).

TO-DO

Sebbene Shelter sia pronto per l'uso e sia stato sviluppato tenendo conto dell'OPSEC, ci sono ancora alcuni miglioramenti che verranno aggiunti nel prossimo futuro:

  • Ridurre l'entropia quando l'intero PE è crittografato.
  • Sostituire BCryptEncrypt/BCryptDecrypt con la corrispondente funzione Nt.
  • Aggiungere un po' di casualità al processo di selezione dei gadget.

Lavori precedenti

  • Gargoyle
  • Ekko
  • Cronos
Scarica lo strumento