Analisi malware: Babuk Ransomware e derivati (mathematical curve analysis)

Nella presente analisi sono stati presi in considerazione la metodologia e l’algoritmo di crittografia/ decrittografia utilizzati da parte di un sample di Babuk Ransomware (variante Linux).

Babuk ha origini nel 2021, la gang conosciuta anche con il nome di “Vasa Locker”. Nell’aprile dello stesso anno il loro momento di “fama” più alto, quando, il gruppo arrivò a minacciare il Metropolitan Police Department (M.P.D.) di Washington D.C. di rilasciare informazioni sensibili estratte dai sistemi del dipartimento, chiedendo in cambio riscatto di 4 milioni di dollari.

I criminali informatici di Babuk dichiararono di aver scaricato 250 GigaByte di dati minacciarono di rilasciare informazioni sugli informatori della polizia nelle bande criminali e di continuare ad attaccare le agenzie governative statunitensi, tra cui l’FBI.

Il leak, poi effettivamente confermato dalle autorità, si è rivelato poi essere la disfatta della gang. Da li a poco frantumatasi dietro dissidi interni e – probabilmente – la pressione di Washington. E, in mezzo a questo chaos, uno degli sviluppatori arrivò a pubblicare l’intero source code del ransomware in chiaro.

Source code che, sfortunatamente, è stato utilizzato da altre gang, ma anche da alcuni “impostori” che si fingono parte della defunta organizzazione di cyber criminali.

Questo crea un doppio problema: non solo sono aumentate le gang spin-off che hanno semplicemente preso in prestito il codice – come per esempio Daixin – e lo hanno poi reso “loro”, ma sono aumentati anche i casi in cui questo source code è stato scaricato, modificato nel cryptor e utilizzato in campagne dove venivano impersonati i Threat Actors di Babuk. Senza però le competenze (o forse l’effort) per modificare il decryptor, rendendo la vittima impossibilitata al recupero dati, anche dopo il pagamento del riscatto.

Tactics, Techniques, e Procedures: il modus operandi di Babuk

A seguire i dettagli dei TTPs utilizzati dalla minaccia in questione:

FASE DI CRITTOGRAFIA

 Visualizzando i dettagli degli imports effettuati dal file main.cpp (lato encryption) si può notare come siano presenti i seguenti headers:

Osservando alcune variabili utilizzate all’interno del main si evidenziano arrays di 32 celle basepoint e m_publ, nonché una struct denominata BABUK_KEYS, che come vedremo in seguito, sarà fondamentale:

L’esecuzione del core della fase di crittografia inizia con l’ottenimento ricorsivo dei files da criptare e lo fa sfruttando un threadpool ai fini di efficienza e concorrenzialità:

La funzione encrypt_file prende in input un puntatore void arg che viene poi (tramite un’operazione di cast) convertito in puntatore char. A questo punto vengono inizializzate le variabili che di fatto saranno le protagoniste nell’ottica della gestione di chiavi di crittografia da parte del ransomware: u_publ, u_priv, u_secr, sm_key.

Successivamente viene inizializzata la variabile sc che verrà utilizzata per effettuare SHA256 digesting e le due variabili sosemanuk contexts (sosemanuk_key_context e sosemanuk_run_context) al fine di permettere la crittografia dei files.

Viene poi effettuato un costrutto if al fine di verificare se siano accessibili ed ottenibili le informazioni sullo status del file preso in input mediante il valore di return della funzione stat64. Il file in questione viene poi letto con gli attributi “r+b” che indicano la lettura in formato binario:

Viene effettuata una function call mediante la funzione di generazione randomica csprng per la variabile u_priv di 32 bytes. In seguito vengono svolte altre manipolazioni randomiche mediante gli operatori  &=248, &=127 e |=64 (come da procedura ufficiale della libreria curve25519-donna):

Viene poi eseguito un richiamo alla libreria curve25519-donna per generare la chiave pubblica e la shared_key (si noti che i parametri utilizzati combaciano con quelli da documentazione ufficiale della libreria):

A questo punto viene “svuotata” completamente la variabile u_priv che rappresenta la chiave privata. Per svuotare il valore della medesima viene utilizzata la funzione memset:

Consequenzialmente viene richiamato il context di SHA256 digesting sc e viene calcolato l’hash SHA256 della shared_key per poi salvare il valore all’interno della variabile sm_key. Dopo le operazioni necessarie viene svuotato anche il context sc con il richiamo alla funzione memset. Viene in seguito richiamata la funzione sosemanuk_schedule, la quale fa riferimento al modello matematico di key modification Serpent Key. Il modello Serpent Key effettua somme ricorsive modulari mediante diverse variabili da w0 a w7:

Dopodiché viene chiamata la funzione sosemanuk_init che effettua ulteriori rounds dell’algoritmo Serpent Key Schedule e, dettaglio importante, nel caso specifico viene effettuata una modifica al modello Serpent Key originale in quanto la trasformazione lineare viene lasciata come ultimo passaggio:

Viene poi effettuata una crittografia IV tramite alcuni valori di output di rounds precedenti di Serpent Key:

Al termine dell’esecuzione della funzione sosemanuk_init viene eliminato il contenuto della variabile sm_key:

