Le Packing (For Newbies) Part 1

Il y a quelques temps j’ai reçu un mail m’indiquant un soucis de facturation quelconque  Ce mail contenait, hooo joie, un executable nommé facture.exe tout simplement attaché au mail. Je me suis empressé de regarder la bête :

Vous pouvez retrouver cette bête sur malware.lu sous le hash 17832c9a78b36c8a3133e2c2e24ebc3b9896763a

[MODE PROMO ON] Malware.lu, T’en veux, y en na ! T’en re-veux, il y en re-na ! [MODE PROMO OFF].

A quoi ressemble mon malware

Commençons par savoir ce que c’est. Pas de doutes c’est bien un executable PE (Portable Executable) pour Windows. ;)

$ file facture.exe.malv    
facture.exe.malv: PE32 executable for MS Windows (GUI) Intel 80386 32-bit

Voyons voir avec quels DLLs ce truc est linké pour savoir ce que potentiellement il peut faire :

$ objdump -x facture.exe.malv  | grep Name:
	DLL Name: MSVCRT.dll
	DLL Name: KERNEL32.dll
	DLL Name: USER32.DLL
	DLL Name: GDI32.DLL
	DLL Name: SHELL32.DLL

Ce qui est étonnant c’est qu’il ne semble pas appeller Winsock (généralement WS2_32.dll). Un malware sans support tcp cela ne se fait plus de nos jours. De plus ce genre de trucs par mail c’est généralement un droppeur dont l’unique but est d’installer une autre saloperie downloadée plus loin. Cherchons vraiiiiiiment, peut être charge t’il la dll dynamiquement.

$ strings -a facture.exe.malv | grep -i dll
uxtheme.dll
DllGetVersion
COMCTL32.DLL
msimg32.dll
MSVCRT.dll
KERNEL32.dll
USER32.DLL
GDI32.DLL
SHELL32.DLL

Y a t’il une maigre strings en unicode ?

$ strings -a -el facture.exe.malv  
$

rien, non, rien de rien.

Toujours pas de winsock. Le salaud cache son jeu. Serait t’il packé ?

Mode Mother Knowledge ON…Mode Mother Knowledge ON…Mode Mother Knowledge ON…

Qu’est ce qu’un executable packé Maryse ?

Pour les avides de connaissance (voir son wikipedia). Un exécutable packé est un exécutable contenant un autre exécutable  Cela remonte du temps ou la disquette faisait pas plus de 740Ko. L’idée d’origine de cette aberration est la suivante; j’ai un gros exécutable. Je vais le compresser et autour je met un autre exécutable lanceur qui le décompressera en mémoire et lancera. Cela permet d’avoir un exécutable final plus petit qui fait juste un peut plus de travail au lancement initial.

Packed Exe

Les méchants créateurs de malware l’on vite compris. Non seulement ca compresse mais surtout l’autre effet c’est que cela offusque l’exécutable principal. Les chaines de caractères n’apparaissent plus en clair dans l’exécutable posé sur le disque. En plus ils peuvent ainsi réutiliser le même malware, si il est détecté un jour, il suffit de changer l’enveloppeur. Et les enveloppeur sont bien chiadés. Fait comme il faut pour perdre toute personne qui tente de les comprendres ou toutes sandbox d’antivirus.

C’est un sport prospère la création de packer, je vous conseille la lecture de cet article (Packers) pour vous rendre compte de la “vastitude” de la chose.

Dans le civil les packers dit “légaux” les plus connus sont UPX et Armadillo. Mais aucuns malware digne de ce nom n’utilise directement ceux ci pour une raison évidente; Ils sont connus, donc facile à dépacker car des tools existent pour ca. Donc les antivirus aussi savent les depacker. Au mieux on trouvera des version UPX trafiquées. Dans le peloton des packer utilisés on trouvera aussi FSG, Aspack, Morphine et Mew.

Allez, ca plait toujours , un petit TP. Packons un “hello world” avec un tools de niveau newbies:

Soit le programme hello.c suivant qui affiche le traditionnel hello world.

#include <stdio.h>

int main ()
{
	printf("hello World !\n");
}

on le compile pour Windows, on le strip (pour virer les infos de debugeage) et on calcule son hash md5

$ i586-mingw32msvc-gcc hello.c -o hello.exe && strip hello.exe 
$ md5sum hello
1d21d9cd12d40bc8f18d6c5cdc428bd3  hello.exe

Notre programme évidemment fonctionne à merveille.

$ wine ./hello.exe 
hello World !

Et si on recherche les chaines de charactères (ici toute chaine ascii de plus de 10 lettres), on retrouve bien notre “hello world” à l’intérieur du binaire.

$ strings -10 -a hello.exe 
!This program cannot be run in DOS mode.
libgcj_s.dll
_Jv_RegisterClasses
hello World !
ExitProcess
GetModuleHandleA
GetProcAddress
SetUnhandledExceptionFilter
__getmainargs
__p__environ
__p__fmode
__set_app_type
KERNEL32.dll
msvcrt.dll

