YAU – Parte 7 – Il secondo stadio, seed, GUID e privilegi
yau
Nell’articolo precedente avevamo solo estratto i JJ chunk dal secondo stadio e avevamo visto come questo fosse sufficiente ad ottenere i primi IoC.
Adesso è il momento di analizzare il secondo stadio nel dettaglio.
YET ANOTHER URSNIF
Questo è il settimo 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
Codice comune con il primo stadio
Il secondo stadio ha un po’ di codice in comune con il primo.
In particolare l’esecuzione inizia dall’entry-point PE che contiene del codice molto simile, se non identico, a quello riscontrato nel primo stadio.
La procedura waitUntilDone
, nuova del secondo stadio, segnala un evento per indicare al codice la necessità di terminare e poi cicla (con pause di 64ms) finchè il flag di lavoro non è azzerato.
Quindi una metodologia molto simile a quella già vista.
Anche nel secondo stadio è presente la decodifca della sezione bss e il recupero dell’handle del proprio processo.
Questa volta però l’handle è effettivamente usato (per ricavare il token utente).
Il malware determina se il proprio processo è o meno a 64 bit e patcha la versione dell’OS recuperata con GetVersion
.
Questa infatti può essere alterata tramite le impostazioni di compatibilità, Ursnif usa i campi PE di ntdll.dll
(Ottenuta con GetModuleHandle
) agli offset 0x40 e 0x42 (si veda il formato PE).
Il seed ed il GUID
Terminati i preparativi, il primo passo del secondo stadio è quello di determinare l’integrity level del proprio processo e di generare un seed a 32 bit.
Queste due funzionalità sono implementate dalla solita funzione: getSeed
.
getSeed
ottiene il token dell’utente che ha lanciato il processo corrente (quello in cui sta girando il secondo stadio) e dal token calcola la somma di tutte le sub authority, tranne le ultime due.
Qualora questa somma sia zero o non sia stato possibile ottenere il token, viene preso il timestamp della data di installazione di Windows da “SOFTWARE\Microsoft\Windows NT\CurrentVersion\InstallDate
“.
Quale che sia il valore ottenuto, questo viene xorato con 0x81BBE65D.
Il numero così ottenuto sarà usato come seed per generare un GUID che a sua volta rappresenterà univocamente la vittima.
Oltre al seed, la funzione getSeed
ritorna anche il modo in cui questo valore è stato generato, tramite la data di installazione di Windows o tramite la somma delle sub authority.
La funzionalità di generazione del seed si può riassumere come segue.
make_seed:
seed = Somma sotto authority tranne le ultime due
seed_is_install_date = False
if seed = 0:
seed = WIndows install date
seed_is_install_date = True
seed ^= 0x81BBE65D
return (seed, seed_is_install_date)
La funzione getSeed
si occupa anche di determinare se il processo gira con un integrity level sufficiente o meno.
Notare che Ursnif non richiede i privilegi di amministratore, la sua unica preoccupazione è quella di non avere un integrity level basso.
Questo infatti lo isolerebbe da explorer.exe e dai browser, impedendogli di fare il suo lavoro.
Facciamo adesso un piccolo salto in avanti nel codice in modo da tenere vicine le funzionalità correlate.
Il secondo stadio usa il seed per generare 16 byte tramite un LCG.
L’LCG può essere riconosciuto dalle sue costanti ed è noto in rete.
Nel codice del secondo stadio, quattro passi sono stati fusi in un unica funzione (forse dal compilatore, forse dagli autori).
La generazione dell’GUID è piuttosto semplice, a patto di riconoscere la seguente funzione:
Si tratta di CRC32, l’implementazione è identica a quella fornita in questa pagina tranne che per la funzionalità di reflect dell’input e dell’output.
La generazione del GUID può essere così definita:
make_guid(seed, seed_is_install_date):
guid = random16bytes(seed)
if seed_is_install_date:
guid[0] ^= crc32(GetUserNameW())
else:
guid[0] ^= 0x2F653B6D;
guid[3] ^= crc32(GetComputerNameW())
eax, ebx, ecx, edx = cpuid(1)
guid[1] ^= (edx ^ ecx ^ eax)
Il GUID sarà usato più avanti dal malware.
Il riavvio per rimuovere l’integrity level basso
Come già detto, ad Ursnif non servono i privilegi di amministratore ma gli è necessario poter accedere ai processi di explorer e dei browser.
Siccome questi sono eseguiti con le credenziali dell’utente è sufficiente che il processo di Ursnif non sia isolato con un integrity level basso.
Nel caso in cui il secondo stadio rilevi che il proprio integrity level sia troppo basso, riavvia l’infezione dalla DLL packer.
Questo può farlo grazie all’area di memoria condivisa vista precedentemente. Essa infatti contiene il percorso del modulo del packer.
Per rimuovere il proprio integrity level Ursnif si riavvia tramite l’interfaccia come IShellView
, che è l’interfaccia usata da explorer.exe quando si fa doppio click su un file. In sostanza viene simulato l’avvio dall’interfaccia da explorer.
La navigazione degli oggetti COM è articolata per chi non è della materia, uno strumento come COMView può aiutare a ritrovare le vtable delle varie interfacce.
Il codice segue più o meno quando descritto in questo post su StackOverflow.
Se questo metodo di riavvio dovesse fallire, viene provato ShellExecuteEx
usando il verbo “runas” per avviarsi come amministratore.
Una volta generati il seed, il GUID ed eventualmente riavviato l’esecuzione, il secondo stadio si occupa di estrarre la configurazione da un JJ chunk.
Dopodiché si registerà al C2 e otterrà come risposta i moduli per il proseguimento dell’infezione.
Se tutto va a buon fine verrà usato il registro di sistema per la permanenza e l’infezione si sposterà su explorer.exe o sui browser.
Vedremo tutto nel dettaglio nel prossimo articolo.