Attaques sur les hachages de mots de passe : principes et salage
Les mots de passe restent, aujourd'hui encore, l'une des portes d'entrée les plus utilisées par les attaquants. Mais comprendre pourquoi ils sont si souvent le maillon faible demande d'abord de comprendre comment ils sont réellement stockés, et pourquoi un même mot de passe peut être protégé... ou catastrophiquement exposé. Cette leçon pose les bases techniques.
Dans les chapitres précédents, vous avez obtenu un accès initial et compris comment il peut s'étendre dans un réseau (pivoting). Ce chapitre se concentre sur un objectif que recherche presque systématiquement un attaquant une fois entré quelque part : récupérer des identifiants, car ils ouvrent souvent plus de portes qu'une faille technique isolée.
Rappel : pourquoi on ne stocke jamais un mot de passe en clair
Vous avez vu, dans le premier cours du parcours, qu'un bon mot de passe est long et unique. Côté application, la bonne pratique n'est pas de le « se souvenir » tel quel, mais de stocker une empreinte calculée par une fonction de hachage : une fonction qui transforme n'importe quelle donnée en une chaîne de longueur fixe, de façon irréversible (on ne peut pas remonter du résultat à l'entrée) et déterministe (la même entrée donne toujours le même résultat).
Lors de la connexion, l'application ne compare pas des mots de passe, mais des hachages : elle recalcule le hachage du mot de passe saisi et le compare à celui stocké. Si une base de données fuit, l'attaquant récupère des hachages, pas des mots de passe directement lisibles — à condition que ces hachages soient correctement calculés.
Le problème des tables précalculées
Le déterminisme a un revers : si deux utilisateurs choisissent le même mot de passe, ils auront le même hachage. Un attaquant peut alors précalculer les hachages de mots de passe très courants (listes de mots de passe fréquents, mots du dictionnaire, variantes) et constituer une table de correspondance qu'il consulte ensuite pour « deviner » rapidement les mots de passe correspondant à des hachages volés, sans refaire le calcul à chaque fois. Ces tables, parfois organisées de façon très compacte (on parle de « rainbow tables »), rendent les fonctions de hachage génériques (conçues à l'origine pour vérifier l'intégrité de fichiers, pas pour protéger des mots de passe) totalement inadaptées à cet usage si elles sont utilisées seules.
Le salage : casser les correspondances précalculées
La parade s'appelle le salage (salting) : on ajoute, pour chaque mot de passe, une valeur aléatoire unique (le « sel »), différente pour chaque compte, avant de calculer le hachage. Le sel est ensuite stocké à côté du hachage (il n'a pas besoin d'être secret). Résultat : même si deux utilisateurs choisissent le même mot de passe, leurs hachages seront différents, car leurs sels le sont. Les tables précalculées génériques deviennent inutiles : un attaquant devrait recalculer une table différente pour chaque sel, ce qui annule l'intérêt de les précalculer à l'avance.
| Situation | Conséquence pour l'attaquant |
|---|---|
| Hachage simple, sans sel | Tables précalculées utilisables directement ; deux mots de passe identiques se voient immédiatement |
| Hachage salé | Chaque mot de passe doit être attaqué individuellement ; deux mots de passe identiques ont des hachages différents |
Pourquoi un algorithme « rapide » ne suffit toujours pas
Même salé, un hachage calculé avec une fonction conçue pour être rapide (comme celles utilisées à l'origine pour vérifier des fichiers) reste vulnérable à une attaque par essais massifs : un attaquant qui dispose de matériel puissant peut tester des milliards de combinaisons par seconde. C'est pourquoi la profession recommande des fonctions spécialement conçues pour le hachage de mots de passe, volontairement lentes et coûteuses en mémoire, qui rendent chaque tentative beaucoup plus chère pour l'attaquant sans gêner sensiblement l'utilisateur légitime qui ne se connecte qu'occasionnellement. Le choix de l'algorithme a donc un impact direct et considérable sur la résistance réelle d'un système, bien au-delà de la complexité du mot de passe choisi par l'utilisateur.
Le rôle du nombre d'itérations et du facteur de coût
Les fonctions de hachage adaptées aux mots de passe permettent de régler un facteur de coût : plus il est élevé, plus chaque calcul prend de temps et de ressources, donc plus une attaque par essais devient lente pour un attaquant. Ce facteur doit être ajusté régulièrement à la hausse, à mesure que le matériel informatique devient plus puissant : un réglage jugé raisonnable aujourd'hui peut devenir insuffisant dans quelques années. C'est une maintenance de sécurité continue, pas un réglage que l'on fait une fois pour toutes.
Ce que cela signifie pour un testeur
Lors d'un audit (toujours en labo autorisé), si vous obtenez l'accès à une base contenant des hachages, plusieurs observations orientent votre analyse, sans qu'il soit nécessaire de « casser » réellement les mots de passe pour les signaler :
- Les hachages sont-ils salés (sel visiblement différent pour chaque compte) ou identiques pour des comptes qui ont probablement le même mot de passe ?
- Quel algorithme semble utilisé (cela se déduit souvent du format ou de la longueur de la donnée stockée) ? Un algorithme reconnu comme obsolète pour cet usage est une faille à signaler, indépendamment de toute tentative de cassage.
- Existe-t-il une protection contre les tentatives répétées de connexion (sujet de la prochaine leçon) qui limiterait, en complément, les attaques même si le hachage était un jour compromis ?
Dans un rapport, on peut tout à fait signaler « absence de salage » ou « algorithme de hachage obsolète pour les mots de passe » comme une faille de configuration, sans avoir besoin de démontrer le cassage effectif d'un mot de passe réel, ce qui est d'ailleurs souvent préférable pour limiter l'exposition de données.
Le point de vue du développeur et de l'administrateur
Pour qui conçoit un système, les bonnes pratiques actuelles se résument ainsi :
- Utiliser une fonction de hachage spécifiquement conçue pour les mots de passe, pas une fonction de hachage générique ;
- Laisser cette fonction gérer elle-même le salage automatiquement, plutôt que de l'implémenter soi-même (une erreur d'implémentation maison est un risque fréquent) ;
- Choisir un facteur de coût adapté à la puissance de calcul disponible aujourd'hui, et le revoir périodiquement ;
- Ne jamais inventer son propre algorithme « maison » : utiliser des bibliothèques et standards reconnus et maintenus.
À vous de jouer : analyser une configuration
Pour cet exercice, aucune cible réelle n'est nécessaire. Dans votre carnet, répondez à ces questions à partir des principes de la leçon : (1) Pourquoi deux comptes avec le même mot de passe doivent-ils avoir des hachages différents dans un système bien conçu ? (2) Pourquoi une fonction de hachage « rapide » est-elle un problème pour les mots de passe alors qu'elle est parfaite pour vérifier l'intégrité d'un fichier téléchargé ? (3) Si vous deviez rédiger une recommandation pour une application fictive qui utilise une fonction de hachage générique sans sel, que écririez-vous dans votre rapport (impact, puis recommandation) ?
Voir une solution
(1) Grâce au sel, propre à chaque compte : sans cela, un attaquant qui casse un hachage casse instantanément tous les comptes partageant le même mot de passe, et peut réutiliser des tables précalculées. (2) Une fonction rapide permet de tester un très grand nombre de combinaisons par seconde ; pour l'intégrité d'un fichier, la vitesse est un avantage, mais pour un mot de passe, c'est un défaut car elle facilite les attaques par essais massifs. (3) Impact : « les mots de passe stockés dans la base sont vulnérables à des attaques par tables précalculées et par essais massifs, ce qui pourrait permettre, en cas de fuite, de retrouver un grand nombre de mots de passe en clair. » Recommandation : « migrer vers une fonction de hachage reconnue et spécifiquement conçue pour les mots de passe, avec salage automatique et un facteur de coût adapté. »
Astuce. Si vous développez une application, ne cherchez jamais à écrire vous-même une fonction de hachage ou de salage : utilisez les fonctions dédiées fournies par le langage ou une bibliothèque reconnue, et laissez-les gérer les paramètres par défaut, régulièrement mis à jour par leurs mainteneurs.
À retenir
- Un mot de passe bien conçu n'est jamais stocké en clair, mais sous forme de hachage, idéalement avec un sel propre à chaque compte.
- Sans sel, des tables précalculées permettent de retrouver rapidement des mots de passe courants, et des comptes identiques deviennent visibles.
- Les fonctions de hachage génériques et rapides sont inadaptées aux mots de passe ; il faut des fonctions volontairement lentes et coûteuses, avec un facteur de coût réglable et maintenu dans le temps.
- Un testeur peut signaler une absence de salage ou un algorithme obsolète sans avoir besoin de casser réellement des mots de passe.
- Ne jamais implémenter soi-même le hachage de mots de passe : utiliser des bibliothèques reconnues.
La leçon suivante aborde les attaques par dictionnaire et par force brute, ainsi que les protections responsables à mettre en place pour s'en prémunir.