Packons le, évidement son md5 change. Pour tout antivirus bas du front ce serait un ‘autre’ exécutable.

$ upx -9 hello.exe -o hello-upx.exe
                       Ultimate Packer for eXecutables
                          Copyright (C) 1996 - 2010
UPX 3.05        Markus Oberhumer, Laszlo Molnar & John Reiser   Apr 27th 2010

        File size         Ratio      Format      Name
   --------------------   ------   -----------   -----------
      4608 ->      3072   66.67%    win32/pe     hello-upx.exe                 

Packed 1 file.
thanatos@cyanide:~/code/hello$ md5sum hello-upx.exe 
b4d52b91a4d42b2cbe0ff7fde0964b78  hello-upx.exe

Et il marche toujours (C’est un peu le but).

$ wine ./hello-upx.exe 
hello World !

Mais par contre, la chaine “hello world” maintenant compressée dans l’exécutable à disparue :

$ strings -10 -a hello-upx.exe 
!This program cannot be run in DOS mode.
libgcj_s.dll
sterClasses#he
ExitProces
GetModuleHand
d:5ptionFil9
__g'mainarg
KERNEL32.DLL
msvcrt.dll
LoadLibraryA
GetProcAddress
VirtualProtect
VirtualAlloc
VirtualFree
ExitProcess

Alors imaginez maintenant un packer dont le seul but est de cacher le vrai payload au yeux des antivirus, il aura 2 buts dans la vie; Cacher ‘Fortement’ le vrai payload et rendre très compliqué la décompression du vrai exécutable par un être humain ou un antivirus. D’autres malwares (Probablement russes) poussent le vice et utilisent le concept des Matriochka et repackent l’executable déja packé.

Bien sur on vient juste d’effleurer le haut de l’iceberg. Tous les packers ne sortent pas un second exécutable tout propre en mémoire, certains décompressent juste un bout de code sur la heap et sautent dessus. D’autre implémentent une machine virtuelle propriétaire “à la java”, le tout pourris d’antidebugger juste pour le fun. Et là on fait moins le mariole.

Mode Mother Knowledge OFF…Mode Mother Knowledge OFF…Mode Mother Knowledge OFF…

Mais reprenons notre facture.exe.

Yara qui ri !

Maintenant que l’on sait ce qu’est un packer. Comment savoir si notre facture.exe est packé ? Le premier indice, on vient de le voir c’est de regarder les strings et les fonctions importées dans l’exécutable, si le résultat est très maigre pour un gros exécutable, c’est louche.

Le second indice c’est de regarder les segments de l’exécutable. En fonction du packer il peut réveler le packing. Avec UPX par exemple pour notre hello world packé, c’est sans équivoques :

$ objdump hello-upx.exe -h 
Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 UPX0          00006000  00401000  00401000  00000200  2**2
                  CONTENTS, ALLOC, CODE
  1 UPX1          00000800  00407000  00407000  00000200  2**2
                  CONTENTS, ALLOC, LOAD, CODE, DATA
  2 UPX2          00000200  00408000  00408000  00000a00  2**2
                  CONTENTS, ALLOC, LOAD, DATA
SYMBOL TABLE:
no symbols

Les noms des sections sont atypiques et en plus elle se chevauchent (Upx0 et Upx1 commencent à l’offset 200 dans le ficher). Un executable “normal” contient généralement toujours un .text ou .code et un .data. Notre hello world n’échappe pas à la règle:

$ objdump hello.exe -h
Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .text         000005f4  00401000  00401000  00000400  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE, DATA
  1 .data         00000034  00402000  00402000  00000a00  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  2 .rdata        00000034  00403000  00403000  00000c00  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .bss          00000070  00404000  00404000  00000000  2**2
                  ALLOC
  4 .idata        00000214  00405000  00405000  00000e00  2**2
                  CONTENTS, ALLOC, LOAD, DATA
SYMBOL TABLE:
no symbols

Un compilateur “standard” ne sort jamais des clous suivants : ‘.text’, ‘.bss’, ‘.rdata’, ‘.data’, ‘.rsrc’, ‘.edata’, ‘.idata’, ‘.pdata’, ‘.debug’,  ‘.xdata’, ‘.reloc’, ‘.rsrc’, ‘.code’ et ‘.tls’

Qu’en est t’il de notre facture.exe … je dirait pas de bol :

$ objdump facture.exe.malv -h
Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .code         00002137  00401000  00401000  00000400  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .text         000025f4  00404000  00404000  00002600  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  2 .rdata        000000bc  00407000  00407000  00004c00  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .data         00000600  00408000  00408000  00004e00  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  4 .rsrc         0000115c  00409000  00409000  00005400  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
SYMBOL TABLE:
no symbols

Ici malheureusement, le nom des sections semble très normal.

Troisième indice pouvant révéler la présence d’un package (Ne pas perdre le moral), la taille, le type, et l’entropie des sections. Prenons un vrai executable pour comparer; Ce que certain utilisateurs de Vi ou Emac considère eux aussi commun un pure malware, j’ai nommé Notepad.exe. Si c’est un gros exe avec très peu de code et beaucoup de data c’est louche. L’entropie sur une section de code peut révéler la présence d’un exe packé. La différence est flagrante si on fait l’exercice avec un bête UPX.  J’utilise ici un de mes script (dispo dans dans le chall tool) qui doit tout à l’excellente librairie python pe_file

