I. Introduction
LokiBot est un malware particulièrement actif aujourd"hui.
c'est un malware dont le code est open-source qui circule sur le darkweb, capable d'enregistrer
les entrées du clavier, voler des mots de passe et aussi permet l'installation
d'autres malwares.
C'est pour cela qu'il est aussi catégorisé comme trojan et vous trouvez comme définition sous "Troj/LokiBot"
Mais dans ces quelques lignes qui suit, nous allons plutot regarder les hashs utilisé et faire le parallèle avec plusieurs analyse de JOESandbox de different échantillons
Comme celui du lien suivant : https://www.joesandbox.com/analysis/314973/0/html
II. l'algorithme de création des hashs
Lokibot utilise l'offuscation des API windows appeler, cela pour complexifier l'analyse et ne pas avoir d'information visible dans l'IAT du programme.A partir d'information disparate existant sur le web, nous
avions crée une tools permettant de disposer de l'algorithme de hash de lokibot
en C++ et Assembleur.
Nous avions réalise ce programme à l'époque pour référencer les hashs des Apis au sein du malware et disposer de l'algorithme lors d'inverse ingénierie sur des binaires non identifié ou différent. comme nous allons le montrer les hash associé permet de de trouver plusieurs autre analyse faite sur JOESandbox avec les hashs cité.
Et de là également reconstruire des fonctions des malwares.
Voici l'outil en question :
Nous mettons l'algorithme correspondant de LokiBot ( correspondant au button "Hash1" ). Celui-ci n'est viable que pour de l'ANSI
DWORD CalcHashA_LokiBot_MalwareRef_C_V1(char *Str ) { if (!Str ) return -1; DWORD dwHash = -1; char *CopyStr = Str; while ( *CopyStr != 0) { dwHash = (dwHash ^ ( *CopyStr )) & 0xffffffff;
for(int i=0;i<8;i++) { if (dwHash & 1)dwHash = (dwHash ^ 0x4358ad54) & 0xffffffff; dwHash = (dwHash >> 1) & 0xffffffff; }
CopyStr++; }
dwHash = (~dwHash) & 0xffffffff; return dwHash; } |
III. Les Hashs d'API
Nous allons regarder une autre url
https://www.joesandbox.com/analysis/315421/0/html
Nous trouvons la fonction
_t45 = E004031E5(__ebx, 9, 0xea792a5f, 0, 0);
_t39 = E004031E5(_t49, 9, 0xc0862e2b, _t67, _t67);
_t29 = E004031E5(_t49, 9, 0xecae3497, _t67, _t67);
_t25 = E004031E5(__ebx, 9, 0xe87a9e93, 0, 0);
cela nous donne 4 hashs , comme la fonction correspondante est
DWORD GetDllFunctionFromIdxAndHash( (DWORD dwIdxOfTabNameDll , DWORD dwHashApiName,DWORD Param1 , DWORD Param2 )
la fonction fonctionne par la sélection d'une dll dans un tableau dynamiquement crée en mémoire ou la valeur 9 correspond à la dll suivante "advapi32.dll"
Il nous reste plus qu'a utilisé notre tools de calcule de hash , déjà vu dans d'autre article
"ApiHashPredator"
ou via le mode recherche
Nous avons donc les hashs vu au dessus ou on a l'Api correspondante
Module advapi32.dll
Hash Value |
Dll |
Api Function |
0xEA792A5F |
advapi32.dll |
OpenProcessToken |
0xC0862E2B |
advapi32.dll |
LookupAccountSidW |
0xECAE3497 |
advapi32.dll |
GetTokenInformation |
0xeE87A9E93 |
advapi32.dll |
OpenThreadToken |
exemple recherchant d'autre d'analyse JOESandbox qui est aussi un echantillons Lokibot
on arrive sur le lien "https://www.joesandbox.com/analysis/301176/0/html"
_t25 = E004031E5(__ebx, 9, 0xe87a9e93, 0, 0);
_t39 = E004031E5(_t49, 9, 0xc0862e2b, _t67, _t67);
_t45 = E004031E5(__ebx, 9, 0xea792a5f, 0, 0);
_t33 = E004031E5(_t35, _t46, 0xf53ecacb, _t46, _t46);
_t6 = E004031E5(_t10, 0, 0xe9af4586, 0, 0);
_t3 = E004031E5(_t4, 0, 0xcfa329ad, 0, 0);
Idem l'index 0 correspond à la dll "kernel32.dll" en effectuant la même recherche des hashs
Module kernel32.dll
Hash Value |
Dll |
Api Function |
0xF53ECACB |
kernel32.dll |
VirtualFree |
0xE9AF4586 |
kernel32.dll |
GetNativeSystemInfo |
0xCFA329AD |
kernel32.dll |
Sleep |
Autre exemple de recherche sur des analyse JOESandbox qui est aussi un echantillons
on a par exemple le lien " https://www.joesandbox.com/analysis/314973/0/html "
= E004031E5(_t72, _t72, 0xd4f4acea, _t72, _t72);
= E004031E5(_t73, 0, 0xce4477cc, 0, 0);
= E004031E5(0, 0, 0xd4f4acea, 0, 0);
Module kernel32.dll
Hash Value |
Dll |
Api Function |
0xD4F4ACEA |
kernel32.dll |
FindFirstFileW |
0xCE4477CC |
kernel32.dll |
FindNextFileW |
0xD4F4ACEA |
kernel32.dll |
FindFirstFileW |
Nous avons également des dans ces échantillons 0xC5FA88F1 utilisé avec l'index 10 ( 0x0A)
Donc cela correspond à Shell32.dll
Nous avons passer la recherche dans la DLL du hash , comme vous pouvez le voir dans la capture suivante:
Cela nous donne l'utilisation de l'API suivante dans Loki
Module Shell32.dll ( Index 0x0A )
Hash Value |
Dll |
Api Function |
0xC5FA88F1 |
Shell32.dll |
CommandLineToArgW |
On va regarder de plus prés la fonction à l'adresse mémoire 0x00414069 utilisant le hash au dessus
nous mettons le bloc des opcodes de la fonction en dessous:
\x55\x8B\xEC\x6A\x00\x6A\x00\x68\xF1\x88\xFA\xC5\x6A\x0A\xE8\x69\xF1\xFE
\xFF\xFF\x75\x0C\xFF\x75\x08\xFF\xD8\x5D\xC3
Nous avons passer le code dans notre outils pour obtenir le code assembleur.
Nous remettons le contenu en dessous:
00000000: 55 PUSH EBP 00000001: 8B EC MOV EBP,ESP 00000003: 6A 00 PUSH 00h (0) ' 00000005: 6A 00 PUSH 00h (0) ' 00000007: 68 F1 88 FA C5 PUSH C5FA88F1h (C5FA88F1=Hash[Lokibok(XOR+Key:0x4358ad54)]('CommandLineToArgvW')) 0000000C: 6A 0A PUSH 0Ah (10) ' 0000000E: E8 69 F1 FE FF CALL 0xFFFEF169 (-10E97h ->:FFFEF17C) 00000013: FF 75 0C PUSH DWORD PTR [EBP+0Ch] 00000016: FF 75 08 PUSH DWORD PTR [EBP+08h] 00000019: FF D8 CALL EAX 0000001B: 5D POP EBP 0000001C: C3 RET |
Nous avons également le hash 0xD6865BD4 pour une Api
utilisé de shlwapi.dll
De la même maniére, nous obtenons l'Api correspondante
Module shlwapi.dll ( Index 0x02 )
Hash Value |
Dll |
Api Function |
0xD6865BD4 |
shlwapi.dll |
StrStrW |
IV. Les Hashs de Module
la différence est que le hash est calculé à partir du nom du module en unicode
Le premier algorithme n'est pas conçu pour ce cas.
Pour ce cas , nous avons repris directement le code assembleur de la fonction du malware LokiBot. Nous avons mis en dessous la fonction construit
WORD __declspec(naked) CalcHash_LokiBot_MalwareRef_Asm_V1(char* pszPlainText, int dwNumber) { __asm { PUSH EBP MOV EBP,ESP MOV EDX,DWORD PTR SS:[EBP+0x0C] OR ECX,0xFFFFFFFF PUSH ESI MOV ESI,DWORD PTR SS:[EBP+0x08] JMP labeb0 label1: MOVZX EAX,BYTE PTR DS:[ESI] DEC EDX XOR ECX,EAX INC ESI PUSH 8 POP EAX label2: TEST cl,1 JE label3 XOR ECX,0x4358AD54 label3: SHR ECX,1 DEC EAX JNE label2 labeb0: TEST EDX,EDX JNE label1 NOT ECX MOV EAX,ECX POP ESI POP EBP RET } } |
Cela nous permet d'avoir les deux hashs pour les modules ntdll.dll et kernel32.dll.
Dans le cas de LokiBot , il récupére via le PEB les au travers du PEB_LDR_DATA
et en parcourant via la liste "InLoadOrderModuleList"
Nous avons remis un schéma du parcours fait par lokibot pour parcourir les modules.
Nous mettons le calcul fait sur l'algorithme au travers de notre outils.
Nous avons également fait l'extraction des opcodes de la fonction de hash dans l'outils
Cela nous donne le shellcode suivant:
\x55\x8B\xEC\x36\x8B\x55\x0C\x83\xC9\xFF\x56\x36\x8B\x75\x08\xEB \x1B\x3E\x0F\xB6\x06\x4A\x33\xC8\x46\x6A\x08\x58\xF6\xC1\x01\x74 \x06\x81\xF1\x54\xAD\x58\x43\xD1\xE9\x48\x75\xF0\x85\xD2\x75\xE1 \xF7\xD1\x8B\xC1\x5E\x5D\xC3 |
Nous l'avons passer dans notre désassembleur perso X32
Vous pouvez à partir de ses reférences trouvé plusieurs sources et disposer des opcodes de fonction
Comme celle en dessous utilisé pour ne pas utilisé l'API dans le malware
DWORD __declspec(naked)GetImagePatchNameByPEB(void) { __asm { MOV EAX,DWORD PTR FS:[0x00000030] MOV EAX,DWORD PTR[EAX+0x10] MOV EAX,DWORD PTR[EAX+0x3C] RET } } |
V. Conclusions
Il est intéressant de comprendre l'algorithme de hash utilisé par un malware, car il permet également d'avoir une base de recherche dans le code assembleur. De pouvoir effectuer des recherche sur des analyse déjà effectué sur des échantillons
Et aussi ce familiarisé avecl'offusaction et les techniques utilisé.
Il est assez, intéressant de croisé les méthodes et les techniques cela pour cartographier
des malwares utilisant les mêmes blocs de codes.
La reconstruction des fonctions interne vers un language plus évolué comme le C permet de valider
Si le code est bien généré ou si basé sur de l'assembleur.