Le Droppeur du jour, label231486.pdf – Part 2

Suite de l’analyse de la facture de chez DHL :) On le dépacke !

Le dit sample est dispo dans AvCaesar chez Malware.lu mais on n’y apprend pas grand chose de plus. A première vue, on n’arrivera pas a dépacker en statique. (Enfin pas moi quoi). Que ce soit radare ou Ida c’est mal partis.

Screen Shot 2014-05-17 at 6.20.04 Voyons comment on peut louvoyer pour dépacker le bignou avec OllyDbg dans une VM sous Fusion. Si quelqu’un a des TIPs pour aller encore plus vite, je suis preneur ! En analysant la table d’import on tombe sur une ou deux fonctions chelou. C’est d’ailleurs étonnant qu’il y ait autant de fonctions déclarées pour un truc packé.

Donc je le renomme en 2.exe comme le veut le précédent batch au cas ou et  je le charge dans Olly. Là on met un breakpoint dans kernel32.dll sur les fonctions habituelles.

(Pour breaker on se rappelle, View > Executable Modules > Mickey Bouton Droit > Show Name > F2 pour breaker) Screen Shot 2014-05-17 at 6.44.34 En plus de cela à coté un Russinovich Process monitor afin de récolter les potentielles lectures/écriture dans la registry et/ou fichiers. Et c’est partis. Screen Shot 2014-05-17 at 7.04.23 Cela break en 0x422477 à l’appel à VirtualAlloc et un nouveau segment en 0x33000 est alloué en Read Write Execute. Coté registry de l’étrange, 200 clef de cet acabit on été testée. pas une n’a de sens.

A partir de là, (Snapshot vmware !!)  et je vais lancer le mode trace de demander en plus à Olly de breaker quand il devra executer quelque chose dans le range nouvellement alloué. (ctrl-T puis hit trace dans «Trace») Screen Shot 2014-05-17 at 7.12.53   Quand enfin olly break, dans ce nouveau segment, on se dit qu’on est pas sortis du bois. nous voici dans le stage2 du packeur, une succession de “une a deux instructions, jump” bref du code spaghetti. Petit example remis dans l’ordre :

Bref… c’est pas humain a suivre. Donc on fait le contraire, je trace et je demande à Olly de s’arrêter si on sort du segment avec le code spaghetti. Screen Shot 2014-05-17 at 7.32.07 Et je relance le hit trace. Et là PAF… on sombre dans l’étrange… Packer/Thanat0s 1-0 !… Screen Shot 2014-05-17 at 7.34.23 Là on apprend plein de chose; Premièrement Olly se plain qu’on lui à changé un breakpoint par un 0x00. Normalement le breakpoint software alias l’instruction Int3 , c’est 0xCC en hexa et il est posé en lieu et place de l’instruction que l’on veut arrêter. Ca c’est le signe que notre stage2 chipote dans le code. Amis polymorphes bonjour. Donc il va falloir faire gaffe avec les breakpoint software.

En plus le code tripoté est pas dans le segment que nous suivons mais dans le segment 0x400000 bref là ou il y avait le code loadé initialement. Cela veut dire que le code original de l’executable est remplacé.

Ensuite, l’EIP est arrivé en 0x7FFDE000 qui l’addresse notre PEB, le process environnement bloc, c’est un bout de mémoire avec  une structure certes essentielle mais qui n’est absolument pas supposé être exécutée. Ca n’a pas de sens !

Coté registry cela comment à devenir compréhensible. Il semblerai que l’on soit dans les tests offensifs. Le packer cherche NOD32. Etonnant de la part d’un fichier issus d’un spam qui dit être déjà passé par cet antivirus, n’en doutons pas c’est surement pour nous éviter un second et inutile test :)

Quoi qu’il en soit.. Il a gagné, l’exe va au crash. Déjà, voyons ou s’est passé cet read dans la registry à la recherche de l’antivirus. Pour cela bonne nouvelle Russinovich sauve l’état de la stack à l’appel de la fonction le lecture de la clef de registre. Screen Shot 2014-05-17 at 8.09.54 Après l’appel à ADVAPI32 pour lire la registry le programme est supposé retourner en 0x33b5b il y a donc fort à parier que l’instruction de devant c’est notre fameux call. Et effectivement si on regarde le code, on tombe sur un call EAX

On reprend donc notre snapshot vmware, . Dans la mesure ou le code se modifie de partout et qu’étonnamment 0x33B59 tombe en plein milieu de deux instructions on va utiliser un break point hardware ce coup ci (Shift+F5). Screen Shot 2014-05-17 at 8.26.08 Et on lance, cela confirme que c’est bien là qu’il faut breaker si on veut éviter le test avec node 32. Petit truc, en examinant un peut plus haut la stack on retrouve l’adresse de base de la DLL ADVAPI32. (Struct IMAGE_DOS_HEADER) cela est un bon indicateur que le packer parse lui meme les dll à la recherche des adresse des fonctions et que la table d’import originale n’est qu’un leurre. Screen Shot 2014-05-17 at 8.37.17 Bon, ca c’était pour le fun.. J’ai pas NOD32.

