Réécrivez-le : exécuter une transformation de mot de passe dans le bon sens
Le défi
La bibliothèque d'Aldermoor utilise toujours le système d'adhésion acheté en 2011. Un test d'intrusion a trouvé un point d'injection capable d'écrire dans la table members, et le manuel de l'éditeur explique ce que contient la colonne pw_enc : pw_enc = base64_encode(strrev(password)). Pas un hachage. Pas de sel. Une inversion et un encodage, qui fonctionnent tous deux dans les deux sens. Le compte de démonstration le prouve : demo.reader a le mot de passe demo1234 et pw_enc NDMyMW9tZWQ=. Vous voulez que le compte du bibliothécaire accepte le mot de passe Kestrel-88 à la prochaine connexion. Produisez la chaîne exacte à écrire dans pw_enc.
Ce que tu vas apprendre
- Appliquer une chaîne d'encodage dans le sens direct plutôt que d'en décoder une à l'envers
- Lire une transformation imbriquée et déterminer quelle opération s'exécute en premier
- Expliquer la différence pratique entre un hachage et une transformation réversible
- Décrire ce que vaut un accès en écriture à une colonne de mot de passe quand le stockage est réversible
Compétences testées
Prérequis
- Ce qu'est le base64
- Lire un appel de fonction de l'intérieur vers l'extérieur
Comment ça marche
Le stockage des mots de passe a un seul rôle : à partir de la valeur stockée, personne ne doit pouvoir retrouver une entrée qui lui correspond. Un hachage de mot de passe moderne y parvient en étant à sens unique et volontairement lent, si bien que la seule voie d'une base de données volée vers une connexion valide est de deviner, à un coût par tentative choisi par le défenseur.
Ce que fait ce système de bibliothèque n'est pas cela. base64_encode(strrev(password)) est constitué de deux étapes réversibles. Un accès en lecture à la colonne livre tous les mots de passe en clair, et un accès en écriture est encore plus fort : vous n'avez pas besoin de connaître le mot de passe actuel, puisque vous pouvez calculer la forme stockée de n'importe quel mot de passe de votre choix et l'y placer.
Le sens est toute la compétence en jeu. Les appels imbriqués se lisent de l'intérieur vers l'extérieur, donc strrev s'exécute en premier et base64_encode enveloppe ce qu'il renvoie. Inversez les deux et vous obtenez quand même une chaîne base64 bien formée, ce qui explique pourquoi ce type d'erreur survit à une relecture rapide : la sortie a l'air tout aussi convaincante quand elle est fausse.
Erreurs fréquentes
- Encoder avant d'inverser. Les deux ordres produisent du base64 valide. Un seul se décode en le mot de passe écrit à l'envers.
- Soumettre le mot de passe inversé.
88-lertseKest la valeur intermédiaire, pas ce que contient la colonne. - Retirer ou ajouter le padding à la main. Laissez l'outil le produire. Le
==final fait partie de l'encodage, ce n'est pas une décoration. - Chercher une opération de décodage. Rien n'est encore encodé ici. L'entrée est en clair.
Comment s'en protéger
Stockez un vérificateur, jamais une valeur récupérable.
- Utilisez un hachage de mot de passe conçu pour cet usage, comme argon2id ou bcrypt, avec un sel par utilisateur. L'encodage et l'inversion ne sont pas un hachage faible, ce n'est pas du hachage du tout.
- Migrez à la prochaine connexion : vérifiez une fois par rapport à la colonne héritée, écrivez un hachage correct, effacez l'ancienne valeur. Un système qui ne peut pas être réécrit peut quand même être vidé de ses valeurs réversibles une connexion à la fois.
- Traitez la colonne de mot de passe comme une surface en écriture seule pour l'application. Si une injection peut l'atteindre, la prise de contrôle du compte ne nécessite aucun identifiant.
- Corrigez l'injection comme défaut principal. Le stockage réversible est ce qui la rend catastrophique, mais ce sont les requêtes paramétrées qui l'arrêtent.