YAU – Parte 5 – Ancora il primo stadio e i “JJ chunk”
yau
Nell’ultimo articolo avevamo interrotto l’analisi del primo stadio a metà.
Avevamo visto come è decodificata la sezione bss e come automatizzarne il processo.
Il malware creava un nuovo thread che portava avanti l’infezione tramite un’APC.
In questo articolo proseguiamo dall’APC e arriviamo al termine dell’analisi del primo stadio, passando per la decodifica dei “JJ chunk”.
Per facilitare l’analisi statica è utile decodificare la sezione bss.
YET ANOTHER URSNIF
Questo è il quinto di una seria di articoli, tutti raggruppati qui.
Indice
Parte 1, Le e-mail e il documento Excel
Parte 2, Le macro
Parte 3, Il packer
Parte 4, Primo stadio e la sezione bss
Parte 5, Ancora il primo stadio e i “JJ chunk” <–
Parte 6, Il secondo stadio e i primi IoC
Parte 7, Il secondo stadio, seed, GUID e privilegi
Parte 8, Il secondo stadio, configurazione e download
Parte 9, Il secondo stadio, salvataggio dei moduli e persistenza
Parte 10, Rimozione di Ursnif
Parte 11, Il client, inizializzazione e configurazione
Parte 12, Il client, da powershell ad explorer.exe ai browser
Parte 13, Il client, comandi e trasmissione al C2
Parte 14, Il C2, panoramica
Parte 15, Il C2, i sorgenti e l’architettura
Parte 16, Il C2, vulnerabilità
Parte 17, OSINT e resoconto finale
Il flusso di lavoro
Il flusso di lavoro è molto semplice:
- decodificare la DLL contenuta nel JJ chunk
- creare un’area di memoria condivisa
- eseguire la DLL.
Il primo passo effettuato dal malware è quello di create un security descriptor per l’area di memoria condivisa.
La stringa usata dipende dalla versione del sistema operativa ma l’effetto è sempre lo stesso: negare ogni accesso ai gruppi AU (Utenti autenticati), BG (Guest) e BA (Administrator). Le due stringhe usate sono mostrate sotto (quella in basso per Windows Vista e successivi, quella in alto per Windows XP).
S:(ML;;NW;;;LW)D:(A;;0x1fffff;;;WD)(A;;0x1fffff;;;S-1-15-2-1)(A;;0x1fffff;;;S-1-15-3-1) D:(D;OICI;GA;;;BG)(D;OICI;GA;;;AN)(A;OICI;GA;;;AU)(A;OICI;GA;;;BA)
Questo security descriptor verrà usato per la sezione di memoria condivisa (il malware ad un certo punto infetterà explorer.exe, più avanti).
Nella figura sotto sono mostrati i passi successivi: estrarre il payload dal chunk JJ e la creazione dell’area di memoria condivisa.
L’area di memoria condivisa
L’area è creata con CreateFileMapping
e MapViewOfFile
. Il nome del mapping ha il formato Local\<ora in unità di 2 giorni>
.
Ovvero, l’ora di sistema è divisa per il numero di 100ns in due giorni. In questo modo il nome è “casuale” ma stabile per 48 ore.
L’area di memoria ha dimensione sufficiente a contenere il nome del file del packer (in unicode, con due byte nulli per terminatore) e altre due DWORD. Il formato è il seguente.
I JJ chunk
I JJ chunk (chiamati Joined Data da ISFB, il precursore di Ursnif) sono dati strutturati identificati da un id.
La tabella dei JJ chunk si trova subito dopo la tabella delle sezioni PE ed è identificata dalla firma “JJ” (che però è variata in alcuni sample).
Il codice di decodifica dei JJ chunk è molto semplice e rimandiamo al database IDA allegato per la sua lettura.
Dal codice è facile risalire al formato dei JJ chunk:
PACK(struct chunk_t
{
/* The word JJ (0x4a4a) */
uint16_t signature;
/* Empty space to the next item (in DWORD) */
uint8_t padding;
/* Flags*/
uint8_t flags;
/* XORed with the first DWORD of the decoded data (if compressed) or used as the first state to decode the data*/
uint32_t xorKey;
/* An unique ID */
uint32_t id;
/* RVA of the encoded data */
uint32_t offset;
/* Size of the encoded data */
uint32_t size;
});
#define CHUNK_SIGNATURE 0x4a4a
#define CHUNK_FLAG_IGNORE 0x2
#define CHUNK_FLAG_COMPRESSED 0x1
La decodifica del JJ chunk è una semplice decodifica a differenza o, se compresso, tramite aPLib (in questo caso la prima DWORD è xorata con il campo xorKey
, se ci sono almeno 4 byte).
Un’importante aspetto del codice di Ursnif è il modo in cui sono generate le costanti (tipo quella della firma JJ o quella dell’ID del chunk).
Nell’articolo precedente avevamo visto come Ursnif usava una costante (ottenuta come somma di due DWORD di una stringa) per verificare che la corretta decodifica della sezione bss.
Questa DWORD, chiamiamola signatureCheck è una specie di “cookie” (così è chiamato nel codice di ISFB trapelato in rete) con il quale tutte le costanti sono xorate.
Ad esempio, il valore 0x4a4a è ottenuto da signatureCheck tramite un opportuno xor. Analogo discorso per l’id del JJ chunk da recuperare.
Questo modo di operare è onnipresente in Ursnif.
Decodifica automatica dei JJ chunk con ujj
Anche per i JJ chunk è possibile scrivere uno strumento per il recupero automatico.
Dato che i dati puntati dai chunk potrebbero essere ovunque, è buona norma decodificare la sezione bss prima dell’estrazione.
E’ possibile scaricare ujj qui.
ujj è stato compilato per Windows ma è possibile ricompilarlo anche per Linux.
Per ogni JJ chunk viene creato un file con lo stesso nome dell’id del chunk e alcune informazioni sono mostrate in output.
>ujj ursnif.payload0.dll -- JJ Chunk -- Id: 9e154a0c Flags: CM RVA: 00007400 Size: da00 XOR key: d644da83 Padding: 0
All’interno del JJ chunk estratto troviamo un PE.
Per finire, il malware mappa ed esegue il PE estratto dal suo entry-point.
Questo conclude l’analisi del primo stadio. Per i ricercatori è disponibile il DB IDA qui.
Nel prossimo articolo vedremo il secondo stadio ed inizieremo finalmente ad esplorare le funzionalità di Ursnif.
E’ dal secondo stadio che il malware effettua le prime azioni malevole come il download dei moduli aggiuntivi, la registrazione con il C2 e la persistenza.