Le Packing (for newbies) Part 2

Rappelons nous le dernier post. On était arrivé à la conclusion que notre exécutable était packé (On a d’ailleur a cette occasion appris ce que c’était), mais on patinait dans la choucroute pour le dépacker de façons automatique. On va donc devoir sortir tout l’attirail pour tenter de le dépacker, J’ai nommé IDA pour désassembler et Ollydgb pour débugger et le vénérable LORD_PE pour dumper le processus depuis la ram. Pour une somme modique on peut tout faire avec IDA sur une vaste gamme de systèmes avec des plugins comme IDA_Dumper. Ha l’argent, c’est probablement la raison pour laquelle tout le monde se tourne vers OllyDbg (Enfin pour l’instant en 32Bits uniquement). Il nous faudra aussi d’autres petits tools. Nous y reviendrons plus tard.

Pour s’échauffer on va reprendre notre Hello World packé sous UPX de la partie 1 de cet article et on va se le dé-packer à la main.

Le cas simple “find the Jump”

L’idée est la suivante; Que va faire un packer simple, il va décompresser/déobfusquer le code réel, puis il vas sauter dedans pour l’exécuter. La première méthode dans le cas d’un packer pour newbies est de trouver oû est ce saut, d’y poser un breakpoint, de laisser faire le programme dépackant et quand on arrive à notre breakpoint on dumpe le programme et on crée un nouvel exécutable.

Ouvrons notre hello world upx dans IDA, dés-fois que cela serait simple. Et heureusement oui, UPX c’est bien pour l’apprentissage. Au premier abords ca fait peur. En y regardant plus près, il n’y a qu’une seule fonction. Et on trouve facilement le saut car IDA nous informe qu’au dela de ce saut, le il n’y a pas de programme exécutable (sp-analysis failed). Il n’y a pas encore de programme car le décompresseur n’a pas été lancé. Là c’est facile ida vois bien qu’il n’y a pas de code derrière le “JMP”, mais cela peut être moins évident avec un saut de type “call registre” ou un “ret”.

Upx in IDA

On se met sur la ligne de saut, on appuie sur “space” pour avoir le désassembler en vue liste et on note l’adresse du saut (Ici 0x004076EB).

Ida Jump Upx

Ensuite on ouvre OllyDbg, on charge l’exécutable. On met un point d’arrêt (F2) au même endroit.

Olly Dbg Breakpoint

Voila, le piège est en place, ne reste plus qu’a lancer. Quand Ollydbg rend la main on est devant notre saut, on step d’une instruction (F7) et on se retrouve devant notre code dépacké. On note la valeur d’Eip, ici 0x00401130, c’est là que le vrai programme commence.

Upx Jump address

Il ne reste qu’a dumper le programme, Pour cela on lance notre LORD_PE (Nota il y a plein de soft qui font la même chose, même des plugins OllyDbg le font (ex PE_Dumper) , choisis tes armes camarade).

On sélectionne notre exécutable et on le dump “Full”.

Lord_PE Dump

Là notre LORD_PE fait un truc étonnant dont il faut avoir conscience. Il “Rebuild Import Table”

Lord_PE Export

Apparté, Rebuilding de l’IAT : Dans un executable PE, l’IAT de son nom complet Import Adress Table est un tableau de correspondances pour les fonctions importées (Un appel a une fonction de Kernel32.dll par exemple). Elle contient ce qui doit être importé ainsi que le nom des dites DLL (Pour les amis des ELF on peut considéré cela comme une genre de GOT). C’est indépendant de la version de windows, au démarrage la correspondance fonction vers l’adresse de la lib est remise en place. En plus de cela, notre Packer a nettoyé cette IAT avec les fonction que seul lui utilise, une fois dépacké, il faut donc remettre l’IAT en ordre. A la main, on oublie, mais avec le bon tools c’est simple.

Pour plus d’informations sur l’IAT je vous encourage à lire ce lien.

Mais ce n’est pas tout ! Il faut encore changer l’EP, l’Entry Point. C’est a dire l’emplacement en mémoire où va démarrer le programme. Il faut que l’on démarre là où on a finis le dépacking (rapellez vous l’addresse 0x00401130 que l’on a noté ).

On reprend LordPE, on prend l’option PE Editor, on édite l’exécutable que l’on vient de dumper. On change l’Entry Point. La base étant 0x0040000 il suffit de mettre 0x1130 dans la case.

Entry Point

Voila c’est finis, on a retrouvé notre executable “décompréssé”, Avec son code et ses strings en clair.

Malheureusement c’est rarement aussi facile qu’avec UPX.

La méthode ‘Regarde le Tas’