$ peentro.py notepad.exe 
Section	Entropy	Bytes	MD5					Remark
.text	6.28	7	e2c89efc10b642edb8b21d71878e69eb	
.data	0.76	1	347ef5c176ef9739d0e2c9f04346b7d3	
.rsrc	7.37	8	9bce8d34eb3d836c984e8935746d222d	 High Entropy
.reloc	6.43	7	4b0ee59eff3683cc8ee9361119d7e3c6	

$ peentro.py notepadupx.exe 
Section	Entropy	Bytes	MD5					Remark
UPX0	-0.00	0	d41d8cd98f00b204e9800998ecf8427e	Unusual Name.
UPX1	7.89	8	4eee658d2f4753f70343fb613bdd5282	Unusual Name. High Entropy
.rsrc	7.37	8	44e6a801c6d9aaa6588e6829ea11f861	 High Entropy

C’est recta l’entropie de la section UPX1 est élevée (Sur .rsrc pour ressources, (image, icones tout cela, cela peut arriver, ce n’est pas grave)). Un autre exemple avec un packer commercial VmProctect sur un fichier quelquonque.

$ peentro.py Chat.exe 
Section Entropy Bytes Size MD5 Remark 
.text -0.00    0 19764  d41d8cd98f00b204e9800998ecf8427e 
.data -0.00    0 4512   d41d8cd98f00b204e9800998ecf8427e 
.rsrc 3.31     4 2344   a4e53a7b515468a21cb94cfd0b2d24d0 
.vmp0 -0.00    0 62376  d41d8cd98f00b204e9800998ecf8427e Unusal Segment 
.tls -0.00     0 24     620f0b67a91f7f74151bc5be745b7110 
.vmp1 7.90     8 113862 6ae0ced50031e23605f6ac8130bbf0ae Unusal Segment,High Entropy

Idem d’étranges sections et une entropie galopante.  Qu’en est t’il de notre facture.exe ??

$ peentro.py facture.exe.malv 
Section Entropy Bytes   Size    MD5                                     Remark
.code   5.65    6       8503    6d7c8f47c89843bafb8d8a0912730242
.text   6.49    7       9716    5e70fa9623805d69b6e548873c23d37f
.rdata  1.75    2       188     96fdc428b50e1fa15bc8ce78d17a0525
.data   5.29    6       2796    cd00c1734804fcf8f776f8ce3431b129
.rsrc   2.94    3       4444    0b5ae9b8bfbc2ecfcb22c9578e800439

les salaud… on est bien là… rien a redire ! l’entropie ne révèle rien non plus. Un bon exemple ce facture.exe.

Arrivé la, on demande un miracle. C’est là qu’apparaît une nouvelle race d’outils, le détecteur de packing. J’en connais 2, le premier sous windows est Peid (Et il sent le sapin, malgré sa forte réputation), le second, tendance, free, open source et évolutif est Yara. Pour plus d’info sur Yara, je vous conseille la lecture de Misc Nr 65.

$ yara -r packer.yara facture.exe.malv 
PureBasic4xNeilHodgson facture.exe.malv

Mais voila, dans notre cas, le pire qu’il puisse arriver arrive. Yara trouve bien un éventuel nom de Packer (et encore). Normalement on saute de joie et on se tourne vers le tools de dépacking. Car si il existe de nombreux packeur, heureusement il existe aussi de nombreux de-packeurs, (voir http://www.exetools.com/unpackers.htm pour une belle collection). Mais là, j’ai pas la queue d’un dépackeur associé à ce truc. C’est domage car c’est super sympas avec un dépackeur associé.

$ yara  -r packer.yara hello-upx.exe 
UPXv20MarkusLaszloReiser hello-upx.exe
UPXV200V290MarkusOberhumerLaszloMolnarJohnReiser hello-upx.exe
UPX20030XMarkusOberhumerLaszloMolnarJohnReiser hello-upx.exe
UPX290LZMAMarkusOberhumerLaszloMolnarJohnReiser hello-upx.exe

$ upx -d hello-upx.exe 
                       Ultimate Packer for eXecutables
                          Copyright (C) 1996 - 2010
UPX 3.05        Markus Oberhumer, Laszlo Molnar & John Reiser   Apr 27th 2010

        File size         Ratio      Format      Name
   --------------------   ------   -----------   -----------
      4608 <-      3072   66.67%    win32/pe     hello-upx.exe

Unpacked 1 file.

Bon on se démonte pas. On va mettre les doigts dans le cambouis et on va pas lacher et on va le dépacker avec les doigts ce facture.exe.

Mais cela, ca sera au prochain numéro !  …

On résume;
On sait ce qu’est un exe packé et pourquoi
On sait que les antivirus on pas facile !
On sait ce qu’il faut regarder tenter de sentir si c’est packé.
On sait que c’est pas une science exacte.

 

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