Maintenant gérons notre crash quand il nous a envoyé nous balader sur le PEB. On reprend le snapshot vmware au moment du crash et on va analyser la pile.

Au dessus de 7FFDE00 on retrouve l’offset de retour d’une fonction en 0x401235 et on est passé par la juste avant le crash. Et oui vu qu’il modifie le code, il a réussis son coup le packeur, mais le breakpoint du trace n’a pas fonctionné.  Pas grave on sait où regarder… Regardons la fonction autour de cette adresse.

On reprend notre snapshot, et comme le code se modifie, on break en hardware en 0x401235. Arrivé en 0x40124D tout s’explique. Toute la mamaille entre 0x401235 et 0x40124B sert uniquement à mettre 0x30 dans EAX. Et FS:[0x30] c’est à retenir, cela pointe le PEB. Du coup ce qu’il se passe en fait. C’est un test d’anti debugging. le fameux PEB!BEINGDEBUGGED C’est cela en clair:

Donc si je débugge, il le sent,il pousse l’offset du PEB et jumpe dessus ce qui conduit à mon crash. Il faut donc sauter en 0x401258 pour passer outre l’antidebug. On recommence, snapshot, hdw breakpoint sur 0x401254 et on rebranche avec «bouton droit > New origin here »quand on à la main. 401245 Si on step un peu, on passe par une petite procédure qu’on va retrouver plusieurs fois encore et qui xor un énième pan de mémoire dans le bloc mémoire 0x40000 avec des 0x5E.

Et enfin on retombe sur un peu le même soucis qui conduit au crash, la faute à ce bout de code :

C’est un autre test d’anti debugging. le fameux PEB!NTGLOBALFLAG . arrivé en 0x401208, EBX pointe sur le PEB et  quand on débuggue, les flags HEAP_ENABLE_TAIL_CHECK, HEAP_ENABLE_FREE_CHECK et HEAP_VALIDATE_PARAMETERS sont mis. Du coup on se fait gauler. Il faut jumper en 0x40120F pour bypasser ce test. Petite aparté non primordiale mais classique, quand juste après après avoir re xoré encore un coup un pan de code avec 0x5E  on tombe sur ce genre de code, c’est intéressant.

Ce genre de code est un classique, Voici un exemple typique d’un parseur de EAT qui va s’occuper de chercher l’addresse d’une fonction dans une DLL. cette fonction est appelée avec un hash, ce hash est le nom de la fonction ou chaque lettre est décalée d’un octet et xorée avec ce qu’il y a avant (voir 0x401115 et 0x40118).  Bref c’est une fonction obfusquée qui fait le même travail que GetProcAddress

Il est toujours juteux de breaker sur cette fonction car on peut y apprendre quel sont les fonctions que le packers souhaite utiliser sans oser les déclarer. En breakant sur le mov avant le popad on découvre donc les fonctions :

  • ntdll.NtAllocateVirtualMemory
  • ntdll.NtTerminateProcess

Et maintenant on sait avec quoi il alloue ses pans de mémoire. Le debug continue et on s’arrête désormais (merci olly) au chargement de la DLL msasn1.dll qui est en fait appelée par le chargement de crypt32.dll. Si on prend les calltrace (View > CallStack) dans olly, on découvre que notre loadlibrary est appelé depuis 0x36343d. Fichtre encore un nouveau segment avec du code. Stage 3 ! Screen Shot 2014-05-17 at 16.10.00 Et là on est très heureux, il semblerai que le segment 0x360000 soit enfin le bon. En 0x361000 plein de strings bien claires et du code pile poil en 0x36500. Screen Shot 2014-05-17 at 16.17.02 Bon, on est presque au bout, mais il nous faut juste un entry point propre. Bref s’arrêter au plus tôt dans le code exécuté dans le segment 0x36000. On reprend le dernier snapshot et on ajoute un breakpoint sur le NTAllocateVirtualmemory découvert plus tot. Au terme d’un peu de steeping on arrive enfin au Graal

EDX contient 0x364A00 notre EntryPoint ! Le call Dword[0x401009] d’après contient NTTerminateProcess.

VICTORY !   Au final on sais le dépacker avec ces 3 steps.

  • Mettre 3 hardware Breakpoints en execution qui ne semblent pas n’avoir de sens en 0x401254 et  0x40120b et 0x4010E5
  • On aide à passer les deux anti-debug
  • Au break sur 0x4010E5 on dump le segment pointé par EDX et dont l’entry point est EDX.

Donc je repart depuis le début et je suis ces 3 steps.. ce coup-ci c’est le segment 0x9C0000 qui est alloué pour notre stage 3 (précédemment 0x360000)

Arrivé là on tape un peut dans le code et on assemble un mov edx pour aider a faire marcher le call EDX

Et on dump avec le plugin OllyDumpEX le segment 40000 et 9C4A00 (ici celui pointé par EDX) Dépacké enfin ! On set l’entry point sur notre bidouille.

Screen Shot 2014-05-20 at 1.54.31

Bingo on l’a dépacké le bignou

Allez bientôt on dépècera cet executable.

 

This entry was posted in Malware, Reverse and tagged , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

AlphaOmega Captcha Classica  –  Enter Security Code