Craquer un mot de passe faible
Un simple script de quelques lignes suffit à retrouver un mot de passe mal choisi, plus vite qu'on ne le croit
TP pour réfléchir et résoudre des problèmes
Votre défi pour aujourd'hui consiste à auditer, avant une migration informatique, les mots de passe de deux comptes de l'ancien intranet d'une médiathèque
La médiathèque Jules Verne, ses comptes et ses mots de passe sont fictifs, construits pour l'exercice.
N'utilisez jamais, dans un exercice comme celui-ci, un mot de passe que vous employez réellement ailleurs.
Étape 1 — Récupérer la sauvegarde des comptes
Avant de migrer vers un nouvel intranet, le responsable informatique de la médiathèque vous confie une sauvegarde de l'ancien système, pour vérifier si les mots de passe qu'il contient sont acceptables. Reproduisez cette sauvegarde :
mkdir ~/tp-craquage
cd ~/tp-craquage
comptes_mediatheque.json :
[
{
"pseudo": "amelie",
"mot_de_passe_md5": "bc56c1d968d854fab31eac797203995a"
},
{
"pseudo": "direction",
"mot_de_passe_md5": "b015be41a519e3d50c0aec54240ead3e"
}
]
- Ce fichier ne contient aucun mot de passe en clair. Que contient-il à la place, d'après le nom du
champ
mot_de_passe_md5? MD5transforme n'importe quel texte en une suite de caractères de longueur fixe, toujours la même pour un même texte. Peut-on, à partir de cette seule suite de caractères, retrouver directement le texte d'origine par un calcul inverse ?
📌 Réponse attendue
Étape 2 — Préparer une liste de mots de passe probables
Un attaquant ne devine pas un mot de passe au hasard : il essaie d'abord les plus courants.
Créez le fichier mots_de_passe_courants.txt :
123456
password
azerty
Password1
mediatheque
Mediatheque
soleil2024
Mediatheque2024
bonjour123
motdepasse
qwerty123
bibliotheque
Cette technique, qui consiste à essayer une liste de mots probables plutôt que toutes les combinaisons possibles, s'appelle une attaque par dictionnaire.
Étape 3 — Écrire le script qui compare les empreintes
Créez craquage.py :
import hashlib
import json
def lire_comptes():
with open('comptes_mediatheque.json', encoding='utf-8') as fichier:
return json.load(fichier)
def lire_dictionnaire():
with open('mots_de_passe_courants.txt', encoding='utf-8') as fichier:
return [ligne.strip() for ligne in fichier if ligne.strip()]
dictionnaire = lire_dictionnaire()
for compte in lire_comptes():
trouve = None
for mot in dictionnaire:
empreinte = hashlib.md5(mot.encode()).hexdigest()
if empreinte == compte['mot_de_passe_md5']:
trouve = mot
break
if trouve:
print(f"{compte['pseudo']} : mot de passe retrouvé -> {trouve}")
else:
print(f"{compte['pseudo']} : aucun mot de passe de la liste ne correspond")
- Avant de l'exécuter, expliquez avec vos propres mots ce que fait la boucle
for mot in dictionnaire. - Que représente la variable
empreinteà chaque tour de cette boucle ?
📌 Réponse attendue
Étape 4 — Lancer l'attaque et mesurer sa durée
time python3 craquage.py
Résultat attendu :
amelie : mot de passe retrouvé -> Mediatheque2024
direction : aucun mot de passe de la liste ne correspond
suivi du temps d'exécution affiché par time.
- Combien de temps le script a-t-il mis pour tester les 12 mots de passe de la liste sur les 2 comptes ?
- Pourquoi le mot de passe de
directionn'a-t-il pas été retrouvé, alors que celui d'ameliel'a été en une fraction de seconde ?
📌 Réponse attendue
Étape 5 — Réagir à un cas pratique
Le responsable informatique de la médiathèque propose : « gardons MD5 pour le nouvel intranet, cet algorithme fonctionne très bien, il suffit juste d'imposer aux bénévoles des mots de passe plus longs à l'avenir ». Que lui répondez-vous ?
Restitution orale
Un étudiant (ou un binôme) vient présenter au tableau le résultat obtenu pour les deux comptes à l'étape 4, l'explication de cette différence, et sa réponse au responsable informatique de l'étape 5.
- Durée : 5 minutes de présentation + 2 à 3 minutes de questions.
- Qui passe : un(e) étudiant(e) (ou un binôme) désigné(e) par l'enseignant.
- Support : le travail réalisé pendant le TP, aucune préparation supplémentaire n'est nécessaire.
- Ce qui est attendu :
- rappeler le résultat obtenu pour
amelieet pourdirection, et la durée d'exécution constatée ; - expliquer pourquoi un mot de passe peut résister à une attaque par dictionnaire alors qu'un autre, haché avec le même algorithme, ne résiste pas ;
- répondre aux questions de la classe.
- rappeler le résultat obtenu pour
Cet exercice entraîne à l'oral technique court exigé par plusieurs épreuves du BTS (notamment E5 et E6) : clarté, structure, capacité à répondre à l'improviste.
📌 Une solution
Notions théoriques
Vous venez de retrouver un mot de passe à partir de sa seule empreinte, sans jamais le voir en clair. Comprenons précisément ce que vous avez fait, et ses limites.
Qu'est-ce qu'une fonction de hachage ?
Une fonction de hachage (comme MD5, SHA-1 ou SHA-256) transforme un texte de longueur quelconque en une empreinte de longueur fixe, toujours identique pour un même texte en entrée. Elle est à sens unique : il n'existe aucun calcul qui reconstitue le texte d'origine à partir de l'empreinte seule.
C'est la raison pour laquelle de nombreux systèmes stockent une empreinte du mot de passe plutôt que le mot de passe lui-même : même en cas de fuite du fichier de comptes, personne ne devrait pouvoir en déduire directement les mots de passe.
Pourquoi « deviner » fonctionne quand même
Puisqu'on ne peut pas inverser le calcul, il reste une autre méthode : essayer des mots de passe
candidats, calculer leur empreinte, et comparer au résultat enregistré. C'est exactement ce que
fait craquage.py.
| Méthode | Principe | Limite |
|---|---|---|
| Attaque par dictionnaire | Essayer une liste de mots probables (mots courants, noms propres, motifs classiques) | Échoue si le mot de passe réel n'est dans aucune liste testée |
| Attaque par force brute | Essayer toutes les combinaisons possibles de caractères, dans l'ordre | Fonctionne toujours, mais devient vite trop lente si le mot de passe est long |
| Credential stuffing | Essayer des couples identifiant/mot de passe déjà fuités lors d'un autre piratage | Fonctionne seulement si la victime a réutilisé un mot de passe déjà compromis ailleurs |
Dans ce TP, vous avez mené une attaque par dictionnaire : la liste de 12 mots de passe est minuscule par rapport à celles réellement utilisées par un attaquant, qui comptent souvent plusieurs millions d'entrées.
Pourquoi MD5 est un mauvais choix pour des mots de passe
MD5 a été conçu pour vérifier rapidement l'intégrité d'un fichier, pas pour protéger un secret. Pour des mots de passe, sa rapidité devient un défaut :
- Aucun salage : deux comptes avec le même mot de passe ont exactement la même empreinte MD5, ce qui permet de précalculer une immense table d'empreintes à l'avance (une rainbow table) et de retrouver un mot de passe en une seule recherche, sans relancer aucun calcul.
- Beaucoup trop rapide : un ordinateur ordinaire calcule des centaines de millions d'empreintes MD5 par seconde, ce qui rend une attaque par force brute bien plus rapide qu'elle ne devrait l'être.
Le bon outil pour stocker un mot de passe n'est ni MD5 ni SHA-256, mais un algorithme pensé
spécifiquement pour cela (volontairement lent, salé automatiquement), comme password_hash() en
PHP, étudié dans une séance à venir.
Test de mémorisation/compréhension
Bonnes pratiques
- Mot de passe long (16 caractères ou plus) : multiplie énormément le nombre de combinaisons possibles à essayer.
- Mot de passe imprévisible : jamais le nom d'une organisation, une année, ou un motif courant, pour sortir des dictionnaires d'attaque.
- Algorithme de hachage lent et salé côté serveur (comme
password_hash()en PHP), jamais MD5 ni SHA-256 seuls, pour ralentir chaque tentative même face à un attaquant équipé. - Limiter le nombre de tentatives en ligne, pour rendre une attaque en direct bien plus lente qu'une attaque menée hors ligne.
- Ne jamais réutiliser un mot de passe compromis ailleurs, pour éviter le credential stuffing.