Crackme automatique

 druide

Toujours dans ma série de challenge, on me propose de cracker un exécutable en deux secondes.

Etape I

Le challenge commence avec le téléchargement du-dit exécutable. Pour ce faire, on fait appelle à une page php qui nous renvoi un flux binaire correspondant au programme, c'est-à-dire, à l'exécutable lui-même. Dans un navigateur, ça donne ça 😆


Il faut donc télécharger le flux binaire directement dans un fichier exécutable. Depuis le shell, il faut d'abords se connecter pour obtenir le cookie de session.


crack@druide:~$ wget --save-cookies cookies.txt --post-data 'user=************&password=***********' http://www.le_site_de_challenge.com/index.php?action=login
crack@druide:~$ wget --load-cookies cookies.txt -O crack.exe http://www.le_site_de_challenge.com/prog.php
crack@druide:~$ file crack.exe
crack.exe: PE32 executable (console) Intel 80386 (stripped to external PDB), for MS Windows

Etape II

Maintenant qu'on possède le programme, on peut le tester dans une machine virtuelle Windows


C:\Users\druide>crack.exe
Usage : crack.exe pass

C:\Users\druide>crack.exe JENESAISPAS
Rate, dommage ! Retente ta chance !


Allons faire un tour dans OllyDbg...


Explication

Dans la partie grisée, on peut voir la constitution du mot de passe. Ce dernier est composé de lettres mais ces dernières sont mélangées. Dans l'ordre de constitution on trouve:
0x7A, 0x69, 0x7A, 0x76, 0x79, 0x70, 0x73, 0x65, 0x69, 0x73, 0x00
. Convertit en caractères cela donne
'z', 'i', 'z', 'v', 'y', 'p', 's', 'e', 'i', 's', NULL
hors, si on regarde le "vrai" mot de passe qui apparaît dans la fenêtre de droite, pointé par le registre ECX, on trouve
"sizypsezvi"
. On peut donc facilement trouver les lettres du mot de passe mais il faudra également récupérer les offset de chaque caractères pour les replacer dans l'ordre. À la hauteur du breakpoint, on trouve l'instruction de comparaison qui décidera si le programme affichera
"Bravo tu..."
ou au contraire
"Rate, dommage..."
.

La récupération

Comme on connaît les opcodes permettant la création du mot de passe, on peut facilement les trouver directement dans le binaire avec quelques commandes dans le shell. Tout les opcodes commencent par
C645 OFFSET CAR
.

crack@druide:~$ hexdump -e '8/1 "%02x"' crack.exe | egrep -o 'c645[0-9a-f][0-9a-f]([0-9a-f][0-9a-f])' | awk '{ print substr( $0, length($0) - 3, length($0) ) }' | tr -d '\n'
ea7af169ef7af076eb79ec70e873ee65e969ed73f200


Maintenant on possède une chaîne composée de l'offset suivit du code ascii suivit du prochain offset suivit du prochain code ascii etc...

Remettre les lettres dans l'ordre

Pour remettre les lettres dans l'ordre, il faut simplement trier les code ascii par ordre croissant d'offset. Pour ce travail, j'ai choisi le langage C. Le programme reçoit la chaîne de caractères, la trie selon l'offset et affiche le résultat.

[collapsed title="Programme C"]


#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define MAXCHAR 44
#define NBCHAR  11

typedef struct _CARDEF
{
        char offset;
        char car;
}CARDEF;


int main(int argc, char** argv)
{
	CARDEF cardef[NBCHAR];
	int i = 0, j = 0;
	int done = 0;
	
	if(argc != 2)
	{
		fprintf(stdout, "Usage: %s ea7af169ef7af076eb79ec70e873ee65e969ed73f200\n", argv[0]);
		exit(EXIT_FAILURE);
	}
	
	if(strlen(argv[1]) != MAXCHAR)
	{
		fprintf(stdout, "The count of the char are incorrect!\n");
		exit(EXIT_FAILURE);
	}
	
	for(;i<MAXCHAR;i+=4,j++)
	{
		char off[3] = { argv[1][i],   argv[1][i+1], '\0' };
		char car[3] = { argv[1][i+2], argv[1][i+3], '\0' };
		cardef[j].offset = (int)strtol(off, NULL, 16);
		cardef[j].car    = (int)strtol(car, NULL, 16);
	}

	while(!done)
	{
		done = 1;
		for(i=0;i<NBCHAR-1;i++)
		{
			CARDEF tmp = { 0, 0 };
			if(cardef[i].offset > cardef[i+1].offset)
			{
				tmp.offset         = cardef[i].offset;
				tmp.car            = cardef[i].car;
				cardef[i].offset   = cardef[i+1].offset;
				cardef[i].car      = cardef[i+1].car;
				cardef[i+1].offset = tmp.offset;
				cardef[i+1].car    = tmp.car;
				done = 0;
			}
		}
	}

	for(i=0;i<NBCHAR;i++)
        {
		fprintf(stdout, "%c", cardef[i].car);
        }
	fprintf(stdout, "\n");

	return 0;
}

[/collapse]

Ce qui donne:


crack@druide:~$ ./password ea7af169ef7af076eb79ec70e873ee65e969ed73f200
sizypsezvi

Dernière étape

Pour valider le challenge, il faut encore faire appelle à une page php de vérification. On assemble donc le tout dans un script bash


#!/bin/bash
wget --save-cookies cookies.txt --post-data 'user=************&password=***********' http://www.le_site_de_challenge.com/index.php?action=login
wget --load-cookies cookies.txt -O crack.exe http://www.le_site_de_challenge.com/prog.php
CHAROFFSET=`hexdump -e '8/1 "%02x"' crack.exe | egrep -o 'c645[0-9a-f][0-9a-f]([0-9a-f][0-9a-f])' | awk '{ print substr( $0, length($0) - 3, length($0) ) }' | tr -d '\n'`
PASSWORD=`./password $CHAROFFSET`
wget --load-cookies cookies.txt http://www.le_site_de_challenge.com/verif.php?reponse=`echo -n $PASSWORD`


Réponse du site:

Bravo, tu as réussi l'épreuve ! Pour valider l'épreuve, le mot de passe est : *****************

That's all folks

  • 4 years 3 weeks before
  • |