====== John The Ripper ======
* MAJ : 24/04/2006
* Article co-écrit avec - et à l'insu de son plein gré - [[http://sclo.retiaire.org|Stéphane Clodic]]
* **Note:** cet article est un draft de chez draft !
* FIXME FIXME
* 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
* En partant de cette empreinte, JTR (mais d'une façon plus générale tout outil similaire) retrouve - grosso modo - le mot en clair de la manière suivante :
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 [[http://ophcrack.sourceforge.net/|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 =====
* Une image vaut parfois mieux que les mots :
{{ start:jtr-1.png }}
===== Modes =====
* JTR fonctionne selon les modes suivants :
== 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).
* Le caractère "-" introduit une règle de rejet :
-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 "?" introduit une classe de caractères :
?? 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]
* L'emplacement d'un caractère dans le mot de passe est spécifié à l'aide des paramètres suivants (la numérotation commence à 0) :
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 =====
* Passons rapidement sur la section Options qui ne présente que peu d'intérèt :
[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
* Tout au plus notera t-on l'option Beep dont l'utilité m'échappe ainsi qu'à l'auteur...
===== Données de test =====
* Nous avons utilisé pour les besoins de la cause les données suivantes issues d'un système Linux (Fedora Core 4 pour être précis) :
joe:$1$YtHfMRd3$mRaycu/ZMsVAwQKj.74qE.:13244:0:99999:7:::
tim:$1$QiH0JSfV$MO2B7ExogiGPd8PrZ2Bjl/:13264:0:99999:7:::
tom::13264:0:99999:7:::
* On y trouve un utilisateur dont le mot de passe est égal à son identifiant (login), un qui n'en a pas (devinez lequel...) et un autre dont la robustesse du mot de passe laisse clairement à désirer.
* Même si votre machine n'est pas une bête de guerre dernier cri, il ne devrait qunad même pas vous falloir [[http://www.acklabs.net/blog/index.php/2006/10/25/242-quelques-nouvelles-et-reflexions-rapides|40 jours]] pour casser ces empreintes.
===== Test =====
* Lançons notre JTR à l'assaut des empreintes susmentionnées en mode Single :
[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]#
* on peut être tenté de croire que les mots de passe contenus dans le fichier passwds sont forts et l'on aurait bien tort.
* Moralité : seule la sortie de -show fait foi (dont parfois dans le dos).
===== Sous le capot =====
* Que se passe t-il en coulisses pendant que JTR travaille ?
* Jetons un oeil au contenu du fichier de log john.log. On y trouve ceci :
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
* Ces lignes correspondent au premier lancement de JR en mode -single. On y retrouve le nom du mode utilisé ("single crack") et les règles - cinq - issues du fichier de configuration et utilisées pour aboutir au cassage du mot de passe 'tim'.
* Nous trouvons ensuite les lignes qui correspondent au second lancement en mode single :
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
(...)
* On note dans les lignes qui précèdent la mise en majuscule de la première lettre du mot, l'ajoût d'un chiffre en fin du mot, la mise en majuscule et l'ajoût d'un chiffre.
* Et finalement :
joejoe (joe)
guesses: 1 time: 0:00:02:36 100% c/s: 6489 trying: joejoe
[root@localhost jtr]#
* Le mot de passe est trouvé.
* Un petit tour dans john.log :
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
* nous informe que c'est la règle #7 qui a permis ce miracle.
* Dans le fichier de configuration un commentaire bienvenu nous indiquait que cette opération serait faite :
# Duplicate reasonably short pure alphabetic words (fred -> fredfred)
<7>1!?Ald
* L'option -show confirme que nous avons trouvé les trois mots de passe de notre jeu de test :
[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 =====
* La section List.Rules:Single commence ainsi :
[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 =====
* FIXME
===== Incremental Crack Mode =====
* FIXME
===== External Crack Mode =====
* FIXME
===== john.conf =====
* Le fichier complet est livré ci-dessous dans sa version brute : {{start:john.conf}}
===== Quelques recettes =====
* FIXME
* 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 ne veux générer que des mots de 8 caractères :
[List.Rules:Wordlist]
<7
== Je connais le début d'un mot de passe mais pas la fin ==
* Je sais que le mot de passe que je cherche a une longueur de 8 caractères, commence par les lettres 'Cs' et se termine par '5' mais j'ai oublié le milieu :
[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';
}