lundi 7 novembre 2011

Reversing d'un packer de malware

Bonsoir,

En ce lundi je vais enfin ranimer mon blog un petit peu par une publication (et oui, c'est encore possible). Je pense que vous vous souvenez de l'analyse du malware que je faisais ; par un jeu de circonstances je l'ai arrêté et je n'ai décidé que récemment de reprendre le tuto afin de lui donne une mise en forme correcte et de présenter ce maigre stuff aux yeux des gens, en espérant que quelques uns d'entre vous y trouvent un quelconque intérêt.

Evidemment, comme j'ai écrit cela en début d'année quand je débutais encore en reversing de malware, ça ne va pas être très poussé ; mais j'y présente quelques techniques classiques que l'on retrouve dans certains vx et la majorité des packers de malwares qui pourraient intéresser les gens ne s'étant jamais vraiment penché sur ce genre de choses.

Bref, trêve de blabla, tout est le reste est dans le pdf.
Critiques bienvenues évidemment, positives ou négatives.

Lien ici : http://www.multiupload.com/Z51TI59KFF

EDIT: http://www.multiupload.com/MCN516LF32 // rajout du malware, pass infected

Je terminerai par des remerciements pour ceux qui ont relu ce papier.

Sinon, pour les éventuels intéressés mon keygenme avance toujours à petit pas. J'ai implémenté quelques tricks, j'ai pas mal allégé la todo pour ne pas qu'il soit ennuyeux (l'intérêt étant de keygenner, pas de bypass 15 anti debugs) ; mais je dois réécrire énormément de choses de part les choix que j'ai fait. J'en ai donc pour encore un petit peu de temps, sans compter que je vais devoir certainement me mettre au C pour coder une partie de mon keygenme (qui sera au final comme d'habitude codé en 100% win32 assembly)

Voilà, bonne nuit à tous.

vendredi 22 juillet 2011

Quelques nouvelles

Bonsoir à tous,

Ayant du mal à dormir et réfléchissant plus ou moins sérieusement à l'organisation de mes projets, je me suis dit "Pourquoi ne pas actualiser un peu mon blog ?". Sur ce, voilà le pc rallumé. Alors, comme vous pouvez le constater tout d'abord je ne suis pas mort, même si je suis moins actif (motivé ?) qu'auparavant. Depuis mon dernier tuto sur WJChess 3D je ne faisait plus que du reversing de malwares, jusqu'au début de ce mois où je me suis retrouvé un intérêt pour l'unpacking / keygenning.

Donc, pour ce qui est de mes projets (car je suppose que ma vie ça ne vous intéresse pas, et puis ce n'est pas l'objet de ce blog après tout :p), j'en ai un peu moins en cours (beaucoup deviennent obsolètes au fil du temps).

Commençons par le plus ancien : mon tuto sur le reverse engineering complet d'un malware. Je me suis vite aperçu que c'était une entreprise assez titanesque, donc j'ai plus ou moins mis mon projet en sommeil quand je me suis aperçu que plus j'avancais dans le code plus j'avais de choses à traiter au vu de la complexité du binaire. Le MISC du mois de juin traitant du malware qui faisait l'objet de mon tuto, j'avais complétement abandonné le projet. Finalement, je me suis dit que mon travail pourrait être un minimum intéressant à la publication (enfin je l'espère), il faut donc que je réorganise le tuto & que je fasse les modifications adéquates afin de porter ceci aux yeux du public.

 Ensuite, je me suis mis récemment à commencer à coder mon keygenme 2, mais je crois que je vais enlever quelques tricks sur la todo list sinon personne ne voudra le faire :')
Ca sent encore pas mal de pages de documentations à potasser tout ça...

Enfin, niveau keygenning bah je sors d'une période de type sabbatique, je m'y suis remis récemment en essayant de tâter un peu la v1.3 de WJChess 3D, mais apparemment l'auteur a retenu la leçon (!), la protection a été entièrement revue pour ressembler à quelque chose de type keyfile. C'est facile de la patcher, de réinitialiser le trial (une simple clé créée dans la base de registre), mais comme je cherche à faire des trucs propres j'ai mis l'affaire en standby. Je suis donc sur un autre logiciel avec une protection sympathique : du base64, des similis bignums un peu partout, le tout combiner à pas mal de routines de calcul intermédiaires, dont une utilisant les registres FPU. En gros, la cible parfaite pour un super tuto, pour peu qu'on réussisse à comprendre ce gros bout de code qu'à l'air de représenter la protection.

