Et oui ! Il est vraiment temps de lui dire adieu ! Mais à qui donc ? A la fonction de hashage fournie par MySQL en version 3.23. En effet, MySQL dans cette version (sorti le 5 juillet 1999), nous proposait une fonction de hashage qui fut très vite abandonnée suite à de légers problèmes de sécurité sur un plan cryptographique. Mais pourquoi diable je viens vous ennuyer avec ca aujourd’hui ? Tout simplement parce qu’un ami, que je salue (coucou Xanadrel), m’a parlé d’un outil qui est sorti récemment et qui permet de s’amuser un peu avec cette vieille fonction de hashage. Suite aux découvertes (approximativement fin 2006) faites par Philippe Vigier (http://sqlhack.com/) qui offrent une accélération plus que significative des calculs permettant soit de la brute forcer, soit de faire de la recherche de collisions. Ce dernier point étant toujours sympathique.
Alors cet outil se nomme MySQL323 Cracker, il est codé par Sc00bz. Vous trouverez son site web ici : http://www.tobtu.com/. D’ailleurs son nom de domaine est assez rigolo car il s’agit du ROT13 de « GBOGH » qui signifie « Go big or go home ».
Vous pouvez télécharger ce tool ici : http://www.tobtu.com/files/mysql323.zip
La page relative au sujet est ici : http://www.tobtu.com/mysql323.php
Et vous trouverez un fil de discutions ici : http://hashkiller.com/index.php?topic=5426.0
Rentrons un peu plus dans les détails. Une fois l’archive téléchargée et décompressée, vous constaterez que les sources sont absentes, toujours frustrant de ne pas pouvoir faire le curieux. Toutefois les binaires pour Linux & Windows sont présents (en 32 & 64 bits pour Linux et en 32 bits seulement pour Windows). Il y a en tout et pour tout 2 logiciels, le premier qui est un cracker se nomme ‘mysql323-32′ et le second qui est en charge de la recherche de collisions se nomme ‘mysql323collider32′. Commençons par jeter un rapide coup d’œil au man du premier (le cracker).
flappy@flappy:/media/hdd0/oclHashcat-0.24/tools/MySQL323 Cracker$ ./mysql323-32
Wrong number of arguments This takes three or four arguments:
* number of threads *
hash
* key space file *
resume code (optional)
./mysql323 4 7fffffff7fffffff keyspace.txt 1234567890
Le premier argument à lui donner est le nombre de thread, le second est votre hash MySQL323, le troisième est un fichier contenant les masques (j’y reviens plus bas), et le dernier, qui est optionnel, le code pour la reprise de votre tâche dans le cas ou vous aviez interrompu le processus. Faisons un essai rapide avec le hash MySQL323 de ‘password’ qui est : 5d2e19393cc5ef67
flappy@flappy:/media/hdd0/oclHashcat-0.24/tools/MySQL323 Cracker$ ./mysql323-32 4 5d2e19393cc5ef67 keyspace.txt
Calculating speed…
5d2e19393cc5ef67:70617373776f7264:password
Total time: 5.085 seconds
Average speed: 1.422 Tp/s
Il lui a fallu 5 secondes pour retrouver notre mot de passe de 8 caractères en minuscules. Ce qui est plutôt rapide. Par contre la vitesse moyenne de l’attaque surprend, 1,422 Tp/s. C’est énorme car tenez-vous bien, ce logiciel fonctionne sur CPU, il n’est pas question ici d’utiliser votre GPU. La machine sur laquelle je fais mes tests est équipée d’un Dual Core à 2Ghz. Mais jouons la carte du scepticisme et refaisons un test. Prenons un mot de passe un peu plus compliqué comme une chaine aléatoire de 10 caractères de long en minuscules, majuscules et nombres, QV7YPwCufD qui nous donne le hash suivant : 3b693dae338b7d3a.
flappy@flappy:/media/hdd0/oclHashcat-0.24/tools/MySQL323 Cracker$ ./mysql323-32 4 3b693dae338b7d3a keyspace.txt
1.562 Tp/s [25.0% 25.0% 25.0% 25.0%]
Après une dizaine d’heures, c’est l’échec ! Il faut reconnaitre que j’ai mis la barre un peu haute. Hashcat (la version CPU) estimait à environ 250 jours de calculs pour en venir à bout et avait du mal à m’afficher sa vitesse comme vous pouvez le constater ci-dessous.
Charset…: 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
Length….: 10
Index…..: 0/1 (segment),
839299365868340224 (words), 0 (bytes)
Recovered.: 0/1 hashes, 0/1 salts
Speed/sec.: – plains, 20.72M words
Progress..: 745433448/839299365868340224 (0.00%)
Running…: 00:00:00:36 Estimated.: 251:12:17:51
Et regardons du coté d’OclHashcat Lite 0.1 (petit dernier des hashcat tools dont je vous parlerai quand il sera release officiellement) avec une ATI 5970 :
Status….: Running
Current…: **4piy7faa
Speed.GPU*: 30.9G/s
Progress..: 1038658969600/9301612953526272 (0.01%)
Running…: 33 secs
Estimated.: 3 days, 11 hours
3 jours et 11 heures à la vitesse sympathique de presque 31 Gp/sec. C’est vraiment pas mal mais très loin derrière MySQL323 Cracker qui lui tourne sur CPU ! Alors quel est le secret de MySQL323 Cracker pour pouvoir tourner aussi vite sur CPU ? Pour répondre à cette question nous devons nous rendre sur le site de Philippe Vigier, http://sqlhack.com/, auteur du PoC (Proof of concept). Sur la page de Sc00bz, il est indiqué qu’il utilise pour MySQL323 Cracker le code de Secret Squirrel, mais après avoir jeté un œil à la source, Secret Squirrel s’appuie bien sur le PoC de Philippe Vigier.
Lien officiel pour le code de Secret Squirrel :http://packetstorm.linuxsecurity.com/Crackers/msqlfast.c
Mirror Kalk : http://project.kalkulators.org/download/mysql323-poc/mysqlfast.c
Sur son site, M. Vigier nous explique que c’est un fan d’échecs et qu’il a codé pour une émission de TV française un des principaux jeux d’échec. Cette expérience lui a permis d’aborder le problème d’une autre façon. Pour mieux comprendre, voici un exemple :
- Prenons 4 hashes MySQL323
- admin -> 43e9a4ab75570f5b
- password -> 5d2e19393cc5ef67
- root -> 67457e226a1a15bd
- mon_pass_2_leet -> 41cf0b605522d78e
Nous constatons bien que ces 4 mots de passe sont bien différents mais également leurs hashes qui sont pas du tout les mêmes. Vous me direz « oui normal, c’est le principe de la fonction avalanche des fonctions de hashage ». Justement cette fonction avalanche est loin d’être parfaite et en voici la démonstration :
- Prenons 4 plaintexts qui se suivent
- aaaa -> 28d6917a6fab63e5
- aaab -> 28d696bf6fab672a
- aaac -> 28d697f06fab665b
- aaad -> 28d695356fab67a0
Vous commencez à voir le « léger » problème ? Certains caractères des hashes changent, mais pas tous. Il y a donc un problème évident avec la fonction avalanche dans MySQL323.
- Reprenons 4 autres plaintexts qui se suivent
- xUZvgIQ7 -> 77df53cb25867057
- xUZvgIQ8 -> 77df517425866e00
- xUZvgIQ9 -> 77df56a525866b31
- xUZvgIR0 -> 77dfe70125858712
Nous retrouvons bien le même problème. Comme nous le montre l’illustration ci-dessous, nous pouvons découper les hashes en 4 blocs de 4 caractères.
Les caractères dans les blocs bleus ne changent pas, en revanche ceux des blocs verts varient sans point commun entre eux. En fait les blocs bleus varient, mais moins fréquemment que les blocs verts. Il y a donc des « pools ». Si vous voulez observer par vous même ces pools, voici un petit script en python qui vous génère tous les hashes MySQL323 issues des plaintexts de 1 à 10 caractères en minuscules, majuscules et chiffres. Il vous suffit juste de décompresser l’archive dans un dossier et de lancer ‘mysql323-gen.py’ et d’observer la sortie. Lien : mysql323-gen.tar.gz Une fois ce détail bien assimilé, passons à l’explication d’un balayage. Pour ce faire, reprenons un exemple simple.
- Prenons un hash MySQL323 dont nous ne connaissons pas son plaintext
2a4cb2bb729af916
- découpons le en 4 blocs de 4 caractères
2a4c b2bb 729a f916
- Numérotons nos 4 blocs
2a4c b2bb 729a f916 1 2 3 4
- Nous savons que nos blocs 1 et 3 ne varient pas, donc l’idée c’est de retrouver tous les plaintexts en faisant varier les blocs 2 et 4
Pour ce faire je vais utiliser un petit script python qui va commencer par chercher un plaintext dans le pool de notre hash et ensuite il partira de ce plaintext qu’il fera varier pour retrouver le plaintext de notre hash de départ.
[>] Input your MySQL323 hash : 2a4cb2bb729af916
[>] Bloc 1 : 2a4c 2a
[>] Bloc 3 : 729a
[>] Looking for candidat password in pool 2a4cXXXX729aXXXX
[>] checking passwords width [1]
[>] checking passwords width [2]
[>] checking passwords width [3]
[>] checking passwords width [4]
[>] Pool & candidat password found : admina 2a4c27f0729a8c4b
[>] Password found : admin0
real 0m4.902s
user 0m4.328s
sys 0m0.004s
Vous pouvez télécharger ce script ici : mysql323-little-poc.tar.gz Presque 5 secondes pour un mot de passe de 6 caractères en minuscules et chiffres, on est bien loin des performances de MySQL323 Cracker mais remettons les choses dans leur contexte, c’est un script python et de plus le PoC de M. Vigier n’est pas totalement implémenté. En revanche le même script python (la partie du PoC en moins) qui se contenterai de faire un simple brute force mettrai bien plus que les 5 secondes. Regardons en détail ce que fait le script exactement.
- Il commence par découper le hash en 4 et met dans 2 variables les blocs bleus.
- Il génère des plaintexts à la façon d’un brute force classique et leurs ajoute « aa ».
- Il regarde si les 2 premiers caractères des blocs 1 et bloc 3 de chaque hash résultant des plaintexts créés correspondent aux 2 premiers caractères des bloc 1 et 3 du hash que nous lui avons donné.
- Si les 2 premiers caractères des blocs 1 et 3 correspondent, il effectue un premier balayage, c’est à dire qu’il retire un « a » (ajouté en 2) et qu’il fait un « mini » brute force sur la chaine résultante et bien sur il compare à chaque fois si le bloc 1 et le bloc 3 correspondent aux blocs 1 et 3 du hash que nous lui avons donné.
- Si les blocs 1 et 3 correspondent, il retire le dernier « a » ajouté en 2 et recommence son « mini » brute force, si les 4 blocs correspondent, il a trouvé notre mot de passe.
- Sinon il continue
A ce stade de mon explication, vous devez vous demander pourquoi j’ajoute 2 « a » à l’étape 2. C’est très simple. Comme toujours, prenons un exemple.
- Prenons 3 plaintexts qui se suivent et hashons les.
- aaaaaa -> 3af1 11f4 2d17 8bb8
- aaaaab -> 3af1 13e9 2d17 8dad
- aaaaac -> 3af1 1d9e 2d17 8f62
Tous nos blocs 1 sont identiques entre eux ainsi que tous nos blocs 3.
- Prenons de nouveau 3 plaintexts qui se suivent.
- aaaadd -> 3af8 ef5a 2d0d 5ecd
- aaaaee -> 3afa 3a1c 2d19 4ec4
- aaaaff -> 3afb 749a 2d19 5b83
Quand on fait varier les 2 derniers caractères de nos plaintexts, le dernier caractère du bloc 1 varie (c’est pas toujours le cas, c’est fréquemment les 2 premiers qui ne changent pas) et les 2 derniers caractères du bloc 3 également. Cela signifie qu’on peut trouver le pool plus facilement en forçant les 2 derniers caractères des plaintexts que nous testons. On dit que nous sommes en N-2 car nous pouvons supprimer les 2 derniers caractères dans les plaintexts testés et les remplacer par un caractère de notre choix. Si nous supprimons le dernier caractère de notre plaintext et le remplaçons par un de notre choix, on dit que nous sommes N-1. Que se passe t’il si on essaye de pousser le vice à monter en N-3, et donc forcer les 3 derniers caractères de nos plaintexts.
- Prenons 4 plaintexts et hashons les.
- adminabc -> 02b3 a6dd 711d 657a (celui ci est notre mot de passe qu’on cherche à cracker)
- adminaaa -> 02ae ddd2 7141 f20e
- adminbbb -> 080d bb8d 7a0c 64e8
- adminccc -> 0eca 6164 76c0 0fd6
On voit tout de suite que cela est beaucoup moins évident, et pour cause, les blocs 1 et 3 n’ont plus que 1 caractères identiques en commun. Donc le N-3 n’est pas toujours possible. Mais ne nous avouons pas vaincu si vite, en effet, M. Vigier, grâce à son expérience des algorithmes des échecs va utiliser un algorithme dit discriminant pour voir si les mots de passe sont réellement candidats ou pas. Cela lui permet d’arriver en N-3 et d’avoir une accélération théorique de 1000000 de fois. C’est vraiment ingénieux, nous pouvons le féliciter pour son travail remarquable, d’autant plus que lui, à l’instar de Sc00bz, donne la source de son PoC en licence Creative Common.
Vous le trouverez ici : http://sqlhack.com/poc.html. (mirror Kalk : ici)
Maintenant que le PoC est clairement expliqué, revenons à MySQL323 Cracker. En début d’article, je vous montrais la rapidité de l’outil sur le hash du plaintext « password », bench effectué sur un DualCore cadencé à 2ghz. Voici le même bench effectué sur un I7 950. (merci Xanadrel)
C:\Crack\MySQL323 Cracker>mysql323-32.exe 8 5d2e19393cc5ef67 keyspace.txt
Calculating speed…
5d2e19393cc5ef67:70617373776f7264:password
Total time: 1.171 seconds Average speed: 6.696 Tp/s
Ce coup ci, le bench est encore plus « sexy » puisqu’on monte à 6,7 Tp/s, rappelez vous du bench sur une ATI 5970 qui tournait à 30Gp/s. La différence est vraiment importante. Mais cette performance n’est pas dû exclusivement au PoC que nous venons de voir. Sc00bz a eu l’idée d’utiliser des masques. Les masques sont utilisés en passcracking pour faire du brute force « intelligent » . Je vous explique tout de suite ce que sont les masques et comment ils fonctionnent. Une fois de plus, prenons un exemple !
- Prenons un mot de passe relativement classique
password88
Ce mot de passe a une longueur de 10 caractères et on utilise 2 charsets. On utilise les minuscules et les chiffres. Imaginons que les minuscules soient représentées par le symbole « m » et que les chiffres soient représentés par le symbole « c », nous pourrions écrire ce même mot de passe de la façon suivante :
mmmmmmmmcc
On dit dans ce cas que « m » et « c » sont des masques, car ils représentent un charset précis. On utilise les masques pour économiser les temps de calculs. Les chiffres disposent de 10 symboles, 0 1 2 3 4 5 6 7 8 9, et les minuscules 26. Si on devait brute forcer ce mot de passe sans utiliser de masque, il faudrait tester 26+10 possibilités par caractères, soit 10 caractères au total pour cet exemple.
- Calculons le nombre de combinaisons à tester dans ce cas :
26^10 = 1.41167e+14
Avec nos masques, nous avons 8 caractères codés sur 26 symboles chacun et 2 caractères codés sur 10 symboles chacun, ce qui nous donne le nombre de combinaisons suivantes :
26^8 * 10^2 = 2.08827e+13
Vous pouvez constater qu’avec les masques cela donne moins de travail à la machine. Maintenant ouvrons un fichier de masques de MySQL323 Cracker pour voir comment nous devons écrire nos masques afin de personnaliser nos recherches. Prenons le fichier « keyspace.txt ».
# # Character sets #
* [!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~]
s [!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~] M [0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz]
n [0123456789abcdefghijklmnopqrstuvwxyz]
m [ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz]
a [abcdefghijklmnopqrstuvwxyz]
A [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
0 [0123456789]
Première étape logique, il faut définir ses masques, c’est à dire préciser quel symbole représente quel charset. Comme vous le constatez, rien de compliquer la dedans, il suffit de mettre le symbole et sur la même ligne la liste des symboles qu’on vont englober, le tout entre crochets. Ensuite pour écrire nos masques, par exemple on veut tester tous les mots de passe de 6 caractères minuscules et commençant par 1 chiffre, on écrira alors notre masque de la façon suivante :
0aaaa (on retire 2 caractères de la fin car N-2, MySQL323 Cracker ajoute « ** »)
Il n’y a rien de compliqué là-dedans, l’usage des masques est une chose très simple. De plus vous n’êtes pas limité dans le nombre de masque, il suffit d’en écrire 1 par ligne, d’enregistrer votre fichier et de le passer en argument à MySQL323 Cracker. Aller je suis bon prince, voici un exemple.
- Le contenu de mon fichier de masques, il contient 1 charset défini et 1 masque.
M [0123456789abcdefghijklmnopqrstuvwxyz]
MMMMMM
Comme vous pouvez le voir, ce masque teste tous les mots de passe de 8 caractères de long en minuscules et chiffres. Je vous recommande vivement d’aller jeter un œil sur les fichiers keyspace*.txt fournis avec MySQL323 Cracker, vous verrez certaines subtilités sympathiques.
flappy@flappy-ati:/media/hdd0/oclHashcat-0.24/tools/MySQL323 Cracker$ ./mysql323-64 4 5853e0490ab18bbd fxk_keyspace.txt
2.334 Tp/s [24.9% 25.0% 25.1% 25.0%]
5853e0490ab18bbd:353835326278336a:5852bx3j
Total time: 17.977 seconds
Average speed: 2.336 Tp/s
Voila donc pour MySQL323 Cracker, maintenant nous allons passer au préposé aux collisions. Le principe n’est plus le même que celui du PoC de M. Vigier et il n’est plus question d’utiliser les masques. L’absence de la source peut que nous laisser supposer et non affirmer. C’est bien dommage. MySQL323collider consomme beaucoup de RAM (compter entre 2 et 5 go suivant votre OS, 32 ou 64 bits). Ce détail me laisse à penser qu’il fait une table de look up en RAM. En d’autres termes, une sorte de rainbow table live. Mais rien n’est sûr sans avoir un œil sur les sources… Regardons le man de ce tool.
flappy@flappy-ati:/media/hdd0/oclHashcat-0.24/tools/MySQL323 Cracker$ ./mysql323collider64
**** MySQL323 Collider v1.0 ****
Generates a collision for a MySQL323 hash.
./mysql323collider64 [parameters]
*** Required parameters ***
-h|–hash=<string> A MySQL323 hash (such as 7fffffff7fffffff)
-t|–threads=<int> Number of threads
*** Optional parameters ***
–help Display this message and exit
-c|–collisions=<int> Number of collisions found before exiting (default 1)
-m|–memory=<int> MiB of memory to allocate for main lookup table
-n|–no-bitmap Don’t create the 31 bits of the hash bitmap
-o|–output=<file> A file to output cracked hashes
-p|–prefix Use t, M, B, T, and Q for thousand, million, billion, trillion, and quadrillion. Instead of the SI prefixes k, M, G, T, P, E, Z, and Y.
-r|–resume=<int> Resume code
-s|–silent Silent mode (suppresses output of current speed)
-S|–super-silent Super silent mode (outputs cracked hashes or nothing with -o) -
v|–verbose Verbose mode
Je vais donc me concentrer sur l’essentiel, je vous laisse le plaisir de « bidouiller » avec celles que j’aurai homis d’expliquer, car bien secondaires. Donc en premier lieu, le tool attend le paramètre -h suivit du hash MySQL323, -t pour le nombre de threads et on pourrai ajouter -c pour le nombre de collisions souhaitée. Pour ne pas déroger à notre petite habitude, voici un exemple :
Calculs non terminés, j’update dès que possible, désolé, publié un peu trop vite :p
Juste pour la curiosité, un petit bench sur I5 ce coup ci (merci San) :
D:\hashcat\MySQL323> »mysql323 collider 32.exe » -h 43e9a4ab75570f5b -t 4 -c 3
Initializing…
Took 11.73 sec
2.205 Pp/s [25.5% 25.1% 25.0% 24.4%]
Une performance qu’on aimerai bien avoir sur des fonctions de hashage plus lourdes comme le md5(unix) ou même phpass(). En revanche même avec de telles performances, sur certains hashes, cela prend un temps considérable. Une implémentation sur GPU serai vraiment la bienvenue. Pour MySQL323 Cracker, Sc00bz est en train d’y réfléchir, donc avec un peu de patience, on verra bien.
Cependant, si vous avez une carte NVidia et un Windows sous la main, vous pouvez vous essayer au tool de Schwarzwaldhacker qui se nomme SchwarzwaldMYSQL. Je n’ai pas pu le tester ne possédant ni de GPU NVidia et encore moins de Windows (faudrait voir à pas déconner non plus hein :p). Vous trouverez la page en question sur son site (qui pique les yeux, vous êtes prévenu
) ici : http://www.schwarzwald.h1.ru/schwarzwaldMYSQL.html
Pour finir, je me suis demandé si on pouvait trouver encore beaucoup de bases de données qui utilisent cette fonction de hashage, MySQL323. Je me suis donc tourné vers une dork Google toute simple. J’ai eu assez de mal à trouver un petit exemple, ce qui est plutôt bon signe, mais j’en ai quand même trouvé un à vous montrer.
Dork Google : 565491d704013245 filetype:sql
Site : http://bit.ly/fwHj76
Cette base de données date de 2009 et n’est visiblement plus d’actualité, par contre toujours « choquant » de voir la personne qui gère ce site exposer ses dump SQL (et donc ses clients) aux vues et yeux de tout le monde. Mais cela est encore un autre problème dont il n’est pas question ici. (admin has to wake up ?)
Les outils exposés ici sont loin d’être aussi rapides que leurs bench nous laisse le penser, mais cela reste quand même une excellente optimisation et qui démontre bien tout l’intérêt de la fonction avalanche dans les fonctions de hashage. Je voudrai en profiter pour saluer le travail de Philippe Vigier qui a eu l’idée de mettre ses recherches sous licence libre, Secret Squirrel pour avoir mis à disposition sa source, Sc00bz pour ses tools et également Xanadrel et San qui m’ont accordé de leurs temps processeurs (I7 & I5) pour quelques bench dans cet article.
Si vous êtes joueur, je vous propose, pour conclure cet article, un petit jeu simple. Trouver le plus de collisions possibles sur ce hash 5250c9fa4ec8a0e8 (qui à été généré avec le plaintext Kalkulator’s), poster vos résultats en commentaire, amusez vous bien




