Aspack manual unpacking

décembre 6, 2014

En fouillant le sombre merdier présent sur mon bureau, je suis tombé sur un vieux disque dur IDE contenant un crackme qui m’avait été envoyé à l’époque par une espèce de maboule que j’avais rencontré sur IRC #cracking. Celui ci avait la particularité d’être packé par ‘ASPACK’…

Je tiens a préciser que j’ai  effectué l’unpacking d’aspack sur un Windows 7 32bits. Il est important de préciser que sur une plateforme 64bits, les choses se compliquent vis-à-vis des tools à utiliser. Pensez donc à faire votre reverse engineering sur une plateforme 32bits (vmware workstation est votre ami.)

En reverse engineering, le bon réflexe est de dégainer PEid avant de sortir Ollydebug ou encore IDA . Cela nous permet d’éviter de perdre trop de temps. Même si parfois PEid peuy nous induire en erreur, il reste une valeur sûre. Par ailleurs, si nous n’avions pas pu utiliser PEid, il aurait simplement fallu faire sous ollydebug CTRL + B, puis rechercher « aspack » dans la section ASCII.

peid_aspack2.11

ASPACK est un compresseur (packer) d’exécutable 32bits et 64bits, capable de réduire considérablement la taille de l’exécutable (jusqu’à 70%).. ceci afin de réduire la charge réseau lors de l’exécution à distance ou encore du téléchargement, sans modifier les performances de l’exécutable natif. Aspack a également pour objectif d’ajouter une protection basique contre le reverse engineering, par exemple il rend (notamment) impossible la lecture des « strings datas references ». Par ailleurs, à l’inverse du packer UPX, Aspack lui n’est pas gratuit, il faut débourser 34€ pour une licence.

PEiD nous prédit donc une version 2.11. Ce crackme (artur dent#4) n’est pas de première jeunesse mais peu importe nous verrons que de manière générale, ASPACK s’unpack quasiment à l’identique pour toutes ses versions, même les plus récentes, type aspack 2.12, aspack 2.35 .

Dès l’ouverture sous Ollydebug nous sommes avertis : ‘Maybe this file is sefl extracting…’

ollydebug_aspack

Lorsque aspack compresse un exécutable, il greffe ce que l’on appelle un ‘loader’, responsable de la compression du fichier. il ne touche pas aux sections du programme, mais modifie l’original entry-point du programme (OEP) afin que ce soit le loader qui se charge en premier, décompressant le programme en mémoire pour le rendre lisible.

Tout comme pour un exécutable compressé par UPX, nous devons rechercher l’OEP. Pour cela, sous OllyDebug on ouvre l’exécutable, puis CTRL + N :

ollyaspack1

Sur la ligne comprenant le GetProcAddress, nous allons faire un clic droit, puis « Toggle breakpoint on Import ». On F9 afin de lancer l’exécutable. Olly break  dans le kernel ou la fonction que l’on vient de sélectionner est appelée par la routine de décompression du loader ASPACK. Moi j’arrive ici :

je trace avec F8 (43x)  jusqu’à cette ligne :

Alt + B et on remove notre breakpoint.

Pour unpacker du ASPACK il y a une règle à connaitre et qui fonctionne à tous les coups. Il faut trouver l’adresse où le programme est unpacké et il nous indiquera l’Original Entry Point :)

ASPACK reprend systématiquement le schéma suivant :

On va donc faire une recherche en HEX pour trouver cette chaine : Sous ollydebug CTRL + B => 61 75 08 B8 01 et bingo on arrive ici :

on met un bpx sur :

et bingo voila notre OEP :

Il n’y a plus qu’a faire un DUMP. Le dump correspond à copier un programme en mémoire. Utile pour notre exemple, car nous allons copier tout ce qui se trouve en mémoire après l’action du LOADER, ceci afin d’avoir le programme décompressé. Pour cela j’utilise un plugin d’ollydebug développé par Gigapede sur l’openRCE (http://www.openrce.org/downloads/details/108/OllyDump), ce plugin se nomme Ollydump, et il est compatible 64 bits.

Je pose mon breakpoint sur l’adresse du POPAD, c’est à dire 0046A3AA,  F9, la ollybreak, puis plugin >olydump > dump debugged

ollyaspack2Puis DUMP.

 

Désormais, il va falloir s’occuper de l’IAT. Quand une application veut appeler une fonction de l’API, elle n’appelle pas directement la DLL qui va bien : elle utilise plutôt une table locale appelée l’IAT (« Import Address Table ») qui liste les adresses des fonctions de toutes les DLL utilisées par l’application. L’IAT est donc une table d’indirections qui permet de « lier » l’exécutable aux différentes DLL du système.

Pour importer IAT, nous allons tout d’abord lancer le crackme packé, puis IMPrec (1.7e pour ma part). On sélectionne notre « active process », puis on modifie OEP sous IAT infos needed. Encore une fois, on indique 584F0 (ce qui correspond à notre OEP 4584f0 – 40000) puis on clique sur IAT autosearch, IMPrec nous indique qu’il a trouvé quelque chose. On fait un GET imports , IMPrec se charge d’importer les fonctions nécessaires à l’exécutable. Reste à faire maintenant un FIX DUMP, on sélectionne notre DUMP précédent, et OK.  IMPrec se charge de reconstruire notre IAT. :-)

On relance PEiD et on analyse à nouveau notre dump_.exe .. et là ..surprise, il nous indique : Borland Delphi 4.0 – 5.0 Victoire ! l’exécutable est UNPACKED ;-)

On s’endort pas, ce n’est pas encore fini. Il faut maintenant passer au reverse engineering du crackme unpacké.
On dégaine à nouveau Ollydebug, et on regarde les All textes strings reference on voit un « Well done Cracker » qui nous amène ici :

C’est bon signe .  Regardons l’ensemble de la routine de calcul du serial afin de la décortiquer :

bon, explication du merdier :

prend la longueur du nom et la compare à Zero,

prend la longueur du serial et la compare à zero

concernant la routine de génération du serial, en prenant l’hypothèse ou je mets ‘thomas’ comme nom :

Résumons donc encore une fois cette routine :

– chaque lettre du nom est additionnée, pour le nom ‘thomas’ = 6
– il prend la première lettre du nom dans sa valeur HEXADECIMALE = 74
– Divise cette valeur par le nombre de lettres composant le nom = 74/6 = 13 (toujours en hexa)
– ensuite il reprend 74 qu’il divise par 2² = 1D
– multiplie 13 par 1D = 227
– Reprend a nouveau 74 et le divise par 0A = 0B
et pour terminer il divise 227 par ce 0B = 32 en HEXA et 50 en DECIMALE

et ce sur chaque lettre, ce qui donne pour thomas : 504444484248

mais c’est pas fini completement. En effet :

ollyaspack3

 

de chaque coté de notre serial calculé, il rajoute ceci, ce qui donne pour notre serial calculé :

ADCM4-504444484248-YEAH!

bingo !