Nel momento in cui viene eseguita la vera e propria funzione di crittografia (sosemanuk_encrypt), viene passato in input il run context, vengono eseguite operazioni di XOR mediante la funzione xorbuf e vengono “puntati” i valori delrun context buf e ptr:

La funzione sosemanuk_encrypt viene richiamata all’interno di un ciclo do while che si occupa di leggere il contenuto dei files presi in input:

FASE DI DECRITTOGRAFIA

Un aspetto molto importante della fase di decrittografia prevede la lettura degli ultimi 32 bytes del file criptato preso in input tramite la funzione fread. I bytes letti vengono salvati all’interno della variabile u_publ. Successivamente viene utilizzata la libreria curve25519-donna al fine di poter ottenere, tramite lo sha256_context, l’hash della chiave u_secr, salvata all’interno della chiave sm_key. Infine, una volta che viene calcolato l’hash SHA256 della chiave u_secr e chiamate le funzioni di sosemanuk_schedule e sosemanuk_init, vengono eliminati gli ultimi 32 bytes del file preso in input mediante la funzione truncate64 e l’offset negativo -32:

A seguire, a titolo esemplificativo, i 32 bytes che sembrerebbero rappresentare la chiave pubblica archiviata all’interno di due files criptati:

Infine, viene eseguito un ciclo do while al fine di leggere il contenuto dei files presi in input e, a questo punto, viene effettuato il richiamo alle funzioni sosemanuk per poi rinominare i files decriptati:

BASI MATEMATICHE DI CURVE25519

Discutendo più in dettaglio le basi matematiche dell’algoritmo di key agreement Curve25519 è possibile sintetizzare come segue il ragionamento logico associato:

Utente A e utente B vogliono scambiarsi messaggi che devono rimanere però privati. Sia A che B possiedono sia una chiave pubblica sia una chiave segreta, entrambe da 32 bytes. Ogni coppia di chiave pubblica – chiave segreta possiede una shared key di 32 bytes, utilizzata per autenticare e criptare i messaggi dei due utenti.

Qui una rappresentazione grafica della relazione matematica e funzionale che è alla base di tale algoritmo di key sharing:

[2]

A seguire invece un’evidenza che dimostra l’uso dell’hash della shared secret key al fine di criptare il contenuto dei files o effettuare messages authenticating:

“A hash of the shared secret Curve25519(a, Curve25519(b, 9)) is used as the key for a secret-key authentication system (to authenticate messages), or as the key for a secret-key authenticated-encryption system (to simultaneously encrypt and authenticate messages).” [3]

La difficoltà nel tentare di “rompere” la sicurezza dell’algoritmo o di effettuare un’azione di brute force risiede nel fatto che Curve25519 utilizza una metodologia di moltiplicazione scalare mediante la seguente espressione:

I valori delle variabili p (numero primo) ed E sono rispettivamente i seguenti:

E = funzione di curva ellittica

[4]
[5]

È interessante inoltre notare come siano presenti efficienza e velocità nella sequenza logico-matematica ed aritmetica di Curve25519. Tale affermazione è dovuta proprio, tra le varie scelte effettuate dall’autore dell’algoritmo, all’utilizzo di una forma curva:

[6]
[7]

CONCLUSIONI:

Per Babuk ransomware, in base al codice sorgente che è stato diffuso online, possiamo stabilire con certezza l’impiego della libreria di key agreement ellittica Curve25519. Una peculiarità importante, in merito all’algoritmo in questione, è la sua velocità d’esecuzione. Inoltre è doveroso considerare che all’interno della libreria utilizzata per la fase di crittografia e decrittografia venga utilizzata una versione modificata del sistema di key modification Serpent Key Schedule, assicurandosi che la trasformazione lineare all’interno dello scheduler avvenga all’ultimo round di esecuzione.

Riferimenti:

[1] (immagine): The-Serpent-key-schedule-operation-used-for-GISKOP-using-Gi-Gi-8-Gi-5-Gi-3-Gi-1.ppm (472×360) (researchgate.net)

[2][6][7] (immagine): curve25519.dvi (yp.to)

[3]: curve25519.dvi (yp.to)

[4] (immagine): screenshot.png (300×300) (mathworks.com)

 [5] (immagine): curve25519-elliptic-curve-cryptography-montgomery-curve-png-favpng-PjQm6bTqvKexvYwiuGdGQHQVh.jpg (820×656)

Swascan Academy lancia la Terza Edizione del corso propedeutico alla certificazione CISSP!
Report: RANSOMWARE Q3 2022

Pronto intervento Cyber Swascan

Contattaci per un supporto immediato

Il sottoscritto, in qualità di interessato DICHIARA di aver letto e compreso il contenuto della privacy policy ai sensi dell’articolo 13, GDPR. ACCONSENTE al trattamento dei Dati in relazione all’invio da parte del Titolare di comunicazioni afferenti alla gestione di eventuali misure precontrattuali, preordinate alla stipulazione e/o esecuzione del contratto con il Cliente nonché all'adempimento dei relativi obblighi.
Il consenso prestato potrà essere revocato in qualsiasi momento contattando il Titolare ai recapiti presenti nella citata privacy policy.