10/06/2011

Vous reprendrez bien un peu de RE ?

Introduction

Après la defcon, j'avais de grosse envie de continuer à reverse des choses (en l'occurence des binaires win32), j'ai donc voulu alller sur le site crackmes.de, mais malheuresement le site est indisponible actuellement.
Je décide donc d'aller plus loin et me pencher sur un malware, chose que j'ai déjà faite mais sur un blog non-officiel.
Je vais donc comme à mes habitudes sur le site malwaredomainlist.com et visite un domaine foireux pour récupérer un sample.

Informations

Name : pusk.exe
MD5 (pusk.exe) = 76e6e91590b47eba7f13ed164c867999
SHA1 (pusk.exe) = 833312a8b90851e68b75dbb6f1532b64df1e15fa
SHA256 (pusk.exe) = b05df025e7833f99691b019f8ee4656858cc721daa052ba26085be0d0b49d7ef

Break it

Première chose à faire c'est regarder si l'éxécutable est packé, pour ca on sort Peid :

pusk_peid

Peid ne détecte rien, de plus la table d'IAT (Import Adress Table) bronche, tout du moins pas d'entrées vers GetProcAdress, LoadLibrary ...
Mais en regardant les strings présentes dans le binaire, on voit des "kernel32.dll", "ntdll.dll".
Je décide donc d'étudier le code de plu près avec le disas.
Je me rends compte qu'il decrypt un nouveau PE dans un zone alloué au préalable :

pusk_valid_pe

On sort lordPe et on va dump cette zone, et essayer de reconstruire le pe :

pusk_lordpe

Si on avait voulu travailler avec ce dump, il aurait fallu éditer pas mal de choses(PeHEader, Sections...), mais j'ai juste dump pour le faire manger à Peid et voir si il me détectait quelque chose : Non.

En regardant le code de plus près, on peut voir ceci : ( image avec commentaire )

pusk_virtual

On regarde le memory map :

pusk_before_after

Il a effectivement changee l'accés de pas mal de zone mémoire qui lui sont propres.

On peut émettre l'hypothèse qu'il va re-unpack quelque chose dans cette zone étant donné qu'il a memset tout à 0x00.
On regarde le code plus loin et on voit un jump :

00A4137C    83C4 28         ADD ESP,28
00A4137F    83C4 08         ADD ESP,8
00A41382  - FF25 1C309700   JMP DWORD PTR DS:[40301C]                ; pusk.006631D0
00A41388    33D2            XOR EDX,EDX
00A4138A  ^ 0F85 B7FEFFFF   JNZ 00A41247

Qui nous fait tomber sur :

pusk_push_ad

Hmm ca sauve tous nos registres (UPX Like ?), bah on descend dans le code et chercher un POPAD et un jmp :

pusk_pop_ad

Donc le real oep serait en "2634", de plus on voit des strings ASCII plutot intéressante :

"adw: start"
"adw: license self delete"
"adw: lang self delete"
"adw: install"

On va deja dump le process, fix l'IAT avec ImportRec et travailler sur ca ( je vais pas expliquer la tache, un paquet de tuto traite de ce sujet ).

Au tout dÉ le binaire va créer un thread pour la routine en 00602612 :

00602612    68 84966000     PUSH dump_.00609684              ; ASCII "adw: start def block thread"
00602617    E8 CA2B0000     CALL dump_.006051E6
0060261C    59              POP ECX
0060261D    68 6C966000     PUSH dump_.0060966C              ; UNICODE "MSASCui.exe"
00602622    E8 B1200000     CALL dump_.006046D8
00602627    68 D0070000     PUSH 7D0
0060262C    FF15 E0606000   CALL DWORD PTR DS:[<&kernel32.Sleep>]    ; kernel32.Sleep
00602632  ^ EB E9           JMP SHORT dump_.0060261D

pusk_thread

Ce pauvre thread va juste checker si le programme "MSACui.exe" fait partie de la liste des process (routine 6046d8), et sleep pendant 2000 millisecondes, puis reboucle, ansi de suite.