Si le packers commence par sauver la valeur de la pile ou fait un gros PUSHA (haaa ce formidable 32 Bits, il va me manquer). On peut aussi penser à mettre un break point hardware sur la position mémoire de la pile. En se disant, arrivé dans notre code packé, la pile sera revenue à la position initiale. Upx fait aussi comme cela, il est nickel comme exemple cet UPX. Pour faire ceci avec OllyDbg je lance mon programme, je passe le PUSHAD (f7) en step by step, je vais sur la valeur du registre ESP et je l’affiche dans le dump.

pushaddepack

Je selection le word qui se trouve à l’emplacement de ma pile, et j’insère un breakpoint hardware en R/W.

Hardware Breakpoint

Je lance le programme… Et hoo miracle il rend la main dans la fameuse boucle (que l’on connais maintenant) et qui va sauter sur le programme dépacké. il suffit de faire un peu pas à pas jusqu’au saut et on se retrouve là aussi en 0x00401130

stack jump codeA partir de là, Dump, IAT et EP..comme précédemment et c’est bon.

La technique de siY0ug

Mais dans la vraie vie c’est pas toujours aussi rose, même s’il n’y a pas d’anti debugger, on peut errer dans le code pendant des jours à chercher le saut. Par exemple notre facture.exe (Hash 17832c9a78b36c8a3133e2c2e24ebc3b9896763a chez Malware.lu). Il contient 131 fonctions, du code long comme le bras avec utilisation du co-processeur arithmétique, des champs complet de calls dans tous les sens, pas de pusha au début (par contre de la réservation de heap).. Bref… Glups.

facture

Nous voici acculé. Pas de dépackeur tout fait, Trop alambiqué dans IDA. C’est à ce moment là que l’on pleure auprès d’un compagnon de café qui lâche la méthode suivante. Dixit le gaillard (Et c’est pas une tanche coté déssossage) on arrive à dépacker 3/4 des packeur de PE avec du malware dedans. L’idée est la suivante;

On va laisser le malware faire son un-package et on va breaker quand monsieur va faire un appel bien sentis à kernel32. Généralement quand il est en train d’injecter son code dans un autre process (c’est typique pour un malware voir ceci). Actuellement on a vu des packer qui se décompressent dans le même segment mémoire, mais certain se prennent du heap et y sortent carrément un autre executable.

Bon comme çà, ça parait simple, mais ne déconnez pas, faite ceci dans un environnement clos. Une bonne grosse sandbox; Cuckoo, Vmware, au pire un poste dédié.

Si vous ratez le breakpoint, vous êtes poncé, si le dépackeur contient aussi une saloperie,  vous êtes poncé., Si le malware s’attache pas à un process comme vous le pensez, vous êtes poncé; Bref à chaque mauvaise manip, vous êtes poncé.

Reprenons Ollydbg. On ouvre l’exécutable, on demande la fenêtre “Executable Modules” (Alt+E) on sélectionne Kernel32, on fait “show names” (ctrl+N). Devant nous apparaît la fenêtre avec la liste de toutes les fonctions de Kernel32.dll

show names

On cherche “WriteProcessMemory” (Il suffit de taper les premières lettres) et on met en place un breakpoint (F2).

writeprocessmemory

Ensuite , confiant on lance le programme. Quand celui ci rend la main juste avant la fonction. Dans la stack on retrouve les paramètre d’appel à cette fonction, et si on fait “Follow in dump” de l’addresse du “Buffer” on se rend compte que dans ce buffer on est en présence d’un exécutable complet.

executable depacked

Là c’est différent, c’est un programme complet qu’il faudra extraire du dump mémoire. Soyez heureux, pas de IAT et d’EP à tripoter).

Si ça ne va pas avec cette fonction là … On peut essayer les fonctions suivantes

Maintenant extrayons notre exécutable de la mémoire. Sur le dump mémoire sous OllyDbg on fait Bouton droit de la souris => Backup => Create Backup. on se retrouve avec un dump mémoire complet de ce processus. Il suffit de trouver ou commence l’exécutable, et découper. et pour cela, on remercie Zbikowski !!! on cherche les MZ

Pas de bol il y en a un ou deux.. on les essaye plus précis, on a vu dans le dump mémoire que c’était MZ suivis de 0x90 0x00.

Ouf plus que 2 à essayer, Rappelons nous l’original packé était :

Extrayons le premier.  (Note : la valeur pour le tail est +1 par rapport au grep.)

Zut, on est retombé sur l’original.. Allons y pour le second candidat :

Bingo un autre executable !  Allons y.. tentons un strings, somme nous victorieux ?? (Le grep étrange c’est pour n’attraper que les digram les plus utilisé en anglais, ca évite pas mal de strings random)

Et en unicode, y a t’il des strings ?

Pas mal, quel sont maintenant les dll utilisées ?

Ho le support du réseau est arrivé ;) et plein d’autres DLLs qui laissent a penser que le malware est bien juteux

Et bien voila, c’est une victoire il semblerai la bête soit dé-packée. Ne reste plus qu’a l’analyser… Une broutille ;)

Mais ca c’est pour une autre fois.

This entry was posted in 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