mercredi 25 novembre 2020

Les hash de LokiBot

 

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. 

 





samedi 20 juin 2020

Analyse par un minidump d'un processus

I.    Introduction

L'intérêt d'un minidump est de disposer le l'ensemble d'une photo de l'ensembles des éléments en mémoire d'un processus en exécution. que ce soit le TEB, PEB , les handles utilisés par le processus. Ainsi que tout la mémoire du processus.

cela permet de faire des recherches dans le processus et de récupérer tous ce qu'il peut utiliser ou stocker pour son fonctionnement

Exemple qui revient souvent et l'utilisation de ce format de fichier par Mimikatz

Rappelons brièvement le principe utilisé par Mimikatz , effectue un Minidump à distance sur machine sur le processus lsass (  Local Security Authority SubSystem )

Car c’est dans ce processus que se trouvent les différents ou SSP(Security Service Providers) gérant les différents types d’authentification. Pour des raisons pratiques, les identifiants entrés par un utilisateur sont très souvent enregistrés dans l’un de ces blocs pour qu’il n’ait pas à les entrer une nouvelle fois quelques secondes ou minutes plus tard.

En effectuant un minidump sur ce processus , Mimikatz obtient une photo mémoire du processus. Et donc tous les éléments. Cela lui permet ensuite extraire de la mémoire les hachs NTLM des credentials ou tous simplement de transmettre la chaîne de hachage exacte à l’ordinateur cible pour se connecter. les hackeurs n’ont même pas besoin de craquer le mot de passe, il leur suffit d’utiliser la chaîne de hachage pour accéder à la cible.

Mais ce n'est pas cela qui nous intéresse ici, nous souhaitons expliquer le format des minidump pour permettre son utilisation dans l'analyse de Malware et l'extraction d'information des processus analysé. Par exemple cela permet d'avoir le code finale après dépaquetage en mémoire.


II.    Dumper la mémoire d'un processus

 

Il existe plusieurs techniques permettant de dumper le processus.

La plus simple et graphiquement, on peut passer par le gestionnaire de tâches afin de créer un "fichier de vidage":

Ce qui créera le fichier mindump dans le répertoire

c:\\Users\%USERNAME%\AppData\local\Temp

Nous pouvons également crée le minidump via l'outil "procdump.exe" de SysInternals.

On pourra obtenir le minidump d'un processus au travers de son PID de cette manière:

procdump.exe -ma <PID> C:\MyDumpSample

dans note exemple cela donne comme le pid de notre processus est 4916 pour le "simple2.exe"

procdump.exe -ma 4916 C:\MyDumpSample

Un vidage peut également être créé à l'aide de l'api MiniDumpWriteDump

Vous trouverez plusieurs exemples de code en C++ sur le web. Nous mettons quelques liens

http://ntcoder.com/bab/2014/10/14/how-to-create-full-memory-dumps-using-minidumpwritedump/

https://ired.team/offensive-security/credential-access-and-credential-dumping/dumping-lsass-passwords-without-mimikatz-minidumpwritedump-av-signature-bypass

 Nous avons également une tools perso (EzMiniDumpCreator.exe) permettant d'effectuer la création de minidump soit en pointant le programme via une cible comme Spy++, soit en sélectionnant via la liste des processus en cours.

Dans notre exemple le processus ciblé est sample2.exe qui est une boite de dialogue écrit en assembleur via MASM32. Nous avons prise ce processus car il est épuré au maximum et donc l'explication sera plus simple pour la recherche des blocs mémoire et la structuration sera plus réduite dans le Minidump.


Vous pouvez aussi effectué un minidump sans passer par un programme tiers sur une machine cible.

Car comme le gestionnaire de tâches par défaut à la fonctionnalité pour effectuer un vidage de processus. Elle est accessible via sa dll  (comscvs.dll ). Dans cette dll , il y a la fonction exporté "MiniDump"

Note : l'appel de la fonction exportée MiniDump de comsvcs.dll, elle même ne fait que appeller l'API  "MiniDumpWriteDump" utilisé par les outils cité.

Ce qui rend cette technique comscvs.dll pratique, c'est qu'un vidage peut être créé directement à partir de la ligne de commande, sans avoir à cliquer sur les contrôles de l'interface graphique du gestionnaire de tache et surtout ne nécessite pas d'outil présent sur le poste.

il sera aussi possible d'effectuer un dump mémoire via la DLL comsvcs.dll:

rundll32.exe c:\windows\System32\comsvcs.dll, MiniDump <PID>  C:\\file.dmp full

Dans notre exemple cela donne ma ligne de commande suivant:

 

rundll32.exe c:\\windows\\System32\\comsvcs.dll, MiniDump 4916 C:\\MyDumpSample\\Sample2.dmp full

 


Maintenant que vous pouvez effectué des minidump, nous allons rentré dans la partie intéressante.

III.    Lecture d'un minidump et Analyse

Nous disposons maintenant d'un dump valide de la mémoire du processus sample2.exe

Vous pouvez utiliser l'outil "Minidump Explorer" qui est disponible en téléchargement à l'url suivant: 

https://archive.codeplex.com/?p=minidumps

Nous avons passer notre mindump crée de simple2.exe via cette outil. Il permet de voir la structure du fichier. Vous retrouvez les informations sur la pile en mémoire , la pile d'exécution et les threads

ainsi que le code assembleur et les pages mémoire ou les informations sur les modules

Il y a également le TEB et le PEB du processus.