Pour l'instant je vais partir sur la routine adw: install, ou l'on peut remarquer des choses fun :

00601FDC  |.  50            PUSH EAX
00601FDD  |.  68 80886000   PUSH dump_.00608880                      ;  UNICODE "ElCo]N}BMG"
00601FE2  |.  E8 621E0000   CALL dump_.00603E49
00601FE7  |.  8D85 54FFFFFF LEA EAX,DWORD PTR SS:[EBP-AC]
00601FED  |.  68 18956000   PUSH dump_.00609518                      ; /S2 = ".exe"
00601FF2  |.  50            PUSH EAX                                 ; |S1
00601FF3  |.  FF15 A4616000 CALL DWORD PTR DS:[<&shlwapi.StrCatW>]   ; \StrCatW

La routine 00603e49 est une simple routine pour decrypt les chaines (XOR 4), jai donc récupéré toutes les chaines du binaires et écrit un script python :

dump_8080 = "ElCo]N}BMG"

unknow = ["WkbpsevaXImgvkwkbpXSmj`kswXGqvvajpRavwmkjXTkhmgmawXW}wpai", "*a|a",
          "lppt>++!w+!w+!w)`mvagp",
          "E`kfa[Bhewl[The}av*a|a","T5oEhImC6Of3B~T1pI5UFM2@WW=6g75Etcno=hRO",
          "ghmgokh`*kvc?waevglfvae`*kvc", "Wkbpseva",
          "<7e1b<7f)1ee3)0be3)ffb1)27<6=e``6=2a",
          ".A@W*p|p", "Vjcqrdw`YHlfwjvjcqYLkq`wk`q%@}uijw`wYAjrkijda",
          "Vjcqrdw`YHlfwjvjcqYRlkajrvYFpww`kqS`wvljkYUjilfl`vYDqqdfmh`kqv",
          "Vjcqrdw`YHlfwjvjcqYRlkajrvYFpww`kqS`wvljkYUjilfl`vYDvvjfldqljkv",
          "*~mt?*vev?*jbk?*p|p?*a|a?*fep?*gki?*gi`?*vac?*iwm?*lpi?*lpih?*cmb?*fit?*ntc?*erm?*itc?*itac?*ikr?*it",
          "Fm`fn@}`Vlbkdqpw`v", "Vds`_jk`Lkcjwhdqljk", "IjrWlvnCli`Q|u`v",
          "lppt>++!w+040*tlt;p}ta9wpepw", "ebbm`9!w""wqfm`9!w""esko",
          "waevglehmoa*kvc?ghmgonegowkjrmhha*kvc?waevglepikwtlava*kvc?waevglfacej*kvc?waevglejp*kvc",
          "E`kfa[Bhewl[The}av*a|a",
          "<2a<e0=1)713g)073g)f2a=)57a313fbefef",
          "31be7<f3)<f=0)0==1)e`76)16a=7<<23=10",
          "`g52af7g)a4b2)002b)<`63)=56615b<a2`e"]


def decrypt(ch):
    name = ""
    for c in ch:
        name += chr(ord(c) ^ 4)
    print "Name = " + name
        


decrypt(dump_8080)
for val in unknow:
    decrypt(val)

Voici l'output :