Bien évidemment, tout ceci est tributaire de ma motivation légendaire, et ayant loupé ma première année (je suis aux rattrapages) à cause d'une passion un peu trop prenante (oui oui, le RE...), je vous garantis encore moins qu'avant des délais corrects, c'est à dire inférieurs à 4 mois ^^.

N'ayant rien à rajouter, je crois que je vais retourner tenter de dormir, et je vous souhaite donc une bonne nuit :)

lundi 1 novembre 2010

Keygenme #1

Bonjour à tous,

Je release enfin mon premier keygenme en ce premier novembre, depuis le temps que je l'avais commencé et que j'en parlais... Le keygenme est publié au nom d'Astral, car je l'avais commencé sous ce nom, bien que maintenant il me semble que le projet de m3at soit mort, et qu'il l'ait laissé tombé. Enfin bref, c'en est ainsi. Je me suis bien amusé à le coder, et j'espère que vous aurez autant de plaisir à le keygenner, car j'ai essayé d'éviter d'en faire un trop "standard", dirai-je.

Je tiens à remercier tous ceux qui ont participé directement ou indirectement à la réalisation de ce projet, et tous ceux qui m'ont soutenu (ils sont trop nombreux à citer ^^).

Toutes remarques et observations sont les bienvenues, ainsi que les signalements de bugs si il en reste ^^.
Le patching n'est pas autorisé, le serial fishing peut être acceptable si vous analysez la routine... ce qui revient à quasiment faire un keygen, ce que j'attends :D

Voici le lien :
http://www.multiupload.com/QJJUJ340SC

EDIT : Merci à Kirjo pour les signalements de bug.

Pour ceux qui sont intéressés, j'ai quelques projets en cours de rédaction : 1 tuto sur asprotect, et 3 articles traitant d'unpacking et de cd-checks. J'espère réussir à tenir mes délais et à en publier au moins un d'ici la fin novembre.

jeudi 9 septembre 2010

Manual Unpacking de PECompact 2.x


Tools : - OllyDbg 1.10 ‘Shadow’ (ou autre version)

- Peid 0.95

- Le plugin OllyDump pour OllyDbg

- ImpRec 1.7c

- OS : testé sous XP et 7.


