ParcoursOuvrir l'appli

Casser des mots de passe

Sécurité et hacking éthique · 50 min

Se mettre à la place de l'attaquant

Pour bien défendre, il faut comprendre l'attaque. Imagine qu'une base de mots de passe hachés a fuité (la tienne, dans ton laboratoire, bien sûr). Les empreintes sont à sens unique... alors comment un attaquant retrouve-t-il les mots de passe ?

Il ne les « inverse » pas. Il devine : il essaie des mots de passe, les hache, et compare à la base. Si une empreinte calculée correspond à une empreinte de la base, il a trouvé le mot de passe.

Exercice : Un casseur par dictionnaire

Voici une base volée : des utilisateurs et l'empreinte SHA-256 de leur mot de passe. Et une liste de mots de passe courants. Écris casser(base, liste) qui renvoie un dictionnaire {utilisateur : mot de passe} pour tous les comptes dont le mot de passe est dans la liste.

Pour chaque utilisateur, essaie chaque mot de la liste : hache-le, et si l'empreinte correspond, tu as trouvé.

Voir une solution
import hashlib

base = {
    "awa": "8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92",
    "paul": "e93e24c1b877a15df5e4a8cbb20f351b891b750779cf5e8fb99119a7142d89cf",
    "mireille": "5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8",
    "junior": "d77d07912f337030a2972ac7b646dd1f78dadae789b806d2a2ad5fffb8fb9a5a",
    "admin": "dcf8ad297a71852c220ce269f1986187823a05f0e7585ab27799a4036a4f641a",
}
liste = ["123456", "password", "azerty", "soleil", "000000", "admin", "qwerty", "motdepasse", "iloveyou", "dragon"]


def casser(base, liste):
    """Renvoie {utilisateur: mot de passe} pour les comptes cassés par la liste."""
    trouves = {}
    for utilisateur, empreinte in base.items():
        for mot in liste:
            if hashlib.sha256(mot.encode()).hexdigest() == empreinte:
                trouves[utilisateur] = mot
                break
    return trouves


trouves = casser(base, liste)
print(trouves)
print(len(trouves), "comptes sur", len(base), "cassés")

Dans l'appli, ton code est exécuté et corrigé automatiquement. Faire l'exercice

Deviner les variantes : les règles

Junior a résisté avec Douala2024. Mais ce mot de passe n'est pas vraiment solide : c'est un nom de ville plus une année. Les attaquants appliquent des règles à leurs listes : ajouter des chiffres, une année, une majuscule, remplacer a par @...

Avec une règle « mot du dictionnaire + année récente », Douala2024 tombe en quelques secondes. C'est la leçon la plus importante de cette partie :

Exercice : Mesurer le temps de cassage

Comprends pourquoi la longueur gagne. Pour un mot de passe fait de caractères pris dans un jeu de taille possibilités, il y a taille ** longueur combinaisons. Si un attaquant teste vitesse empreintes par seconde, le temps au pire est le nombre de combinaisons divisé par la vitesse.

Écris secondes_max(taille_jeu, longueur, vitesse) qui renvoie ce temps en secondes. Puis compare deux mots de passe face à un hashcat à 10 milliards d'essais par seconde :

  • t_court : 6 chiffres (jeu de 10, longueur 6) ;
  • t_long : 12 caractères parmi 70 (minuscules, majuscules, chiffres, symboles).
Voir une solution
def secondes_max(taille_jeu, longueur, vitesse):
    """Temps au pire pour tout essayer, en secondes."""
    return taille_jeu ** longueur / vitesse


vitesse = 10_000_000_000
t_court = secondes_max(10, 6, vitesse)
t_long = secondes_max(70, 12, vitesse)
print("6 chiffres :", round(t_court, 4), "secondes")
print("12 caracteres varies :", round(t_long / (3600 * 24 * 365), 1), "années")

Dans l'appli, ton code est exécuté et corrigé automatiquement. Faire l'exercice