Name = AhGkYJyFIC
Name = Software\Microsoft\Windows\CurrentVersion\Policies\System
Name = .exe
Name = http://%s/%s/%s-direct
Name = Adobe_Flash_Player.exe
Name = P1kAlMiG2Kb7FzP5tM1QBI6DSS92c31Apgjk9lVK
Name = clickold.org;searchbread.org
Name = Software
Name = 83a5f83b-5aa7-4fa7-bbf5-63829add296e
Name = *EDS.txt
Name = Rnguv`sd]Lhbsnrngu]Houdsodu!Dyqmnsds]Envomn`e
Name = Rnguv`sd]Lhbsnrngu]Vhoenvr]BtssdouWdsrhno]Qnmhbhdr]@uu`bildour
Name = Rnguv`sd]Lhbsnrngu]Vhoenvr]BtssdouWdsrhno]Qnmhbhdr]@rrnbh`uhnor
Name = .zip;.rar;.nfo;.txt;.exe;.bat;.com;.cmd;.reg;.msi;.htm;.html;.gif;.bmp;.jpg;.avi;.mpg;.mpeg;.mov;.mp
Name = BidbjDydRhfo`utsdr
Name = R`wd[nodHognsl`uhno
Name = MnvShrjGhmdUxqdr
Name = http://%s/404.php?type=stats
Name = affid=%ssubid=%sawok
Name = searchalike.org;clickjacksonville.org;searchatmosphere.org;searchbegan.org;searchant.org
Name = Adobe_Flash_Player.exe
Name = 86e8a495-357c-437c-b6e9-13e757bfabab
Name = 75fa38b7-8b94-4995-ad32-52e938867954
Name = dc16eb3c-e0f6-446f-8d27-912251f8e6da

On peut y voir en premier le nom de l'éxecutable qui va étre crée, des noms de domaines, une clef de registre, des urls ... etc.
Next :
La routine en 0060485C va simplement disable le task_manager, stack call de advapi32.RegSetValueExW

pusk_disable_task.png

On regarde aussi la routine de crétion ( plutot recopie ) car c'est exactement le meme binaire qui est copiée : ( disas commenté)

00602157  |.  FF15 84616000 CALL DWORD PTR DS:[<&shell32.SHGetSpecialFol>;  shell32.SHGetSpecialFolderPathW
0060215D  |.  8D85 D8FCFFFF LEA EAX,DWORD PTR SS:[EBP-328]
00602163  |.  50            PUSH EAX                                     ; /\Path = "C:\Documents and Settings\All Users\Application Data"
00602164  |.  FF15 A8616000 CALL DWORD PTR DS:[<&shlwapi.PathAddBackslas>; \PathAddBackslashW
0060216A  |.  8D85 54FFFFFF LEA EAX,DWORD PTR SS:[EBP-AC]
00602170  |.  50            PUSH EAX                                     ; /S2 = "AhGkYJyFIC.exe"
00602171  |.  8D85 D8FCFFFF LEA EAX,DWORD PTR SS:[EBP-328]               ; |
00602177  |.  50            PUSH EAX                                     ; |S1 = "C:\Documents and Settings\All Users\Application Data\"
00602178  |.  FF15 A4616000 CALL DWORD PTR DS:[<&shlwapi.StrCatW>]       ; \StrCatW
0060217E  |.  8D85 D8FCFFFF LEA EAX,DWORD PTR SS:[EBP-328]
00602184  |.  56            PUSH ESI                                     ; /FailIfExists = FALSE
00602185  |.  50            PUSH EAX                                     ; |NewFileName = "C:\Documents and Settings\All Users\Application Data\AhGkYJyFIC.exe"
00602186  |.  8D85 D0FAFFFF LEA EAX,DWORD PTR SS:[EBP-530]               ; |
0060218C  |.  50            PUSH EAX                                     ; |ExistingFileName = "C:\Documents and Settings\analys\My Documents\T",E9,"l",E9,"chargements\pusk\dump_.exe"
0060218D  |.  FF15 E8606000 CALL DWORD PTR DS:[<&kernel32.CopyFileW>]    ; \CopyFileW
00602193  |.  6A 05         PUSH 5                                       ; /IsShown = 5
00602195  |.  56            PUSH ESI                                     ; |DefDir = NULL
00602196  |.  8D85 D8FCFFFF LEA EAX,DWORD PTR SS:[EBP-328]               ; |
0060219C  |.  56            PUSH ESI                                     ; |Parameters = NULL
0060219D  |.  50            PUSH EAX                                     ; |FileName = "C:\Documents and Settings\All Users\Application Data\AhGkYJyFIC.exe"
0060219E  |.  68 78946000   PUSH dump_.00609478                          ; |Operation = "open"
006021A3  |.  56            PUSH ESI                                     ; |hWnd = NULL
006021A4      90            NOP                                          ; \ShellExecuteW

J'ai NOP le call à ShellExecute afin de pouvoir continuer à analyser le binaire.
Car plus loin il va ajouter une valeur dans la RegKey : Software\Microsoft\Windows\CurrentVersion\Run :

0012C6E4   80000001  |hKey = HKEY_CURRENT_USER
0012C6E8   0012C718  |Subkey = "Software\Microsoft\Windows\CurrentVersion\Run"
0012C6EC   0012C6FC  \pHandle = 0012C6FC


0012C6D8   00000060  |hKey = 60
0012C6DC   0012CF74  |ValueName = "AhGkYJyFIC"
0012C6E0   00000000  |Reserved = 0
0012C6E4   00000001  |ValueType = REG_SZ
0012C6E8   0012E22C  |Buffer = 0012E22C
0012C6EC   00000086  \BufSize = 86 (134.)

Ce qui m'interessait de voir surtout après c'était la routine "adw download rootkit", mais malheuresement elle failed :(.
L'URL :

http://searchbread.org/pica1/531-direct

Les domaines ne répondent pas c'est dommage. Pareil pour la routine "adw download exe"...
On continue et on aboutit donc sur la routine "self delete" :

00602707  |> \68 08986000   PUSH dump_.00609808                                         ;  ASCII "adw: self delete"
0060270C  |.  E8 D52A0000   CALL dump_.006051E6
00602711  |.  59            POP ECX
00602712  |.  E8 7F2B0000   CALL dump_.00605296
00602717  |.  E9 D7010000   JMP dump_.006028F3

La routine 605296 delete le fichier et ensuite ExitProcess tout le code qui suit est obsolète.

Bon maitenant on peut bosser sur l'autre binaire.

AhGkYJyFIC.exe

MD5 (AhGkYJyFIC.exe) = 865ea9c1a3fbd1f089749951004b39aa
SHA1 (AhGkYJyFIC.exe) = 9162235f005d7b256d9034201799cdeb9731c14f
SHA256 (AhGkYJyFIC.exe) = 2c7cf2452d1a3f37a9985e7dfdbe2b349e2d5ee4755f5f14460279855c6d882e

On peut remarquer que nous n'avons pas la meme empreinte qu'au départ avec "pusk.exe".
L'unpacking se passe exactement de la meme maniere que pour le précédent binaire.
J'ai omis une chose lors de ma première analyse, une routine qui teste si son nom de process est "AhGkYJyFIC.exe" si c'est le cas on part sur la routine "adw: work"

006026AF  |> \E8 07FBFFFF   CALL dump_.006021BB
006026B4  |.  85C0          TEST EAX,EAX
006026B6  |.  75 64         JNZ SHORT dump_.0060271C
.....
0060271C  |> \68 FC976000   PUSH dump_.006097FC                      ;  ASCII "adw: work"

Dans le disas on voit plusieurs call à CreateThread, 2 routines sont importantes à voir :

006022AF

Crétion d'un fichier temporaire extrait des ressources :

pusk_14081828

On étudiera ce fichier aprés, c'est le fakeAV :]

00603785

Utilisation de l'éxecutable attrib.exe (man page) sur chacun des fichiers du disque dur, afin de les rendre tous "caché".
Et le pourquoi c'est que le programme en lui meme va modifier des clefs de registre qui changeront la visibilité de chacun des fichiers :
"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\Folder\Hidden\SHOWALL" -> "CheckedValue" -> "0".

14081828.exe

Voici le fakeAV que nous attendions tant :

pusk_fakeav

En fait à partir de là, la partie est gagné en faisant un simple strings sur le binaire on trouvait la clef pour se register.

pusk_register

Une fois le logiciel register, ca va restaurer comme il faut les clefs de registre, le wallpaper, et rapeller attribute.exe sur tous les fichiers du disque.
Et ouvrir notepad avec le message suivant :

Thank you for your purchase, Windows XP Recovery!
Your activation code: 8475082234984902023718742058948
EDS URL: http://www.edsawake.org/customers/dl/Recovery.exe
Contact us through Help&Support section in the Windows XP Recovery menu or by phone +1.877.2820139

Voilà c'est la fin de cette article sur une occupation lorsque crackmes.de n'est pas disponible.