La cible du jour est un packer, de niveau facile, car il ne fait que compresser le code (on peut compliquer un petit peu en rajoutant des antidebugs dans les options, mais ca n'a pas l'air d'être le cas ici ;). L'arrivée sur l'OEP se fait grâce à un jmp EAX. Je ne vais pas détailler le loader ou quoi que soit, je proposerai simplement ici une méthode pour l’unpacking. Je l’ai trouvé à l’arrache (ayant pris l’habitude de ne plus lire de tuts sur l’unpacking, ou alors seulement sur des packers costauds ;), et donc elle ne sera pas forcément la meilleure (voire même existe-t-elle déjà, ce qui est le plus probable).


Note : Si vous faites l’unpacking sous 7, vous aurez des exceptions supplémentaires dans ntdll, passez les avec Shift+F9. J’ai testé cette méthode sur 4-5 exe protégés par PECompact 2.x, et elle a marché à chaque fois.


Bon, rentrons dans le vif du sujet. Nous allons faire l'unpack sur le logiciel PDF2Word de Bluesquad. On le passe sous Peid, on obtient : PECompact 2.x -> Jeremy Collake


On lance maintenant Olly, on clique sur "Non" à la messagebox qui nous prévient que le code est compressé, et on obtient normalement un EP de cette forme (elle est toujours pareille) :


00401000 MOV EAX,pdf2word.004DD820

00401005 PUSH EAX

00401006 PUSH DWORD PTR FS:[0]

0040100D MOV DWORD PTR FS:[0],ESP

00401014 XOR EAX,EAX

00401016 MOV DWORD PTR DS:[EAX],ECX


Ces deux dernières instructions génèrent volontairement une exception. En effet, le XOR va mettre EAX à 0, et l'instruction suivante, qui tente de mettre ECX dans le dword contenu dans EAX, ne peut aboutir, car EAX est nul. On va alors avoir droit à une exception, c'est à dire à un événement qui sort du cours ordinaire de l'exécution d'un programme, et que celui ne sait pas gérer. L’exception va alors être traitée par une structure spéciale, les SEH. Enfin, ce n’est pas l’objet de notre présente étude.


Faisons F9 pour déclencher l’exception, on fait Shift+F7 pour la passer en step into, et on atterrit dans ntdll. Faites maintenant Ctrl+M pour afficher la Memory Map, et repérez la section .code de pdf2word (en 00401000). Un click droit dessus, ‘Set break on access’ (ou plus simplement F2 :D). Ensuite on fait F9, ce qui a pour action de nous faire breaker de nouveau dans le loader.


On va désormais rechercher le JMP EAX avant les octets nuls de fin de section, qui caractérise le saut vers l’OEP. Faites maintenant Ctrl+F pour rechercher une commande, puis tapez JMP EAX. On tombe tout d’abord sur cette occurrence :


004DC9D3 00FF ADD BH,BH

004DC9D5 FFFF ??? ; Unknown command

004DC9D7 FFE0 JMP EAX

004DC9D9 CA 0D00 RETF 0D ; Far return


Ce n’est pas la bonne, car elle se situe en plein milieu de code sans queue ni tête (datas ou junk code, je ne sais pas). Recherchons plus loin en faisant Ctrl+L, et nous tombons sur cette occurrence :


004DD8D8 FF11 CALL DWORD PTR DS:[ECX]

004DD8DA 8BC6 MOV EAX,ESI

004DD8DC 5A POP EDX

004DD8DD 5E POP ESI

004DD8DE 5F POP EDI

004DD8DF 59 POP ECX

004DD8E0 5B POP EBX

004DD8E1 5D POP EBP

004DD8E2 FFE0 JMP EAX

004DD8E4 0000 ADD BYTE PTR DS:[EAX],AL

004DD8E6 0000 ADD BYTE PTR DS:[EAX],AL

004DD8E8 0000 ADD BYTE PTR DS:[EAX],AL


Le code est compréhensible, on observe la restauration des registres avant le saut sur l’OEP, situé avant les octets nuls, tout semble donc concorder. On fait tout de même un autre Ctrl+L pour vérifier, Olly nous retourne un ‘Item not found’. On pose donc un bp sur le JMP EAX (F2), puis F9, et enfin F8 pour tomber sur l’OEP. Notez le dans un coin pour ImpRec, l’OEP est donc situé en 0047AB3E. On dumpe avec Ollydump, ne changez rien aux valeurs car tout est juste. Il ne vous reste plus qu’à reconstruire l’IAT dans ImpRec, ce qui se passe de façon tout à fait normale. Et voilà, l’unpack est fini.

A la prochaine dans un autre article ;)


Pour ceux que mon keygenme intéresse, il est bien avancé, mais il reste quelques bugs à corriger. Il devrait sortir d’ici 10-15 jours.

samedi 31 juillet 2010

Mise en ligne de mes tutos

Un petit post pour vous prévenir que mes tutos sont désormais disponibles sur le site de la XTX Team, ici : http://xtx.free.fr/liens/tut/Horgh/ , que je remercie pour l'hébergement.
Cherchez dans la rubrique liens pour les trouver. Voici le sommaire :

Tuto n°1 : Manual unpacking du packer Anti007 2.5 (NSAnti)

Tuto n°2 : Manual unpacking d'UPX et Keygenning

Tuto n°3 : Sérial Fishing sur un soft : Eusing Free Registry Cleaner

Tuto n°4 : Passage d'une démo en version complète : StealthPE 2.2

Tuto n°5 : CrackMe KillNag de KiTo

Tuto n°6 : Manual unpacking d'ASPack 2.12 et fishing de sérials

Tuto n°7 : Création d'un keyfile pour le KeyfileMe1 de KiTo

Tuto n°8 : Sérial Fishing sur mIRC 6.35

Tuto n°9 : Manual unpacking d'EZIP 1.0

Tuto n°10 : Keygenning du Bispoo KeygenMe #1