Voici une capture écran montrant la partie des page mémoire inclus dans notre MiniDump avec l'outil












Il existe d'autre tools comme "BlueScreenView" de nirsoft , il est disponible à l'url suivante:

https://www.nirsoft.net/utils/blue_screen_view.html

















Nous avons notre propre tools d'analyse des MiniDump "EzMiniDumpAnalyzer" , cette outil avait été conçu pour permettre d'extraire le code assembleur après dépaquetage du code par le malware.

Il permet aussi de disposer des chaînes en mémoire.

IV.    Structure d'un Minidump

 Le format du fichier minidump est composant en premier d'une structure Header qui est suivi par  N structures décrivant la localisation des différentes structure possible référencent les données contenues. Chaque structure décrit les éléments propre et aussi l'emplacement du bloc de data le correspondant dans le fichier au travers d'un offset de démarrage de la zone

Nous avons crée une représentation graphique du fichier .dmp en dessous:


Tout d'abord, les 32 premiers octets du fichier sont l'en-tête du fichier Minidump.

Il contient l'identification permettant propre au fichier minidump, la version du format, la somme de contrôle, l'horodatage et certains signes. La structure des données est la suivante:

typedef struct _MINIDUMP_HEADER {
  DWORD Signature;
  DWORD Version;
  DWORD NumberOfStreams;
  DWORD StreamDirectoryRva;   //RVA (relative virtual address)
  DWORD CheckSum;
  union {
    DWORD Reserved;
    DWORD TimeDateStamp;
  };
  DWORD64 Flags;
} MINIDUMP_HEADER, *PMINIDUMP_HEADER;

Nous avons également la représentation en mode TreeView du fichier au travers notre outils

Cela vous permet de voir la partie signature et également la date décodé de la prise du dump














Nous allons nous intéressé à la partie mémoire contenu dans le dump. Cela permet par exemple d'avoir le code assembleur après qu'il est subit le dépaquetage en mémoire.

Dans notre exemple étant un programme basic, il y a pas de packer. 

On peut quand même voir le parcours dans la mémoire du dump de notre Sample2.exe.  Le programme étant chargé à l'addresse 0x00400000 et la section ".text" en 0x00401000













Nous avons donc bien dans le dump le code et les variables ou les chaînes de texte





























Qui représente bien les chaînes du binaire comme on le voir avec notre outils de lecture mémoire d'un processus en cours.
















V.    L'utilisation dans le monde des malwares

Nous venons de voir que au travers d'un minidump d'un processus, nous avons une photo de l'ensemble du processus . C'est grâce que l'on peu extraire des credentials comme différent logiciel font "Mimikatz" ou sa variante python "pypykatz" qui à partir des blocs mémoires contenu dans le dump du processus lsass ( Local Security Authority SubSystem ) extraire les identifiant des utilisateurs connectés.

Mais au final, ce n'est que de l'extraction des informations de la mémoire qui peu être effectué également par un programme malveillant en intégrant dans son code la mécanique cité sans avoir besoin de passer par un dump. L'important étant de connaître ou ce situe les données en mémoire et comme les rendre lisible ou exploitable

Tous simplement par force de sa notoriété, les processus comme Minikatz ou même la demande de dump sur le processus lsass fait avec l'outil microsoft "ProcDump" son vu comme des comportement anormal par Windows Defender ou MalwareByte et le résultat et qu'il supprime le fichier générer du minidump.

le code source étant disponible de Mimikatz et semble évident qu'il sera porté dans des malware ou des parties conceptuel comme la recherche des secrets

Il devient donc évidant que les programmes doivent etre attentif à la neutralisation des informations persistante en mémoire lors de leurs codages. Cela ne ce limite pas uniquement à l'authentification primaire. Mais également identique pour es authentification secondaire au sein d'application métier ou sensible.

VI.    Conclusions

 

Il est intéressant de comprendre le format d'un Minidump, car il permet également de voir les éléments persistant en mémoire qui ne devrait pas resté présent

et donc les programmateurs du logiciel cible. On des bugs de sécurité par le fait de la persistance d'information qui ne devrait pas l'être s'il elle ne sont plus neccessaire après utilisation par le logiciel concerné.

En générale, après utilisation d'une donnée critique ou sensible celle-ci devrait être supprimer de la mémoire. Mais cela est à la charge du développeur qui n'est pas toujours au fait des mécanismes pour mettre celle-ci en évidence dans l'analyse mémoire des processus.

l'exemple de Mimikatz est parlant de lui-même, il ce retrouve utilisé par des malware comme NotPetya

NotPetya utilise Mimikatz pour extraits des informations d'identifications du processus lsass.exe. Après l'extraction, les informations d'identification sont transmises à PsExec ou à WMIC pour la propagation du malware au sein du réseau.

Il est assez, intéressant de croisé les méthodes et les techniques cela pour cartographier les outils du monde du pentest avec les malwares.

Nous espérons que ce petit exemple sur le stockage mémoire des processus dans un format standard le Minidump, vous a permis de comprendre l'intérêt pour l'analyse des malwares et aussi l'analyse des logiciels que vous développé pour mieux ciblé les informations qu'il ne devrait pas être en mémoire en persistant.

Car des que vous avez cette photo de la mémoire d'un malware, votre analyse sera plus simple. Et il est bon de construire ses propres outils et pas ce contenté des tools existantes pour scanné les blocs mémoires ou effectué recherche de séquence particulière. Cela permet aussi d'automatisé la recherche automatique par des jeux de test d'information qu'il ne devrait pas être persistante.