
Freeze.rs è un toolkit di payload per bypassare gli EDR tramite processi sospesi e syscall dirette, scritto in RUST.
Per visualizzare l'ultima versione di Freeze.rs o per inviare una segnalazione, fare riferimento a https://github.com/Tylous/Freeze.rs.
Se desideri saperne di più sulle tecniche utilizzate in questo framework, dai un'occhiata al Blog SourceZero e al tool originale.
Freeze.rs è un tool per la creazione di payload utilizzato per aggirare i controlli di sicurezza EDR e eseguire shellcode in modo furtivo. Freeze.rs sfrutta molteplici tecniche non solo per rimuovere gli hook EDR a livello utente, ma anche per eseguire shellcode in modo tale da bypassare altri controlli di monitoraggio degli endpoint.
Quando un processo viene creato, Ntdll.dll è la prima DLL caricata; ciò avviene prima del caricamento di qualsiasi DLL dell'EDR. Questo significa che c'è un breve ritardo prima che un EDR possa essere caricato e iniziare a hook e modificare l'assembly delle DLL di sistema. Osservando le syscall di Windows in Ntdll.dll, possiamo vedere che nulla è ancora hookato. Se creiamo un processo in stato sospeso (uno che è congelato nel tempo), possiamo vedere che nessun'altra DLL viene caricata, tranne Ntdll.dll. Si può anche notare che nessuna DLL dell'EDR è caricata, il che significa che le syscall presenti in Ntdll.dll non sono modificate.
Per utilizzare questo processo sospeso pulito per rimuovere gli hook dal loader di Freeze.rs, abbiamo bisogno di un modo per trovare e leggere programmaticamente la memoria del processo sospeso pulito. È qui che entra in gioco la randomizzazione del layout dello spazio degli indirizzi (ASLR). ASLR è un meccanismo di sicurezza per prevenire vulnerabilità basate sulla corruzione della memoria dello stack. ASLR randomizza lo spazio degli indirizzi all'interno di un processo, per garantire che tutti gli oggetti mappati in memoria, lo stack, l'heap e il programma eseguibile stesso siano unici. Ora, questo diventa interessante perché mentre ASLR funziona, non funziona per il codice indipendente dalla posizione, come le DLL. Ciò che accade con le DLL (in particolare le DLL di sistema note) è che lo spazio degli indirizzi viene randomizzato una volta all'avvio. Questo significa che non abbiamo bisogno di enumerare le informazioni di un processo remoto per trovare l'indirizzo di base della sua ntdll.dll, perché è lo stesso in tutti i processi, incluso quello che controlliamo. Poiché l'indirizzo di ogni DLL è lo stesso per ogni avvio, possiamo ottenere queste informazioni dal nostro stesso processo e non dover mai enumerare il processo sospeso per trovare l'indirizzo.
Con queste informazioni, possiamo usare l'API ReadProcessMemory per leggere la memoria di un processo. Questa chiamata API è comunemente associata alla lettura di LSASS come parte di qualsiasi attacco basato sulle credenziali; tuttavia, di per sé non è intrinsecamente dannosa, specialmente se stiamo solo leggendo una sezione arbitraria della memoria. L'unica volta che ReadProcessMemory verrà segnalata come parte di qualcosa di sospetto è se stai leggendo qualcosa che non dovresti (come il contenuto di LSASS). I prodotti EDR non dovrebbero mai segnalare il fatto che ReadProcessMemory sia stato chiamato, poiché ci sono usi operativi legittimi per questa funzione e ciò genererebbe molti falsi positivi.
Possiamo spingerci oltre leggendo solo una sezione di Ntdll.dll dove sono memorizzate tutte le syscall - la sua sezione .text, invece di leggere l'intera DLL.
Combinando questi elementi, possiamo ottenere programmaticamente una copia della sezione .text di Ntdll.dll per sovrascrivere la nostra sezione .text hookata esistente prima di eseguire lo shellcode.
ETW utilizza syscall integrate per generare questa telemetria. Poiché ETW è anche una funzionalità nativa integrata in Windows, i prodotti di sicurezza non hanno bisogno di "hookare" le syscall di ETW per accedere alle informazioni. Di conseguenza, per prevenire ETW, Freeze.rs applica patch a numerose syscall di ETW, svuotando i registri e restituendo il flusso di esecuzione all'istruzione successiva. Il patching di ETW è ora predefinito in tutti i loader.
Poiché solo Ntdll.dll viene ripristinata, tutte le chiamate successive per eseguire lo shellcode devono risiedere in Ntdll.dll. Utilizzando la crate NTAPI di Rust (nota che puoi farlo in altri linguaggi, ma in Rust è abbastanza semplice da implementare) possiamo definire e chiamare le syscall NT necessarie per allocare, scrivere e proteggere lo shellcode, saltando efficacemente le chiamate standard che si trovano in Kernel32.dll e Kernelbase.dll, poiché potrebbero ancora essere hookate.
Con la crate NTAPI di Rust, puoi vedere che tutte queste chiamate non appaiono sotto ntdll.dll, ma esistono comunque all'interno del processo.
Di conseguenza:
Questo è iniziato come un progetto divertente per imparare Rust e si è evoluto in un framework a sé stante.
Freeze.rs è stato sviluppato in Rust.
Se Rust e Rustup non sono installati, installali. Se lo stai compilando da OSX o Linux, assicurati di avere il target "x86_64-pc-windows-gnu" aggiunto. Per farlo, esegui il seguente comando:
rustup target add x86_64-pc-windows-gnu
Una volta fatto, puoi compilare Freeze.rs, esegui i seguenti comandi, o usa il binario compilato:
cargo build --release
Da lì, la versione compilata si troverà in target/release (nota che se non metti --release, il file sarà in target/debug/ )
___________
\_ _____/______ ____ ____ ________ ____ _______ ______
| __) \_ __ \_/ __ \_/ __ \\___ // __ \ \_ __ \/ ___/
| \ | | \/\ ___/\ ___/ / /\ ___/ | | \/\___ \
\___ / |__| \___ >\___ >_____ \\___ > /\ |__| /____ >
\/ \/ \/ \/ \/ \/ \/
(@Tyl0us)
Soon they will learn that revenge is a dish... best served COLD & Rusty...
USAGE:
Freeze-rs [FLAGS] [OPTIONS]
FLAGS:
-c, --console Only for Binary Payloads - Generates verbose console information when the payload is executed. This
will disable the hidden window feature
-h, --help Prints help information
-n, --noetw Disables the ETW patching that prevents ETW events from being generated.
-s, --sandbox Enables sandbox evasion by checking:
Is Endpoint joined to a domain?
Does the Endpoint have more than 2 CPUs?
Does the Endpoint have more than 4 gigs of RAM?
-V, --version Prints version information
OPTIONS:
-E, --Encrypt <ENCRYPT> Encrypts the shellcode using either AES 256, ELZMA or RC4 encryption
-I, --Input <INPUT> Path to the raw 64-bit shellcode.
-O, --Output <OUTPUT> Name of output file (e.g. loader.exe or loader.dll). Depending on what file extension
defined will determine if Freeze makes a dll or exe.
-p, --process <PROCESS> The name of process to spawn. This process has to exist in C:\Windows\System32\. Example
'notepad.exe'
-e, --export <export> Defines a custom export function name for any DLL.
Freeze.rs può generare sia un file .exe che un file .dll. Per specificarlo, assicurati che l'opzione della riga di comando -O termini con .exe per i binari o con .dll per le dll. Nessun altro tipo di file è attualmente supportato. Nel caso di file DLL, Freeze.rs può anche aggiungere funzionalità di esportazione aggiuntive. Per fare ciò, usa -export con il nome specifico della funzione di esportazione.
Crittografare lo shellcode è una tecnica importante per proteggerlo dall'essere rilevato e analizzato dagli EDR e da altri prodotti di sicurezza. Freeze.rs include molteplici metodi per crittografare lo shellcode, tra cui AES, ELZMA e RC4.
AES (Advanced Encryption Standard) è un algoritmo di crittografia simmetrica ampiamente utilizzato per crittografare i dati. Freeze.rs utilizza AES con dimensione di bit 256 per crittografare lo shellcode. Il vantaggio di utilizzare AES per crittografare lo shellcode è che fornisce una crittografia forte ed è ampiamente supportato dalle librerie crittografiche. Tuttavia, l'uso di una dimensione fissa del blocco può renderlo vulnerabile a determinati attacchi, come l'attacco di padding oracle.
ELZMA è un algoritmo di compressione e crittografia spesso utilizzato nei malware per offuscare il codice. Per crittografare lo shellcode usando ELZMA, lo shellcode viene prima compresso usando l'algoritmo ELZMA. I dati compressi vengono quindi crittografati usando una chiave casuale. I dati crittografati e la chiave vengono quindi incorporati nel codice exploit. Il vantaggio di utilizzare ELZMA per crittografare lo shellcode è che fornisce sia compressione che crittografia in un unico algoritmo. Questo può aiutare a ridurre le dimensioni del codice exploit e renderlo più difficile da rilevare.
RC4 è un algoritmo di crittografia simmetrica spesso utilizzato nei malware per crittografare lo shellcode. È un cifrario a flusso che può utilizzare chiavi a lunghezza variabile ed è noto per la sua semplicità e velocità.
Freeze.rs utilizza una tecnica per creare prima il processo e poi spostarlo in background. Questo fa due cose: primo, aiuta a mantenere il processo nascosto, e secondo, evita di essere rilevato da qualsiasi prodotto EDR. Generare un processo immediatamente in background può essere molto sospetto e un indicatore di dannosità. Freeze.rs lo fa chiamando le funzioni Windows GetConsoleWindow e ShowWindow dopo che il processo è stato creato e gli hook dell'EDR sono caricati, e poi modifica gli attributi della finestra in nascosti.
Se si seleziona l'opzione della riga di comando -console, Freeze.rs non nasconderà il processo in background. Invece, Freeze.rs aggiungerà diversi messaggi di debug che mostrano ciò che il loader sta facendo.