Tuto n°11 : Keygenning de WJChess 3D

J'espère que ça vous plaira, n'hésitez pas si vous avez des remarques. A la prochaine, je pense pour la parution de mon keygenme ;)

Edit: mis à jour le 01/11/2011

mardi 22 juin 2010

Manual Unpacking et analyse du packer EPProt 0.3 -> FEUERRADER/AHTeam

Lien vers le CrackMe : http://www.multiupload.com/FVAVFZX6H3

Le packer débute dans la section .rsrc (ressources). On remarquera les fausses signatures des sections .code et .data : PEtite (du packer du même nom).

00409619 MOV EAX,CRACKME_.00408160
0040961E JMP EAX
On saute donc en 00408160. On remarquera une routine incomplète de compression type UPX juste en dessous.

00408160 MOV EAX,CRACKME_.00409620
00408165 JMP EAX
On saute donc en 00409620, juste après l'EP du packer. Je ne vois pas l'intérêt de ces redirections. Peut être pour désorienter, comme les NOP un peu partout ?

00409620 MOV EDX,CRACKME_.00408160
On met un pointeur vers le DWORD en 00408160 dans EDX.

00409629 MOV EAX,93F34D93
On met 93F34D93h dans EAX.

0040962E MOV DWORD PTR DS:[EDX],EAX
Et on met EAX (93F34D93h) en 00408160, ce qui a pour effet de changer le code. Il semblerait que cela soit le début de la reconstruction du layer d'UPX.

00409630 ADD EDX,4
On ajoute 4 à EDX pour passer au DWORD suivant (00408164).

00409633 MOV EAX,4D7EF3B3
Et on met cette fois ci 4D7EF3B3h dans EAX

00409638 MOV DWORD PTR DS:[EDX],EAX
Même effet que précédemment, mais en 00408164.

0040963A MOV EAX,CRACKME_.00409600
On met un pointeur vers le DWORD en 00409600 dans EAX.

00409647 JMP EAX
On fait une "boucle" ici car le JMP nous fait revenir au code au dessus de l'EP. Vous remarquerez que l'on tourne depuis tout à l'heure dans un espace restreint entre 00409600 et 00409647, si l'on excepte les redirections.

