John The Ripper

From IdeaNet
Jump to navigationJump to search

Auteur: Boris "Grand-Pas" Baldassari - 27 juin 2005 link to original article


Nous allons étudier dans cet article la théorie et la pratique du perceur de mots de passe John the Ripper. La première version de John date de 1996; c’est un outil fiable et puissant publié sous licence GPL (cf. http://www.fsf-europe.org).

La version de John utilisée dans cet article est la 1.6.37 ; vous pouvez la télécharger à partir du site de l’auteur, Solar Designer : http://www.openwall.com/john/. Si vous souhaitez faire quelques tests (sous GNU/Linux) avec cette version, vous pouvez la trouver ici : http://www.chrysalice.org/telechargement/


Cet article est composé de deux sections : premièrement une introduction à l’outil, dans ses principes fondamentaux et ses capacités de personnalisation. Ensuite, une mise en application de John sur des empreintes LanMan et MD5 suivie de quelques considérations sur les performances. La compilation de l’outil est présentée en annexe I (john_install.txt) et des exemples d’utilisation (sous GNU/Linux) sont fournis dans l’annexe II (john_usage.txt). Dans la mesure du possible, les concepts sont le plus souvent possible illustrés d’exemples réels.

Ce travail est publié sous licence GPL pour Documentation, ainsi que le stipule le fichier de licence (LICENSE) joint à l’article. Vos remarques sont les bienvenues à [grandpas à chrysalice point org].

Première partie : Théorie et Modes

John est ce que l’on appelle un perceur de mots de passe. Pour une liste d’utilisateurs et de leurs mots de passe chiffrés, il va essayer tous les mots de passe possibles en commençant par les plus probables.

La majorité des algorithmes d’authentification utilisés aujourd’hui sont dits asymétriques ; c’est-à-dire qu’ils ne peuvent être appliqués que dans un sens. Lorsque l’utilisateur se choisit un mot de passe, celui-ci est chiffré et enregistré sous sa forme obscure. Lors de la connexion suivante, le mot de passe fourni par l’utilisateur est chiffré avec le même algorithme et le résultat est comparé à la chaîne enregistrée. Si elles sont identiques, l’authentification est réussie. John procède de la manière : à partir d’un ensemble de mots probables, il chiffre chacun d’eux et compare le résultat avec la chaîne de caractère enregistrée jusqu’à trouver un résultat concordant.

Une des plus importantes caractéristiques de john est sa flexibilité : nous pouvons définir pour la génération des mots un jeu de caractères de base, des règles de construction ou un dictionnaire spécialisé adapté au contexte de l’audit. Cela permet à John de s’adapter aisément à n’importe quelle langue ou domaine.

Utilisation simple

L’utilisation la plus simple de john consiste à lui passer en argument un fichier contenant l’ensemble des mots de passe à percer, au format standard Unix (/etc/passwd). Lors d’un appui sur une touche, John affiche les informations d’exécution courantes :

  • le nombre de mots de passes trouvés
  • le temps écoulé depuis le début de la session
  • le nombre d’essais à la seconde
  • la chaîne de caractère actuellement testée.
root run 20:21:10 # ./john unshadowed.txt
Loaded 7 password hashes with 7 different salts (FreeBSD MD5 [32/32])
guest            (guest)
guesses: 1  time: 0:00:01:01 4% (2)  c/s: 1215  trying: Moose
guesses: 1  time: 0:00:01:02 4% (2)  c/s: 1216  trying: Jasper
guesses: 1  time: 0:00:01:33 9% (2)  c/s: 1218  trying: Maxime1

Lorsqu’un mot de passe est trouvé, john l’affiche sur la sortie standard avec l’identifiant utilisateur correspondant et l’enregistre dans le fichier de log john.pot. Ce fichier est utilisé par John au démarrage afin de connaître l’état d’avancement de l’audit.

L’ensemble des mots de passe trouvés peut être affiché en invoquant john avec l’option --show :

root run 20:14:38 # ./john --show unshadowed.txt
guest:guest:1002:1002:Guest Account,,,:/home/guest:/bin/bash
test1:maison:1004:1004:Test 1,,,:/home/test1:/bin/bash

2 passwords cracked, 5 left

John peut construire toutes sortes de chaînes de caractères pour la génération des mots de passe. Nous pouvons lui imposer certaines transformations, telle que "ajoute deux lettres au mot original, et mets-le en capitales". Il y a plusieurs types de règles, des plus simples (grandpas -> grandpas123 ; de nombreux utilisateurs prennent comme mot de passe leur login suivi d’un ou plusieurs chiffre) aux plus complexes (grandpas -> pasgrand, grandpas -> GrAnDpAs, elite -> 37173). Une grammaire complète a été définie pour cela (cf. le répertoire de documentation fourni avec John), permettant de configurer totalement les séquences de mots générés. Bien sûr, John nous offre par défaut un ensemble de règles prédéfinies et éprouvées par la pratique ; mais les particularités culturelles de chaque pays en réduisent l’efficacité.

Le fichier john.conf (ou john.ini selon les distributions) contient toutes les définitions de règles présentes par défaut :

# "Single crack" mode rules
[List.Rules:Single]
# Simple rules come first...
:
-s x**
-c (?acQ
-c lQ
-s-c x**MlQ
# These were not included in crackers I've seen, but are pretty efficient,
# so I include them near the beginning
>6'6
>7l'7
>6/?ul'6
>5'5
# Weird order, eh? Can't do anything about it, the order is based on the
# number of successful cracks...
<*d
rc
<*dMcQ
>5/?ul'5
uQ

Modes

Lorsque John est lancé sans option, il opère successivement selon trois modes, du plus rapide au plus long : single (simple), wordlist (dictionnaire), incremental (incrémental, brut). Le mode courant est affiché entre parenthèses lors de l’affichage des statuts (appui sur une touche), ainsi que (pour les deux premiers modes seulement) le pourcentage effectué. Si nous interrogeons John plusieurs fois en début de session, on peut se rendre compte du temps pris par chaque mode :

root run 20:04:14 # ./john unshadowed.txt
Loaded 5 password hashes with 5 different salts (FreeBSD MD5 [32/32])
guesses: 0  time: 0:00:00:04 50% (1)  c/s: 4926  trying: Test2
guesses: 0  time: 0:00:00:22 16% (2)  c/s: 4945  trying: VICTORY
guesses: 0  time: 0:00:00:28 22% (2)  c/s: 4941  trying: garden3
guesses: 0  time: 0:00:00:38 32% (2)  c/s: 4943  trying: basket6
guesses: 0  time: 0:00:00:55 55% (2)  c/s: 4960  trying: 4champion
guesses: 0  time: 0:00:01:21 82% (2)  c/s: 4953  trying: 9bridge
guesses: 0  time: 0:00:01:32 93% (2)  c/s: 4955  trying: Lindsaied
guesses: 0  time: 0:00:02:32 (3)  c/s: 4931  trying: myocly
guesses: 0  time: 0:00:02:35 (3)  c/s: 4932  trying: crendy
  • dans le mode simple, John utilise les informations login/GECOS des utilisateurs (nom, prenom, login, etc.) en y appliquant les règles de transformations définies dans le fichier john.conf. Il s’agit du mode le plus rapide, il ne dure en général que quelques secondes. Les mots de passe trouvés sont essayés sur toute la liste au cas où deux utilisateurs aient le même mot de passe.
  • les dictionnaires sont des fichiers texte, contenant un mot (ou expression) par ligne. Il en existe pour toutes les langues et tous les domaines d’activité. Les utilisateurs GNU/Linux ont en général deux dictionnaires sur leur système (/usr/shre/dict), un en anglais et un dans la langue locale. Les performances sont légèrement améliorées lorsque le fichier est trié par ordre alphabétique.
Pour spécifier un dictionnaire particulier à john, il suffit de lui indiquer son emplacement avec l’option --wordlist (ou --wordfile pour certaines distributions). Les règles de transformations peuvent ou non être appliquées sur chaque mot, pour déduire le féminin ou le pluriel des mots présents dans le dictionnaire.
root run 19:33:02 # ./john -rules --wordlist:/usr/share/dict/french unshadowed.txt
Loaded 6 password hashes with 6 different salts (FreeBSD MD5 [32/32])
guesses: 0  time: 0:00:00:01 0%  c/s: 1008  trying: abattit
guesses: 0  time: 0:00:00:02 0%  c/s: 1017  trying: abondaient
guesses: 0  time: 0:00:00:08 0%  c/s: 1023  trying: accoudé
guesses: 0  time: 0:00:05:16 0%  c/s: 1443  trying: invinciblement
maison           (test1)
guesses: 1  time: 0:00:06:29 1%  c/s: 1441  trying: pillarde
guesses: 1  time: 0:00:21:24 8%  c/s: 1445  trying: morphologie1sents dans le dictionnaire.
  • le mode incrémental essaie toutes les combinaisons de caractères dans une plage donnée (e.g. jusqu’à 8 caractères), à partir d’un jeu de caractères définis (e.g. seulement les lettres minuscules). Ce mode est *très* long ; il n’est jamais mené à son terme (que l’on peut estimer en fonction des plages données à plusieurs dizaines d’années). Afin d’en améliorer un peu l’efficacité, John base ses essais sur des tables de fréquence d’utilisation des caractères. Le mode incrémental est activé avec l’option -i (ou --incremental).
root run 21:37:18 # ./john -i:all unshadowed.txt
Des ensembles de caractères (charsets) prédéfinis sont livrés avec la distribution de John : all (tous), alpha (lettres), digits(chiffres) et lanman (caractères utilisables pour les mots de passe lanman). Il est possible de générer un charset à partir des mots de passe déjà trouvés ou à partir du fichier john.conf, avec l’option -make-chars :nomducharset.chr (ou -makechars :nomducharset.chr sur certaines distributions de John). Si aucun nom n’est fourni, john utilise son fichier de configuration. Lors de la génération du charset, il est possible de restreindre la plage des caractères utilisés avec l’option --external :filtre. Les filtres disponibles sont définis dans le fichier de configuration :
root john 21:33:01 # john -make-charset:all.chr
Loaded 23 plaintexts
Generating charsets... 1 2 3 4 5 6 7 8 DONE
Generating cracking order... DONE
Successfully written charset file: all.chr (40 characters)

root john 21:32:50 # john -make-charset:alpha.chr -external:filter_alpha
Loaded 6 plaintexts
Generating charsets... 1 2 3 4 5 6 7 8 DONE
Generating cracking order... DONE
Successfully written charset file: alpha.chr (20 characters)

root john 21:33:23 # john -make-charset:lanman.chr -external:filter_lanman
Loaded 23 plaintexts
Generating charsets... 1 2 3 4 5 6 7 8 DONE
Generating cracking order... DONE
Successfully written charset file: lanman.chr (37 characters)

Personnalisation des modes

Nous pouvons définir notre propre mode incrémental dans le fichier de configuration john.conf. Se référer à doc/documentation dans la distribution de john pour un descriptif complet du langage.

Nous pouvons par exemple définir un mode "mon_mode" tel que :

  • le charset utilisé est mon_charset.chr,
  • les caractères !%£ doivent également faire partie du charset,
  • les mots de passe ont une longueur comprise entre 3 et 8 caractères
  • l’état d’avancement est sauvegardé toutes les 5 secondes.

Ce mode est défini dans le fichier de configuration de la manière suivante ; nous l’activerons avec l’option -i :mon_mode.

[Incremental:mon_monde]
File = $JOHN/mon_charset.chr
Extra = !%£
MinLen = 3
MaxLen = 8
Save = 5

Si nous voulons ajouter des règles de transformation ou fournir un dictionnaire dans le mode par défaut de John (i.e. quand l’exécutable est lancé sans option), nous pouvons modifier les sections suivantes dans le fichier john.conf :

[Options]
# Wordlist file name, to be used in batch mode
Wordlist = /usr/share/dict/french

[List.Rules:Single]
:$1
:$123

[List.Rules:Wordlist]
:$1
:$123

Partie deuxième : Utilisation de John

Nous allons maintenant utiliser John pour auditer un fichier SAM de mots de passe MS Windows 2000, ainsi qu’un fichier /etc/passwd pris sur un système GNU/Linux. Les tests sont effectués sur un Pentium III 600MHz équipé d’une Debian SID, avec John 1.6-37 compilés pour l’occasion. Certains tests ont été également conduits sur une machine un peu plus puissante, un Pentium IV-M 2,7GHz, pour une meilleure appréciation des performances.

Performances

Le perçage de mots de passe consomme beaucoup de CPU : plus le processeur est puissant, plus vite sont essayés les mots de passe. La mémoire n’est quasiment pas utilisée, ainsi que le montre l’état des ressources (top) ci-après : 99% du processeur est pris par l’exécution de john, alors que l’espace mémoire pris est très réduit : John n’utilise que 900Ko.

grandpas@localhost:~$ top
top - 17:52:06 up  4:38,  4 users,  load average: 1.09, 0.50, 0.19
Tasks:  64 total,   5 running,  58 sleeping,   0 stopped,   1 zombie
Cpu(s):  99.0% user,   1.0% system,   0.0% nice,   0.0% idle
Mem:    158148k total,   153716k used,     4432k free,    24376k buffers
Swap:   514040k total,     5896k used,   508144k free,    68792k cached

 PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
2995 root      20   0   872  868  464 R 98.7  0.5   2:36.03 john
3016 grandpas  11   0  1044 1044  840 R  1.0  0.7   0:00.16 top
3013 grandpas   9   0  7676 7672 5600 S  0.3  4.9   0:02.07 gkrellm

grandpas@debianhome:~$ free
            total       used       free     shared    buffers     cached
Mem:        158148     153636       4512          0      24416      68072
-/+ buffers/cache:      61148      97000
Swap:       514040       5896     508144

Il est possible d’échanger un peu de consommation de cpu contre de l’espace disque. Dans la documentation complète (répertoire ./doc de la distribution de John), son auteur indique un moyen de procéder à un tel compromis : générer l’ensemble des mots à essayer, les stoquer dans un fichier et les fournir à John lors de l’exécution. Ainsi toute la puissance de calcul est utilisée pour le chiffrement des chaînes de caractères et non pour la génération des variations.

grandpas@localhost:~$ ./john -w:words -rules -stdout:8 | unique huge.lst
grandpas@localhost:~$ ./john -w:huge.lst unshadowed.txt

John peut tourner pendant des jours et des semaines avant de fournir la moindre information. En fonction de la puissance de calcul de l’hôte et les algorithmes de chiffrement percés, le nombre de coups par seconde peut varier de un à cent. Les performances peuvent être largement améliorées en ajustant correctement les options et les modes de john, en spécifiant le jeu de caractères utilisé ou en utilisant des dictionnaires adaptés

Pour ces tests, nous allons exécuter john sans option. Il essaiera ainsi successivement les modes simple, dictionnaire et finalement incrémental. Dans un contexte général ce comportement donne toute sa mesure, surtout si l’on ne connaît pas particulièrement le contexte de l’audit.

Un grand nombre de mots de passe sont trouvés dans les premières secondes. Ce sont les mots de passe les plus faibles, généralement basés sur les informations de login (un utilisateur toto qui a pour mot de passe toto123). Tous les mots de passe trouvés lors des deux premières phases (modes simple et dictionnaire) doivent être considérés comme faibles. Lors de la dernière phase, pour des options d’exécution correctes, tous les mots de passes seront trouvés sans exception ; mais cela peut prendre des années. La dernière phase ne nécessite pas d’être maintenue très longtemps lors d’un audit, car elle est moins représentative de la faiblesse des mots de passe.

LanMan Hashes

ntlm.txt est un fichier texte contenant des hashes NTLM. Ces hashes ont été extraits de la base de registre d’un système Windows 2000 avec l’utilitaire pwdump.

John détecte l’algorithme de chiffrement comme étant du NT LM DES [48/64 4K]. Les mots de passe traités par ce type de système sont tronqués à 128 caractères, convertis en unicode (un octet null est inséré à la fin de chaque caractère). La chaîne de caractère résultante est passée au MD4 pour donner un hash NTLM de 16 caractères. Aucune graîne n’est utilisée (les graînes sont utilisées sur les systèmes GNU/Linux pour introduire un élément aléatoire supplémentaire), ce qui rend l’audit des systèmes massivement multi-utilisateurs bien plus efficace. L’algorithme de chiffrement est également beaucoup plus rapide, ce qui permet une vitesse de test beaucoup plus importante que sur le chiffrement précédent : 2’000’000 coups par seconde.

root run 23:40:30 # ./john ntlm.txt
Loaded 6 passwords with no different salts (NT LM DES [32/32 BS])
guesses: 0  time: 0:00:07:51 (3)  c/s: 2289330  trying: GNIEFSY - RIVHAIM
guesses: 0  time: 0:00:09:25 (3)  c/s: 2293440  trying: ABIPKRO - BDRNBMA

Sur un PIV-M 2,7GHz, le même fichier de mots de passe utilisé avec les même binaires de john montre des performances multipliées par dix.

kadath:~/applis/john-1.6.37/run# ./john ntlm.txt
Loaded 6 password hashes with no different salts (NT LM DES [32/32 BS])
guesses: 0  time: 0:00:00:04 (3)  c/s: 8239066  trying: 1QCEET - 1QCEAT
guesses: 0  time: 0:00:00:06 (3)  c/s: 11369094  trying: 1P1ST4 - SAA02
guesses: 0  time: 0:00:00:08 (3)  c/s: 13433008  trying: MS0033D - MS00114
guesses: 0  time: 0:00:40:58 (3)  c/s: 21902817  trying: DJHMN4O - DJHMVPN

FreeBSD MD5

Les hashes que nous souhaitons auditer maintenant proviennent d’un système Debian SID, utilisant l’algorithme MD5 pour le chiffrement. Avant de fournir le fichier à john, nous devons tout d’abord le reconstruire (sur un système GNU/Linux les mots de passe sont stockés dans un fichier différent de celui qui contient les informations système sur les utilisateurs) au moyen de l’utilitaire "unshadow" fourni dans la distribution.

root run 23:15:26 # unshadow /etc/passwd /etc/shadow > freebsd_md5.txt

Nous pouvons ensuite fournir le fichier reconstruit à John.

root root 23:20:52 # ./john freebsd_md5.txt
Loaded 4 passwords with 4 different salts (FreeBSD MD5 [32/32])
guesses: 0  time: 0:00:00:32 0% (2)  c/s: 1316  trying: kristi
guesses: 0  time: 0:00:01:00 10% (2)  c/s: 1327  trying: Hamster1
guesses: 0  time: 0:00:07:49 (3)  c/s: 1329  trying: 12769

La puissance CPU nécessaire au calcul d’un hash MD5 est 1000 fois plus importante que pour un hash MD4. Le nombre de coups par secondes est réduit du même facteur (2’293’440 -> 1329).

Conclusion

John The Ripper a la réputation d’être le perceur de mot de passe le plus souple d’utilisation pour l’audit des mots de passe. Bien que sa vitesse de calcul soit dans la moyenne d’autres outils du domaine, sa flexibilité en font potentiellement le meilleur outil : il ne dépend que de vous de construire une bonne stratégie d’audit.

Parmi les concurrents de John, les plus connus sont sans doute Crack et L0phtCrack. Crack a de très bonnes performances, notamment au moyen de routines ré-écrites en assembleur x86 (John a également cette caractéristique), mais sa méthode de génération des chaînes de caractères en réduit l’efficacité. Un patch sur les sources de Crack rend le perçage des hashes NTLM possible. L0phtCrack, un autre outil majeur, est depuis trois ans sous licence propriétaire, et ses sources ne sont plus publiées.

Certains pourraient penser que ces outils sont dangereux et constituent une faille de sécurité. Bien que cela soit en partie vrai, plusieurs arguments viennent contredire cette thèse : d’une part, les pirates peuvent aisément coder leurs propres outils. D’autre part l’administrateur d’un système a ainsi la possibilité de tester la solidité des mots de passe de ses utilisateurs avant que les pirates ne le fassent. John peut être configuré pour auditer les mots de passe de temps en temps (grâce à un cron), ou chaque fois qu’un utilisateur change de mot de passe. Il est également possible d’envoyer un mail aux utilisateurs dont le mot de passe est trouvé.

Enfin, Il n’est pas nécessaire d’exécuter John pendant des mois. Seulement les mots de passe les plus faibles -- ceux qui sont trouvés pendant les deux premières phases -- sont intéressants.

Rappelez-vous qu’un système n’est pas plus sécurisé que la plus faible de ses parties. La plupart des exploits disponibles nécessitent un compte local sur le système pour être exécutés. Contrôlez ainsi régulièrement la solidité de vos mots de passe, faites expirer les mots de passe des utilisateurs (par exemple tous les 90 jours), et communiquez sur la sécurité du système et sur les risques de social engineering.