Trouver le bon mode -m de hashcat (et quoi faire quand on se trompe)
Hashcat ne devine rien. Voici comment choisir le bon mode -m, distinguer les hash qui se ressemblent et lire les erreurs qui trahissent un mauvais choix.
Hashcat ne regarde pas votre hash pour deviner ce qu'il est. C'est vous qui le lui dites, via -m, et si vous vous trompez il tournera joyeusement pendant des heures sans rien casser. C'est la première cause, et de loin, qui fait croire qu'un mot de passe est « incassable » alors qu'il s'agissait d'un mot du dictionnaire depuis le début.
La vraie compétence n'est donc pas de lancer hashcat. C'est de choisir le mode.
Le numéro de mode désigne l'algorithme, pas le hash
-m 0, c'est MD5. -m 1000, c'est NTLM. -m 1800, c'est sha512crypt. Le numéro encode la construction exacte, y compris la façon dont le sel est mélangé, si bien que md5($pass) et md5($salt.$pass) sont des modes différents (0 et 20) alors que les deux produisent 32 caractères hexadécimaux. Trompez-vous de construction et chaque candidat que vous testez sera haché différemment de la cible. Aucune correspondance, jamais.
C'est pour cela qu'identifier le hash vient en premier. Le format vous donne la famille. La source vous donne le mode précis.
Utilisez --identify, puis ignorez l'essentiel de ce qu'il dit
Les versions récentes de hashcat embarquent un outil de présélection :
hashcat --identify 5f4dcc3b5aa765d61d8327deb882cf99
Cela renvoie les modes dont la structure correspond à la chaîne. Pour une simple valeur de 32 caractères hexadécimaux, vous obtiendrez une longue liste : MD5, NTLM, MD4, les variantes double-MD5, et ainsi de suite. C'est exact mais peu utile, car tous ces modes sont structurellement identiques. L'outil ne voit que la chaîne. Il ne peut pas voir que le hash est sorti de secretsdump.py lancé contre un contrôleur de domaine, ce qui en ferait du NTLM et rien d'autre.
Traitez donc --identify comme un simple contrôle de cohérence. La décision vient du contexte :
- Extrait de
NTDS.dit, de la ruche SAM, ou d'une lignesecretsdumpdu genreuser:1001:aad3b435...:b4b9b02e...:::? La moitié droite est du NTLM,-m 1000. La moitié gauche est du LM, et si elle vautaad3b435b51404eeaad3b435b51404eec'est le hash LM vide, à ignorer. - Présent dans une table
usersd'un dump d'application web ? C'est très majoritairement du MD5 brut (-m 0) ou du SHA-1 (-m 100), parfois stocké sous la formehash:sel. - Commence par
$2y$ou$2b$? Du bcrypt,-m 3200, et révisez vos espérances à la baisse en conséquence. - Commence par
$6$? Du sha512crypt issu de/etc/shadow,-m 1800.
La longueur restreint la famille. La provenance choisit le mode.
Les erreurs qui trahissent un mauvais choix
Deux messages reviennent en permanence, et les deux sont mal interprétés.
« Token length exception » signifie que le hash ne s'analyse pas sous le mode choisi. La structure ne colle pas. Neuf fois sur dix, c'est un saut de ligne parasite issu d'un mauvais copier-coller, une colonne de nom d'utilisateur que vous avez oublié de retirer, ou tout simplement le mauvais -m. Passez le fichier dans xxd si vous n'êtes pas sûr de ce qu'il contient vraiment :
xxd hash.txt | tail -2
Un 0a à la fin, c'est un saut de ligne. Hashcat tolère un saut de ligne final par ligne, mais deux hash collés ou un 0d 0a à la Windows casseront l'analyse.
« Separator unmatched » apparaît quand vous utilisez --username ou un mode salé et que le compte des deux-points ne tombe pas juste. Les modes salés attendent hash:sel. Si le sel contient lui-même un deux-points, ou si vous avez laissé le préfixe user:, l'analyseur coupe au mauvais endroit.
Aucune de ces erreurs ne signifie que le hash est exotique. Presque toujours, c'est un problème de format ou un mauvais mode.
L'échec silencieux, voilà le vrai danger
Il y a pire qu'une erreur : le mauvais mode qui s'analyse quand même. md5($pass) et md5($pass.$salt) acceptent tous deux un jeton de 32 caractères hexadécimaux. Pointez -m 0 sur un MD5 salé et hashcat tourne proprement, brasse tout votre dictionnaire et n'annonce rien de cassé. Aucune erreur. Juste une mauvaise réponse qui ressemble à un hash coriace.
La parade, c'est le test à réponse connue. Avant de faire confiance à un long calcul, hachez un mot de passe que vous connaissez déjà avec la même construction et vérifiez que hashcat le casse en quelques secondes :
echo -n "password" | md5sum
# 5f4dcc3b5aa765d61d8327deb882cf99
echo "5f4dcc3b5aa765d61d8327deb882cf99" > test.txt
hashcat -m 0 -a 0 test.txt <(echo password)
Si cela ne renvoie pas password, votre mode est faux et il est inutile de lancer la vraie attaque.
Dans le doute, laissez John faire le tri
John the Ripper détecte automatiquement, ce qui en fait une bonne première passe quand vous ignorez réellement ce que vous tenez. Jetez le fichier à john sans drapeau de format et lisez ce qu'il a retenu :
john hash.txt
john --show hash.txt
Si John se fixe sur Raw-MD5, vous avez votre réponse, et vous pouvez transférer le travail vers hashcat avec -m 0 pour profiter du débit GPU. Je détaille quand rester sous John plutôt que de passer à hashcat dans la comparaison des outils.
Un dernier mot sur les noyaux optimisés
Si vous lancez avec -O (noyaux optimisés), hashcat plafonne la longueur des mots de passe candidats, souvent à 31 caractères ou moins selon le mode. Pour l'essentiel du travail au dictionnaire, c'est sans conséquence. Mais si vous lancez un masque qui génère de longs candidats et que rien ne tombe, le noyau optimisé a discrètement sauté tout ce qui dépassait la limite. Retirez -O et relancez avant de conclure que le mot de passe est long et aléatoire. Il fait peut-être juste 33 caractères de quelque chose que vous aviez déjà dans votre liste.