00409600 MOV EAX,CRACKME_.0040815F
EAX contient un pointeur vers le DWORD en 0040815F (qui se situe à l'octet avant le DWORD habituel en 00408160).

00409605 MOV ECX,10
On met 10h dans ECX. 10h reprèsente le nombre d'octets (16d) à modifier pour reconstruire le début de la routine. Il va servir de compteur pour le loop. Allez en effet en 00408170 (00408160+10h), et vous verrez la routine originelle d'UPX. Seuls les 16d premiers octets ont donc été modifiés par EPProt 0.3.

0040960A XOR BYTE PTR DS:[EAX+ECX],0F3
Ici se finalise la reconstruction d'UPX. On xore l'octet dans EAX+ECX, càd 0040815F + 10h avec 0F3h (et ensuite 0040815F + Fh...).

0040960E LOOPD SHORT CRACKME_.0040960A
Tant que ECX supérieur à 1, on saute en 0040960A.

00409610 MOV EAX,CRACKME_.00408160
00409615 JMP EAX
Et on saute sur la routine d'UPX reconstituée...

00408160 PUSHAD
On passe la main à UPX. On utilise l'ESP trick, on atterrit ici :

004082AE POPAD
004082AF JMP CRACKME_.004012C0
F8, et on est à l'OEP. On dumpe avec OllyDump, on corrige BaseOfCode et BaseOfData, on décoche "Rebuilt imports". La reconstruction avec Imprec se passe sans problèmes.

dimanche 20 juin 2010

Manual Unpacking et analyse du packer DEF 1.00 (Eng) -> bart/xt

Lien vers le CrackMe : http://www.multiupload.com/FVAVFZX6H3


On le passe sous Peid, on obtient : DEF 1.00 (Eng) -> bart/xt (l'auteur de FSG)

On lance maintenant Olly, on clique sur "OK" puis "Non" aux deux messagebox.

Fait notable, la routine de décompression se situe dans le PE Header, à la suite des "déclarations" des sections. En effet vous remarquerez que l'adresse ou nous sommes (00400268), est inférieur à 00401000, qui constitue tout le temps le début de la première section du programme. On se penchera en détail sur le PE Header un peu plus loin. Passons maintenant à une petite analyse en Dead listing (mais rien ne vous empêche de suivre en même temps dans Olly, c'est même préférable).


00400268 MOV ESI,004001C8 ; ASCII ".def"

On va dans la Memory Map d'Olly (Alt+M) , Click droit, Dump. Si on va en 004001C8, nous remarquons que c'est le nom de la 1ère section (.code en temps normal) qui est mis dans ESI.


0040026D PUSH 4

On pousse 4 sur la pile, qui correspond au nombre de sections.


0040026F POP ECX

Et on le récupère dans ECX.


00400270 CMP BYTE PTR DS:[ESI+7],0

Le byte est à 1 pour la 1ère et la 3e section. Je ne sais pas à quoi sert le dernier octet (en gras) qui constitue la "signature" de la section, si vous avez une idée…

004001C8 2E 64 65 66 00 00 00 01 ASCII ".def" ; SECTION


00400274 JE 00400287

Si cet octet est égal à 0, on saute en 00400287, et on passera de fait à la section suivante.


00400276 MOV EAX, DWORD PTR DS:[ESI+C]

On met la Virtual Address de la section précédente (ici .code) dans EAX, c'est à dire l'adresse du début de la section en mémoire.


00400279 ADD EAX,00400000

On lui ajoute l'Image Base (dans 99% des cas égale à 00400000, au besoin regardez le PE)


0040027E MOV EDX,DWORD PTR DS:[ESI+10]

Ici on récupère le paramètre "SizeOfRawData", qui est égal à 0x00003000 pour la première section, et on le place dans EDX. Ce paramètre définit la taille de la section en mémoire.


00400281 XOR BYTE PTR DS:[EAX],DL

Ici a lieu le décryptage : on xore l'octet en 00401000 (début de la section .code) avec DL, qui correspond à la partie basse d'EDX : c'est donc les 2 derniers chiffres de la SizeOfRawData


00400283 INC EAX

On incrémente EAX (pour passer à l'octet suivant de la section .code )


00400284 DEC EDX

On décrèmente EDX, qui reprèsente le nombre d'octets restants à décrypter (qui passe ainsi à 00002FFF, et ainsi de suite jusqu'à 0).


00400285 JNZ 00400281

Si EDX différent de 0 (JNZ = Jump If Not Zero), on refait la boucle. On va donc la faire 3000 fois, pour que chaque octet de la section . code soit décrypté (par le XOR). Si vous allez dans le dump à l'adresse 00401000, vous allez voir les octets changer un par un à chaque fois que la routine est effectuée.


00400287 ADD ESI,28

On passe à la section suivante dans le PE Header (car la taille des informations occupées par la section est (inévitablement ?) égale à 28h)


0040028A LOOPD 00400270

On fait une boucle dépendante de la valeur de ECX. A chaque passage, ECX est décrèmenté. Lorsqu'il arrive à 1, le loop est fini, et on enchaîne sur l'instruction suivante.


Au 2ème passage sur le CMP BYTE PTR DS:[ESI+7],0 on sautera directement au ADD ESI, 28, ainsi qu'au 4e. Pour la 3ème section, le CMP BYTE PTR DS:[ESI+7],0 est négatif, on passera donc par la routine de décryptage.


0040028C PUSH 004012C0 => PUSH OEP

00400291 RETN => Le RET fait office de JMP


Ensuite, on dumpe avec OllyDump, et on reconstruit avec ImpRec, j'espère que je ne vous apprend rien ;).

Pour le nag du CrackMe, on utilise la méthode que j'ai présenté dans mon tuto sur KillNag. On remplace le premier argument de la message box par un JMP en 00401047. Pour la réactivation du menu secret, on regarde dans les strings, on va à l'item "Secret". On remarque MF_GRAYED en Flag, à la place de MF_ENABLED. On remarque aussi que le menu "Secret" a les mêmes attributs pushés pour l'API que le menu "About", hormis ce MF_GRAYED. On va donc mettre le même attribut que le menu "About", c'est à dire que l'on va remplacer le PUSH 1 par un PUSH 0.