John The Ripper
John The Ripper (ci-après dénommé “JTR”) est l'utilitaire de référence en matière de cassage d'audit de mots de passe.
L'objectif de ce petit article est d'en présenter sous une forme claire (ie: human readable) les options de configuration livrées en standard.
En effet, la lecture du fichier de configuration de JTR redonne au mythe du geek incapable de s'exprimer autrement qu'en assembleur une nouvelle jeunesse. A croire que l'auteur de JTR se complaisait à la seule lecture d'un bon vieux sendmail.cf… De plus, il faut se méfier des F.A.Q. dans lesquelles on trouve ce genre de réponse : “If you really need to know, read the source code.”. RTFC, next step after
RTFM…
Dans la suite de cet article, nous analyserons les paramètres du fichier de configuration livré avec les sources et, selon une formule consacrée généralement réservée aux conditions d'utilisation : AS-IS, terme à prendre, en l'espèce, dans tous les sens du terme…
Fonctionnement
Le lecteur est en droit de se demander comment fonctionne un logiciel de cassage d'audit de mots de passe.
En résumé, cela marche de la manière suivante : les mots de passe - tout du moins les mots de passe Système des mondes Windows, Unix, etc - sont généralement stockés sous une forme qu'il est convenu d'appeler “chiffrée”. En réalité, c'est une empreinte du mot de passe dit “en clair” qui est stockée. La robustesse du mot de passe est donc en partie liée à sa composition (quelles touches du clavier ont été utilisées pour le construire), à sa longueur (eh oui : plus c'est long, plus c'est bon…) ET à l'algorithme utilisé pour créer l'empreinte stockée in fine sur le système.
Prenons un exemple :
bonjour -> MD5 -> f02368945726d5fc2a14eb576f7276c0
Empreinte stockée: f02368945726d5fc2a14eb576f7276c0
aaaaaaa -> MD5 -> 5d793fc5b00a2348c3fb9ab59e5ca98a != f02368945726d5fc2a14eb576f7276c0 :-(
aaaaaab -> MD5 -> 296e2138307668e7faa75e97889308f7 != f02368945726d5fc2a14eb576f7276c0 :-(
etc.
bonjous -> MD5 -> a5158583165b3fc25bfea9b9c3c1b3e1 != f02368945726d5fc2a14eb576f7276c0 :-(
bonjour -> MD5 -> f02368945726d5fc2a14eb576f7276c0 == f02368945726d5fc2a14eb576f7276c0 :-)
Bingo !
Si les deux empreintes sont identiques, les mots en clair le sont aussi.
Note : pour être plus précis, JTR ne compare pas chaque empreinte une à une. Il génère une empreinte à partir de ses paramètres de coniguration et de ses sources et recherche cette empreinte dans tout le fichier audité.
Pour arriver à ses fins, et surtout accélerer le processus, JTR va user de ruses, de rules et de dictionnaire pour choisir le mot en clair qu'il va hasher (menu comme chair à pâté). Parmi les ruses on citera celles qui consistent à prendre comme mot en clair “plausible” le login de l'utilisateur et de le décliner : en minuscules, en majuscules, en y insérant des chiffres, etc.
Quant à l'utilisation d'un dictionnaire, elle s'explique facilement : il n'est pas rare de choisir comme mot de passe… un nom commun, un prénom, etc. Un bon dictionnaire contiendra également le noms de constructeurs automobiles et de leurs modèles, les prénoms, les noms de vedettes, etc.
Dernière astuce moins visible - mais ô combien importante - exploitée par JTR : stocker les empreintes des mots de passe déjà trouvés dans un fichier suffixés .pot. Il est étonnant de constater le succès que rencontrent certains mots de passe…
Rappelons que ce qui précède n'est qu'une descritpion
très sommaire du fonctionnement intrinsèque de JTR et qu'il existe des
outils dont les prouesses équivalent ou surpassent JTR car basés sur d'autres principes (dont l'utilisation de dictionnaires d'empreintes précalculées).
Signalons enfin qu'il est théoriquement mais rarissement possible que deux mots en clair différents produisent la même empreinte (on appelle ça une collision).
JTR en image
Modes
Single Crack
C'est le mode “traditionnel” de fonctionnement de JTR. En résumé, JTR va utiliser, pour générer les mots de passe, le nom d'utilisateur (login), les données du champ GECOS, le nom de son répertoire de travail, etc. ainsi que les règles définies dans la section List.Rules:Single du fichier de configuration. Dans la même catégorie on trouvera le mode Dictionnaire dont le comportement et la portée sont définis dans la section List.Single:Wordlist.
Le fichier john.pot dans lequel sont stockés les empreintes et les mots de passe correspondant déjà trouvés est également utilisé pour accélerer le processus. Certains disent et pensent même que les mots de passe déjà trouvés servent de base pour en tester d'autres…
Mode WordList
Il s'agit du mode le plus simple de fonctionnement de JTR. JTR puise dans un fichier qui contient une liste de mots en clair (bref : un dictionnaire) ceux à partir desquels il effectue ses tests.
Dans le mode simpliste, les mots du dictionnaire sont utilisés tel-quel mais généralement, des règles du fichier de configuration sont utilisées pour générer des variantes à partir du contenu du dictionnaire. Par exemple : b0nj0ur, h4ck3r, etc.
Ces variantes sont définies par les règles contenues dans le fichier de configuration.
Incremental Crack
“Incremental crack” : c'est le mode exhaustif. JTR va tester toutes les combinaisons possibles pour chaque caractère (au sens “clavier” du terme, un caractère pouvant donc être une lettre, un chiffre ou tout autre touche du clavier). En théorie, aucun mot de passe ne résistera donc à ce mode. En pratique, cela prendra, comme le disait ce cher Fernand, “un certain temps” suivant la longueur et la robustesse des mots de passe… Les paramètres des sections Incremental: vont tempérer les ardeurs de John à casser tout ce qui bouge.
External Crack
“External crack” : par external, il faut comprendre “user defined mode”. Cette acrobatie de langage laisse augurer de la suite et peut expliquer pourquoi il est peu aisé de lire un fichier de configuration de JTR sans… dictionnaire !
Structure du fichier de configuration
Intéressons-nous maintenant au fichier de configuration par défaut de JTR.
Les paramètres qu'il contient définissent la manière dont JTR va générer les mots de passe en clair avant d'en comparer l'empreinte à celles du fichiers de mots de passe (voir Schéma ci-dessus).
Les mots de passe en clair sont généralement extraits d'un dictionnaire. On va ensuite le triturer jusqu'à générer l'empreinte correspondate (ou échouer). L'exemple classique consiste à prendre le login de l'utilisateur concerné, puis, à partir de ce login, tester celui-ci tel quel, puis en majuscules, à l'envers, etc. Cela peut paraitre étonnant, mais cela marche encore !
Ce fichier se compose de plusieurs sections :
Options
List.Rules:Single
List.Rules:Wordlist
Incremental:All
Incremental:Alpha
Incremental:Digits
Incremental:LanMan
List.External:Filter_Alpha
List.External:Filter_Digits
List.External:Filter_LanMan
List.External:LanMan
List.External:Strip
List.External:Double
List.External:Parallel
En dehors de la bien nommée Options, ces sections contiennent les paramètres de configuration appliqués à chaque mode de fonctionnement de JTR.
La seule source d'information évidente pour traduire ces règles en bon français est le fichier RULES. Il faut le lire in extenso et ne pas sauter trop vite la petite ligne qui dit que JTR hérite des caractéristiques de l'utilitaire Crack. Se procurer ce logiciel et sa documentation est très utile pour une bonne compréhension du fichier de configuration de JTR. Et même comme cela, la lecture des paramètres de configuration n'est pas aisée !
Syntaxe
Pour le contenu de cette section, je ne vais pas réinventer la roue ni le fil à couper le beurre : tout ce qui suit est tiré du fichier RULES livré avec le code source de JTR (version 1.7 à l'heure où nous mettons sous presse) ou de la documentation de Crack (version 0.5, même horodatage).
-c reject this rule unless current hash type is case-sensitive
-8 reject this rule unless current hash type uses 8-bit characters
-s reject this rule unless some passwords were split at loading
?? le caractère : "?"
?v les voyelles : "aeiouAEIOU"
?c les consonnes : "bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ"
?w les espaces et tabulations
?p les caractère de ponctuation : ".,:;'?!`", y compris les guillemets
?s les symbôles : "$%^&*()-_+=|\<>[]{}#@/~"
?l les lettres minuscules : [a-z]
?u les mettres majuscules : [A-Z]
?d les chiffres : [0-9]
?a les lettres minuscules et majuscules : [a-zA-Z]
?x les caractères alphanumériques : [a-zA-Z0-9]
0...9 : désigne les emplacements de 0 à 9
A...Z : désigne les emplacements de 10 à 35 (//a kind of// hexadécimale notation)
* : désigne la longueur maximale du texte en clair
- : désigne la longueur maximale du texte en clair - 1
+ : désigne la longueur maximale du texte en clair + 1
Le caractère ”:” indique qu'il ne faut appliquer au mot en clair aucune transformation.
Les caractères ”[” et ”]” encadrent la définition d'un pré processeur. Un pré processeur est une sorte de générateur de règles.
Options
[Options]
# Wordlist file name, to be used in batch mode
Wordlist = dicos/all.lst
# Use idle cycles only
Idle = N
# Crash recovery file saving delay in seconds
Save = 600
# Beep when a password is found (who needs this anyway?)
Beep = N
Données de test
joe:$1$YtHfMRd3$mRaycu/ZMsVAwQKj.74qE.:13244:0:99999:7:::
tim:$1$QiH0JSfV$MO2B7ExogiGPd8PrZ2Bjl/:13264:0:99999:7:::
tom::13264:0:99999:7:::
Test
[root@localhost jtr]# /usr/local/bin/john -single passwds
Loaded 2 password hashes with 2 different salts (FreeBSD MD5 [32/32])
tim (tim)
guesses: 1 time: 0:00:00:00 100% c/s: 200 trying: tim
Yipie, serait-on tenté de se dire, un mot de passe a été trouvé !
Cependant, n'avions-nous pas fait remarqué qu'un compte n'avait pas de mot de passe ? Et JR n'aurait pas détecté cela ?
Ne vous y trompez pas : la sortie présentée ci-dessous n'est pas exhaustive, j'entends par là : tous les mots de passe trouvés ne sont pas affichés. Pour cela, il faut lancer JTR avec l'otpion -show :
[root@localhost jtr]# /usr/local/bin/john -show passwds
tim:tim:13264:0:99999:7:::
tom:NO PASSWORD:13264:0:99999:7:::
2 password hashes cracked, 1 left
Nous retrouvons donc bien notre utilisateur sans mot de passe et celui dont le mot de passe manque particulièrement de robustesse.
Donc ne pas se fier aux apparences : la sortie d'un -single ou de tout autre mode n'est pas à prendre pour argent comptant. Si l'on relance JTR en mode single une nouvelle fois :
[root@localhost jtr]# /usr/local/bin/john -single passwds
Loaded 1 password hash (FreeBSD MD5 [32/32])
guesses: 0 time: 0:00:00:00 100% c/s: 350 trying: J99999
[root@localhost jtr]#
Sous le capot
0:00:00:00 Starting a new session
0:00:00:00 Loaded a total of 2 password hashes with 2 different salts
0:00:00:00 Remaining 2 password hashes with 2 different salts
0:00:00:00 - Hash type: FreeBSD MD5 (lengths up to 15)
0:00:00:00 - Algorithm: 32/32
0:00:00:00 - Candidate passwords may be buffered and tried in chunks of 8
0:00:00:00 Proceeding with "single crack" mode
0:00:00:00 - 5 preprocessed word mangling rules
0:00:00:00 - Allocated 2 buffers of 8 candidate passwords each
0:00:00:00 - Rule #1: ':' accepted as ''
0:00:00:00 - Rule #2: '-s x**' rejected
0:00:00:00 - Rule #3: '-c (?acQ' accepted as '(?acQ'
0:00:00:00 - Rule #4: '-c lQ' accepted as 'lQ'
0:00:00:00 - Rule #5: '-s-c x**MlQ' rejected
0:00:00:00 - Processing the remaining buffered candidate passwords
0:00:00:00 + Cracked tim
0:00:00:00 Session completed
0:00:00:00 Starting a new session
0:00:00:00 Loaded a total of 2 password hashes with 2 different salts
0:00:00:00 Remaining 1 password hash
0:00:00:00 - Hash type: FreeBSD MD5 (lengths up to 15)
0:00:00:00 - Algorithm: 32/32
0:00:00:00 - Candidate passwords may be buffered and tried in chunks of 8
0:00:00:00 Proceeding with "single crack" mode
0:00:00:00 - 5 preprocessed word mangling rules
0:00:00:00 - Allocated 1 buffer of 8 candidate passwords
0:00:00:00 - Rule #1: ':' accepted as ''
0:00:00:00 - Rule #2: '-s x**' rejected
0:00:00:00 - Rule #3: '-c (?acQ' accepted as '(?acQ'
0:00:00:00 - Rule #4: '-c lQ' accepted as 'lQ'
0:00:00:00 - Rule #5: '-s-c x**MlQ' rejected
0:00:00:00 - Processing the remaining buffered candidate passwords
0:00:00:00 Session completed
On remarque que JTR ne va traiter que le mot de passe qu'il n'a pas réussi à craquer au lancement précédent : “Remaining 1 password hash”.
D'où la légitime question que doivent se poser un certain nombre d'entre vous : et le mot de passe craqué, il est où ?
Dans le fameux fichier john.pot :
[root@localhost bin]# more john.pot
$1$QiH0JSfV$MO2B7ExogiGPd8PrZ2Bjl/:tim
Le format de ce fichier est simple : empreinte:mot de passe.
Bon, c'est bien beau tout ça, mais il nous reste un mot de passe qui résiste encore et toujours à JTR.
C'est là que le mode Dictionnaire entre en jeu :
[root@localhost jtr]# /usr/local/bin/john -wordlist:/usr/share/john/dico-fr.txt passwds
Loaded 1 password hash (FreeBSD MD5 [32/32])
guesses: 0 time: 0:00:00:04 9% c/s: 6623 trying: blousait
guesses: 0 time: 0:00:00:07 14% c/s: 6526 trying: avrolles
guesses: 0 time: 0:00:00:11 22% c/s: 6482 trying: hague
guesses: 0 time: 0:00:00:14 29% c/s: 6491 trying: féminisait
guesses: 0 time: 0:00:00:18 38% c/s: 6519 trying: escortassent
guesses: 0 time: 0:00:00:21 45% c/s: 6534 trying: colin-tampon
guesses: 0 time: 0:00:00:24 53% c/s: 6570 trying: défléchiront
guesses: 0 time: 0:00:00:27 61% c/s: 6585 trying: dosassiez
guesses: 0 time: 0:00:00:30 68% c/s: 6592 trying: liquidasses
guesses: 0 time: 0:00:00:33 75% c/s: 6596 trying: ponctuellement
guesses: 0 time: 0:00:00:36 83% c/s: 6606 trying: vaticanes
guesses: 0 time: 0:00:00:39 90% c/s: 6604 trying: repartiras
guesses: 0 time: 0:00:00:42 98% c/s: 6607 trying: strophe
guesses: 0 time: 0:00:00:42 100% c/s: 6608 trying: syzygie
On a fourni ici à JTR un dictionnaire réduit (votre temps est précieux). JTR va tout bêtement prendre chaque mot de ce fichier pour générer une empreinte.
Dans le fichier de log on peut constater que JTR n'applique aucune transformation au contenu du dictionnaire :
0:00:00:00 Starting a new session
0:00:00:00 Loaded a total of 2 password hashes with 2 different salts
0:00:00:00 Remaining 1 password hash
0:00:00:00 - Hash type: FreeBSD MD5 (lengths up to 15)
0:00:00:00 - Algorithm: 32/32
0:00:00:00 Proceeding with wordlist mode
0:00:00:00 - Wordlist file: /usr/share/john/dico-fr.txt
0:00:00:00 - No word mangling rules
Le mot de passe résiste toujours.
Relançons donc JTR, en mode Dictionnaire encore, mais cette fois en appliquant les règles de transformation contenues dans john.conf :
[root@localhost jtr]# /usr/local/bin/john -wordlist:/usr/share/john/dico-fr.txt -rules passwds
Loaded 1 password hash (FreeBSD MD5 [32/32])
guesses: 0 time: 0:00:00:03 0% c/s: 6666 trying: avivement
guesses: 0 time: 0:00:00:07 0% c/s: 6451 trying: arsac
guesses: 0 time: 0:00:00:12 1% c/s: 6454 trying: nabor
guesses: 0 time: 0:00:00:17 2% c/s: 6499 trying: engouffrerez
guesses: 0 time: 0:00:00:21 3% c/s: 6539 trying: collationne
guesses: 0 time: 0:00:00:27 4% c/s: 6584 trying: dors
guesses: 0 time: 0:00:00:37 5% c/s: 6605 trying: rainurerais
guesses: 0 time: 0:00:00:49 14% c/s: 6489 trying: Allonnes
(...)
Premier constat : l'analyse est beaucoup moins rapide. Au lancement précédent, nous avions traité 45% du dictionnaire en 21 secondes contre à peine 3% maintenant.
L'effet de l'option -rules se fait donc sentir sur les performances et ses effets sont visibles :
(...)
guesses: 0 time: 0:00:00:49 14% c/s: 6489 trying: Allonnes
guesses: 0 time: 0:00:01:20 21% c/s: 6446 trying: merenvielles
guesses: 0 time: 0:00:02:00 31% c/s: 6467 trying: longea1
guesses: 0 time: 0:00:02:06 32% c/s: 6478 trying: roqueras1
guesses: 0 time: 0:00:02:12 34% c/s: 6487 trying: Janelle1
(...)
joejoe (joe)
guesses: 1 time: 0:00:02:36 100% c/s: 6489 trying: joejoe
[root@localhost jtr]#
0:00:00:00 Starting a new session
0:00:00:00 Loaded a total of 2 password hashes with 2 different salts
0:00:00:00 Remaining 1 password hash
0:00:00:00 - Hash type: FreeBSD MD5 (lengths up to 15)
0:00:00:00 - Algorithm: 32/32
0:00:00:00 Proceeding with wordlist mode
0:00:00:00 - Wordlist file: /usr/share/john/dico-fr.txt
0:00:00:00 - 15 preprocessed word mangling rules
0:00:00:00 - Rule #1: ':' accepted as ''
0:00:00:42 - Rule #2: '-c >3!?XlQ' accepted as '>3!?XlQ'
0:00:00:42 - Rule #3: '-c >2(?a!?XcQ' accepted as '>2(?a!?XcQ'
0:00:01:12 - Rule #4: '<*>2!?Alp' accepted
0:00:01:40 - Rule #5: '<*>2!?Al$1' accepted
0:00:02:08 - Rule #6: '-c <*>2!?Ac$1' accepted as '<*>2!?Ac$1'
0:00:02:35 - Rule #7: '<7>1!?Ald' accepted
0:00:02:36 + Cracked joe
0:00:02:36 Session completed
# Duplicate reasonably short pure alphabetic words (fred -> fredfred)
<7>1!?Ald
[root@localhost jtr]# /usr/local/bin/john -show passwds
joe:joejoe:13244:0:99999:7:::
tim:tim:13264:0:99999:7:::
tom:NO PASSWORD:13264:0:99999:7:::
3 password hashes cracked, 0 left
Single Crack Mode
[List.Rules:Single]
# Simple rules come first...
:
-s x**
-c (?acQ
-c lQ
-s-c x**MlQ
Ne vous fiez pas au “simples rules” : ces 4 lignes sont pas si simples à comprendre !
Les plus “anciens” d'entre vous auront toute de sutie noté une ressemblance certaine avec la syntaxe des bons vieux sendmail.cf…
WordList
Incremental Crack Mode
External Crack Mode
john.conf
Le fichier complet est livré ci-dessous dans sa version brute :
john.conf
Quelques recettes
-
Pour conclure, quelques recettes honteusement et sans vergogne tirées des archives de la liste de diff' john-users.
Dans la plupart des cas et sans mention contraire, leur auteur n'est autre que Solar Designer aka Alexander Peslyak en personne.
Limiter le nombre de caractères
Je connais le début d'un mot de passe mais pas la fin
[Incremental:All5]
File = $JOHN/all.chr
MinLen = 5
MaxLen = 5
CharCount = 95
[List.External:Cs-5]
void filter()
{
word[8] = 0;
word[7] = '5';
word[6] = word[4];
word[5] = word[3];
word[4] = word[2];
word[3] = word[1];
word[2] = word[0];
word[1] = 's';
word[0] = 'C';
}