Un petit bruteforce de mot de passe avec Hashcat
On s’est retrouvé récemment au boulot face à un petit souci : le mot de passe root par défaut d’une machine fraîchement déployée n’était pas accepté. J’ai donc voulu, de mon côté, trouver le mot de passe par des moyens moins conventionnels. Avec ma première tentative d’utilisation d’un outil incontournable quand on veut se lancer dans le cracking de mot de passe.
La machine virtuelle est donc une CentOS 7 déployée à partir d’un template vmware préparé avec Packer, et configuré via Kickstart, l’outil d’installation automatisée de Redhat. Dans la configuration kickstart, la version « hashée » du mot de passe, au format final sous Linux, est utilisée. J’ai donc voulu partir de ce hash pour retrouver le mot de passe initial.
Hashcat, la rolls des crackers de mot de passe, quand on a le matos
Historiquement, les gens qui voulaient casser du mot de passe linux utilisaient JohnTheRipper, qui reste encore populaire, mais dont l’âge se fait sentir semble-t-il. Le problème, c’est que John ne fonctionne qu’avec le CPU, alors que depuis quelques années, la puissance brute de nos cartes graphiques dépasse largement celle du CPU. Hashcat est capable de fonctionner avec les deux, soit en même temps, soit seulement avec l’un ou l’autre, et exploiter la parallélisation des architectures modernes pour être toujours plus efficace. Il a aussi le bon goût d’être opensource, multiplateforme, bref, que du bonheur. Par contre, comme souvent sous Linux pour certains usages GPU, mieux vaut utiliser une carte Nvidia, les outils AMD pour faire de l’OpenCL sont… Enfin bref, de toute façon, les tests qui vont suivre ont été faits sous Windows, ce qui ne demande finalement qu’un pilote assez récent.
Au départ, je pensais pouvoir utiliser le laptop du boulot, sous Linux. Aucun problème particulier pour le lancer, mais entre la chaleur dégagée et la lenteur, j’ai vite lâché l’affaire. Le fait est qu’on a pu identifier que le souci qu’on rencontrait était un problème d’ICC, j’ai donc arrêté mes tests, et ça m’arrangera pour la suite, quand j’ai attaqué les tests avec la Radeon RX5700XT à ma disposition.
Une brute de calcul, oui mais…
Je rentre donc à la maison et rouvre ma note enregistrée via nb. Je récupère le hash, le met dans un fichier, et démarre les hostilités. Premier constat, avec les options que j’ai utilisé, ça reste super long, et surtout, je teste toutes les possibilités, même celles dont je suis sur de ne pas avoir besoin (toutes les combinaisons inférieures à 8 caractères). Au bout de plusieurs heures, je ne suis pas encore arrivé à 8 caractères, qui était au final le résultat attendu.
Je vois que le nombre de hashs par seconde est particulièrement faible, aux alentours de 9500kH/s. Pourtant, l’algorithme affiché semble être du MD5 (mon hash commence par $1), et quand on voit les chiffres dans cet article d’impact-hardware, on sent qu’il se passe quelque chose :
Image INpact-Hardware
Je devrais donc tourner aux alentours de 26000MH/s, ce qui commence déjà à devenir sérieux (on parle d’un facteur x2600 quand même). Alors bon, est-ce que j’ai des soucis ? L’avantage d’Hashcat, c’est qu’il peut enregistrer la session pour revenir dessus plus tard. J’enregistre donc la session en cours, et relance un test avec une version « md5 » simple du mot de passe, généré avec un petit « echo -n pass |md5sum », et là, magie :
Session..........: hashcat Status...........: Running Hash.Name........: MD5 Hash.Target......: 84de940c098f17f071c1307f135f42dd Time.Started.....: Sun Apr 04 13:52:10 2021 (13 secs) Time.Estimated...: Sun Apr 04 13:56:08 2021 (3 mins, 45 secs) Guess.Mask.......: ?1?2?2?2?2?2?2?3 [8] Guess.Charset....: -1 ?l?d?u, -2 ?l?d, -3 ?l?d*!$@_, -4 Undefined Guess.Queue......: 8/15 (53.33%) Speed.#1.........: 23089.7 MH/s (6.89ms) @ Accel:256 Loops:512 Thr:64 Vec:1 Recovered........: 0/1 (0.00%) Digests Progress.........: 318137958400/5533380698112 (5.75%) Rejected.........: 0/318137958400 (0.00%) Restore.Point....: 3932160/68864256 (5.71%) Restore.Sub.#1...: Salt:0 Amplifier:13312-14336 Iteration:0-1024 Candidates.#1....: Tfc50n07 -> kjj6d9ce Hardware.Mon.#1..: N/A
Ça bourre, donc ça colle, ce n’est pas un souci matériel. J’ai une confirmation via une publication de résultats du mode benchmark que je suis dans les ordres de grandeurs que je peux attendre de ma carte :
Hashmode: 500 - md5crypt, MD5 (Unix), Cisco-IOS $1$ (MD5) (Iterations: 1000) Speed.#1.........: 8992.2 kH/s (69.33ms) @ Accel:256 Loops:500 Thr:256 Vec:1
Je décide quand même de laisser tomber mon premier test, pour en refaire un en retouchant rapidement mes options. Et je patiente. Longtemps… Très longtemps… Mais il trouve. Je reviendrai tout à l’heure sur les raisons profondes qui font la différence, spoiler je suis bête comme mes pieds.
La surprise du brute-force par défaut
En effet, au début, je n’avais pas laissé le mode bruteforce par défaut sur md5 tourner longtemps, l’objectif était d’abord de valider les chiffres de performance. Mais à un moment donné, comme je voulais comparer avec le mode unix, j’ai refait le test et laissé tourner. Mon mot de passe fait huit caractères, ça devrait donc être assez rapide. Sauf que je le vois tourner, et passer à 9 caractères sans avoir trouvé. Il n’y a pourtant que des majuscules et minuscules !
J’investigue donc ce problème, relance en nettoyant d’éventuelles traces d’exécutions précédentes, rien, il passe encore sur toute. Et puis je vois un truc :
Guess.Mask.......: ?1?2?2?2?2?2?2?3 [8] Guess.Charset....: -1 ?l?d?u, -2 ?l?d, -3 ?l?d*!$@_, -4 Undefined
Prenons quelques secondes pour déchiffrer ça. Il applique donc un masque sur le premier caractère, un deuxième sur les six suivants, et un autre encore sur le dernier. Le premier masque dit « majuscule, minuscule, chiffre », le deuxième dit « minuscule et chiffre », le troisième dit « minuscule chiffre et certains caractères spéciaux ».
Surprenant ? En fait non, avec un historique de fuites de mots de passe, de statistiques, et la présence de nombreuses politiques de mot de passes similaires présentes sur les formulaires web, on s’est rendu compte que ce format était le plus répandu. Il est donc souvent intéressant de le prendre comme choix par défaut. Oui mais voilà, ça veut dire qu’il ne teste pas toutes les possibilités. Mon petit mot de passe a une majuscule en plein milieu, et ça suffit à passer à travers ce masque !
J’ai retenté en forçant le même masque sur tous les caractères, qui est le premier sélectionné, et là, paf :
84de940c098f17f071c1307f135f42dd:TotoToto Session..........: brut Status...........: Cracked Hash.Name........: MD5 Hash.Target......: 84de940c098f17f071c1307f135f42dd Time.Started.....: Sun Apr 04 14:09:09 2021 (35 secs) Time.Estimated...: Sun Apr 04 14:09:44 2021 (0 secs) Guess.Mask.......: ?1?1?1?1?1?1?1?1 [8] Guess.Charset....: -1 ?l?d?u, -2 Undefined, -3 Undefined, -4 Undefined Guess.Queue......: 1/1 (100.00%) Speed.#1.........: 23263.4 MH/s (7.00ms) @ Accel:128 Loops:1024 Thr:64 Vec:1 Recovered........: 1/1 (100.00%) Digests Progress.........: 829563863040/218340105584896 (0.38%) Rejected.........: 0/829563863040 (0.00%) Restore.Point....: 3440640/916132832 (0.38%) Restore.Sub.#1...: Salt:0 Amplifier:57344-58368 Iteration:0-1024 Candidates.#1....: O8cdiqss -> 4mnMX3ll Hardware.Mon.#1..: N/A
35 secondes pour le faire sauter, sachant qu’on connaissait les limitations, et que j’ai volontairement évité les mots de passe plus courts. Quand on vous dit que la taille compte quand il s’agit de mot de passe (j’en ai parlé y’a assez longtemps maintenant, mais l’idée est toujours d’actualité), et que certains militent pour des phrases de passe, ce n’est pas un hasard. Car l’impact sur les temps nécessaires pour les casser n’est pas linéaire, c’est donc très intéressant.
De l’importance du sel, et de ma confusion
Le sel est un minéral à la fois nécessaire et toxique pour le corps humain, c’est pour ça qu’on doit le consommer avec modération. Euh, je m’égare…
En informatique, un sel est le nom qu’on donne à un élément qu’on ajoute à une information avant de la chiffrer/hasher. L’idée, rendre l’information à encoder plus longue, et donc ralentir le travail des casseurs. C’est exactement ce qui se passe avec mon fameux mot de passe unix. Le format complet est le suivant :
$1$1Z6lMk9Q$T3XVqBcgF1fY9PlKlU9Oz0
Dans la pratique, cela veut dire qu’il y a un sel de sept caractères appliqué au mot de passe de huit. Sous Linux, chaque mot de passe a son propre hash qui est régénéré à chaque changement de mot de passe, ce qui élimine toute capacité de gain de temps lié à la récupération d’un seul d’entre eux. Ajoutez à ça que le md5 est en fait un md5crypt, soit un dérivé d’md5 avec donc d’autres opérations (je vous laisse le détail de l’algo ici, à lire au repos), et voilà, vous avez la raison de la différence de la performance par rapport à un md5 standard, et de mon interrogation sur les performances de ma bête.
D’ailleurs, le md5 n’est plus considéré comme un algorithme sur. Non seulement, les performances actuelles pour le brute-forcer le rendent faible, mais en plus, il a été prouvé mathématiquement puis par l’exemple qu’on pouvait générer le même hash à partir de deux contenus complètement différent. Alors que l’objectif de base était justement l’unicité des hash. Dans la pratique pour les mots de passe, ça veut dire qu’on peut trouver au moins deux mots de passe différents pour un même hash. Pas glop.
On m’a fait remarquer dans l’oreillette que le md5 n’était pas très reluisant sur un OS en 2021. C’est juste qu’on a repris le hash sur un ancien modèle de 2014, et de toute façon on le change lors de la phase de configuration de l’OS. Donc après, c’est du SHA512crypt qui est utilisé, pout tous les mots de passe générés/modifiés.
Le monde merveilleux du cassage de mot de passe
Mon expérimentation s’arrête ici. Ce qui est rigolo, c’est que ce billet a démarré deux semaines avant la parution dans le Journal du Hacker de cet autre article sur hashcat, qui présente grosso modo les options dont j’ai eu besoin pour arriver à mes fins, et comprendre les erreurs que j’ai faites ou rencontrées. Il y a aussi cet épisode du Comptoir Sécu sur les mots de passe avec un expert sur le sujet. Et pour le hardware porn, je vous laisse chercher « password cracking rig » sur un moteur de recherche d’images pour voir les machines de l’enfer !