
Magic hashes – « collisions » de hachage PHP
Inscrivez-vous avec mot de passe 1 puis connectez-vous avec mot de passe 2. Si vous y arrivez, alors le stockage utilise l'algorithme spécifié pour hacher le mot de passe et PHP utilise == pour les comparer (pour MD5, SHA-1, et le texte en clair).
Pour MD5, SHA-1 et la famille SHA-2, cela utilise l'astuce bien connue (c'est en réalité une fonctionnalité documentée, voir tables de comparaison de types PHP et nombres à virgule flottante) selon laquelle pour PHP '0e1' == '00e2' == '0', simplement utilisée à des fins pratiques. Tout mot de passe correspond à n'importe quel autre mot de passe de la liste. C'est une astuce différente des chaînes intégrales débordant en nombres à virgule flottante, il suffit de repérer la différence entre ces deux lignes.
Voici tous les algorithmes avec des hashes magiques :
md5(md5(password))Pour citer @0xb0bb, « il existe d'autres applications pour les hashes magiques en dehors des comparaisons de mots de passe (comme les couches de cache ou les données dérivées de la sortie d'une fonction de hachage) où ces algorithmes connus comme non sécurisés, moins connus et pseudo-hash peuvent être trouvés plus facilement. »
Pour plaintext, cela utilise diverses astuces de conversion. Le premier mot de passe correspondra uniquement au second. Les astuces sont regroupées par versions de PHP les autorisant.
bcrypt tronque les mots de passe à une longueur maximale de 72 caractères. Les mots de passe correspondent si les 72 premiers caractères des deux mots de passe correspondent.
descrypt (crypt DES UNIX traditionnel) tronque les mots de passe à une longueur maximale de 8 caractères. Les mots de passe correspondent également si les 8 premiers caractères des deux mots de passe correspondent, voir la section « General cross-check ».
Si vous utilisez un mot de passe de plus de 64 octets et le hachez avec PBKDF2-HMAC-SHA1, il est d'abord pré-haché avec SHA1, donc PBKDF2-HMAC-SHA1(password1) === PBKDF2-HMAC-SHA1(password2) parce que sha1(password1) === bin2hex(password2). Un pré-hachage similaire est appliqué dans le cas de PBKDF2-HMAC-SHA224 et PBKDF2-HMAC-SHA256.
Pour l'instant, il n'y a qu'un seul hash magique dans chacun grâce à Norbert Tihanyi, on espère que d'autres seront ajoutés à l'avenir.
Utilisez === pour comparer quoi que ce soit* en PHP, pas ==. Et utilisez password_hash() et password_verify() pour le hachage des mots de passe en PHP, n'utilisez pas MD5 ou SHA-1. *Utilisez hash_equals() pour comparer les hashes.
Tout a commencé avec ce tweet, j'ai généré QNKCDZO et 240610708 en février 2014 et cela s'est depuis répandu partout sur les intertubes. Il suffit de rechercher sur Google.