In questa lezione ci concentreremo sull'analisi statica di un file eseguibile utilizzando Ghidra, il potente framework di reverse engineering sviluppato dalla NSA. Dopo aver configurato l'ambiente nella lezione precedente e introdotto l'eseguibile guesser_master
dal repository OliCyber.IT-Writeups, siamo pronti per esplorare in dettaglio le tecniche e gli strumenti che ci aiuteranno a comprendere il comportamento del software senza eseguirlo.
Non andremo ad analizzare per filo e per segno questo eseguibile, poiché il nostro obiettivo è utilizzarlo come caso di scuola per imparare a muoverci su Ghidra e a familiarizzare con le sue funzionalità principali. Eventuali chiarimenti più approfonditi circa il comportamento specifico dell'eseguibile possono essere trovati direttamente nel repository GitHub associato.
Cos'è l'analisi statica?
L'analisi statica di un eseguibile è una tecnica utilizzata per esaminare un file binario (eseguibile) senza eseguirlo. L'obiettivo è ottenere informazioni sul suo comportamento, sulla struttura del codice e su eventuali vulnerabilità di sicurezza. Questo tipo di analisi viene spesso utilizzato in ambiti come la sicurezza informatica, la reversing e il malware analysis. In breve:
- Non richiede l'esecuzione del programma: a differenza dell'analisi dinamica, l'eseguibile non viene avviato, riducendo il rischio di attivare codice dannoso.
- Analisi del codice macchina: vengono esaminati il codice binario, le sezioni del file (come
.text
,.data
,.bss
), le stringhe, le librerie collegate e le chiamate di sistema. - Rilevamento di vulnerabilità: permette di individuare buffer overflow, funzioni insicure, o errori logici nel codice.
Con Ghidra, possiamo disassemblare, decompilare e navigare il codice binario per comprenderne la logica interna. Non si corre alcun rischio di esecuzione accidentale del malware. Tra gli svantaggi troviamo però una maggiore complessità nell'interpretazione del codice senza il supporto del comportamento dinamico e la presenza di tecniche di offuscamento che complicano l'analisi.
Preparazione dell'ambiente di lavoro
Prima di iniziare apriamo Ghidra e carichiamo il progetto creato nella lezione precedente. Creiamo popi un nuovo Project o utilizziamo quello esistente. Importiamo quindi il file guesser_master
tramite "File > Import File" e selezioniamo l'eseguibile. Lasciamo le impostazioni di default, Ghidra rileverà automaticamente il formato del file (es. ELF
, PE
). Una volta importato, facciamo doppio clic sul file per avviare la fase di analisi.
Ghidra propone diverse opzioni per l'analisi automatica. Per il nostro caso dovremo avere:
- Enable Analysis: attivato.
- Decompiler Parameter ID, Function ID: attivi.
- String References: attivo, per individuare facilmente le stringhe.
Facciamo clic su "Analyze" e attendiamo il completamento.
Navigazione nell'interfaccia di Ghidra
Dopo aver cliccato su "Analyze", il programma avvia un processo di analisi automatica dell'eseguibile durante il quale vengono applicati diversi algoritmi per interpretare e strutturare il codice binario. Al termine dell'analisi, l'interfaccia di Ghidra si presenta ricca di informazioni e strumenti utili per il reverse engineering.
La finestra principale di Ghidra si chiama CodeBrowser e si suddivide in diverse aree chiave. La prima è Listing View (sezione centrale), qui viene mostrato il codice disassemblato, ossia la traduzione del codice binario in linguaggio assembly. Se l'eseguibile contiene sezioni di codice C o simili, Ghidra tenterà anche una decompilazione parziale per renderlo più leggibile.
- Indirizzi di memoria: sulla sinistra, indicano la posizione del codice nel file.
- Istruzioni assembly: al centro, con operazioni come
MOV
,CALL
,JMP
, ecc. - Commenti automatici: generati da Ghidra per facilitare la comprensione del flusso del programma.
La seconda è Decompiled View (pannello a destra). Questo pannello mostra la versione decompilata del codice, spesso in una sintassi simile al C. Anche se non perfetto, è molto utile per comprendere rapidamente la logica delle funzioni.
Il terzo e ultimo è Symbol Tree (barra laterale sinistra). Qui troviamo una struttura ad albero che organizza simboli come:
- Functions: tutte le funzioni identificate nell’eseguibile.
- Labels: etichette che indicano punti specifici del codice.
- Data: variabili, stringhe e altre strutture dati.
- Imports/Exports: funzioni e librerie esterne utilizzate dal programma.
Analisi delle sezioni del file eseguibile con Ghidra
I file eseguibili sono suddivisi in sezioni. Con Ghidra possiamo esplorarle per comprendere meglio la struttura del programma. Sezioni comuni nei file ELF
o PE
:
.text
: contiene il codice eseguibile..data
: dati inizializzati..bss
: dati non inizializzati..rodata
: dati in sola lettura (es. stringhe costanti)..plt
e.got
: usati per la risoluzione dinamica delle funzioni di libreria.
Navigando tra queste sezioni, possiamo identificare:
- Funzioni sospette (es.
strcpy
,system
,execve
). - Stringhe codificate o indirizzi IP.
- Pattern di offuscamento, come cicli inutili o chiamate a funzioni ridondanti.
Esplorazione delle funzioni
Nel Symbol Tree, clicchiamo su "Functions" per visualizzare tutte le funzioni rilevate da Ghidra. Spesso troveremo funzioni di libreria standard (es. printf
, malloc
) e funzioni definite dall'utente, spesso con nomi generici (es. FUN_00123456
).
Per analizzare una funzione facciamo doppio clic sul nome. Osserviamo poi sia il disassemblato che il codice decompilato e cerchiamo pattern ricorrenti:
- Crittografia: loop complessi, operazioni bitwise.
- Network: chiamate a funzioni come
connect
,send
erecv
. - Offuscamento: codice che sembra inutilmente complicato.
Questo ci fornisce informazioni critiche su possibili vulnerabilità o logiche di controllo deboli.
Analisi delle stringhe e riconoscimento di pattern sospetti con Ghidra
Le stringhe possono rivelare molto sul comportamento di un malware. In Ghidra andiamo su "Window > Defined Strings" per aprire il pannello delle stringhe. Filtriamo poi per parole chiave come "http", "cmd", "key" o "password". Le stringhe sospette possono indicare comandi nascosti o backdoor, indirizzi di server C2 (Command and Control) e chiavi di crittografia o password hardcoded.
L'analisi statica ci aiuta infine ad identificare pattern comuni nei malware come:
- Code Injection: uso di funzioni come
VirtualAlloc
,memcpy
eCreateThread
. - Offuscamento: uso eccessivo di
XOR
, loop ridondanti e nomi di funzioni confusi. - Anti-debugging: controlli su
IsDebuggerPresent
o istruzioni particolari comeINT 3
.
Identificare questi pattern ci permette di formulare ipotesi sul comportamento del malware senza la necessità di eseguirlo.
Conclusioni
In questa lezione abbiamo esplorato l'importanza e l'efficacia dell'analisi statica utilizzando Ghidra. Abbiamo visto come caricare un file eseguibile, configurare l'ambiente per un'analisi efficace e navigare tra le diverse sezioni del binario. L'esame delle funzioni, delle stringhe e dei pattern sospetti ci ha permesso di ottenere una comprensione più profonda del comportamento di guesser_master
, senza la necessità di eseguirlo.
Abbiamo imparato a riconoscere indicatori di potenziali minacce. A documentare in modo efficace le nostre scoperte e a sviluppare un metodo di lavoro sistematico per affrontare file complessi. L'analisi statica rappresenta una fase cruciale nel processo di reverse engineering. Fornisce infatti una base solida per le analisi più avanzate che affronteremo nelle prossime lezioni.
A breve ci concentreremo sul disassemblaggio e la decompilazione, approfondendo ulteriormente la nostra capacità di interpretare e comprendere il codice binario.