
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 et ) selon laquelle pour PHP , simplement utilisée à des fins . Tout mot de passe à n'importe quel autre mot de passe de la liste. C'est une astuce différente des , il suffit de repérer la différence entre .
'0e1' == '00e2' == '0'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.
J'ai utilisé mon ordinateur portable, quelques boucles for (ou foreach ?), beaucoup de cycles CPU et un ventilateur externe en 2014, mais aujourd'hui vous pouvez/devez utiliser un GPU et un hashcat modifié pour cela. Voir cet article de Carl Löndahl et 0xb0bb.
Chick3nman & co. travaillent également sur leur version de hashcat, restez à l'écoute.
Si vous avez besoin d'une collision réelle alphanumérique, voici une collision MD5 alphanumérique de 72 octets avec une différence d'un octet, même d'un bit, par Marc Stevens :
md5("TEXTCOLLBYfGiJUETHQ4hAcKSMd5zYpgqf1YRDhkmxHkhPWptrkoyz28wnI9V0aHeAuaKnak")
=
md5("TEXTCOLLBYfGiJUETHQ4hEcKSMd5zYpgqf1YRDhkmxHkhPWptrkoyz28wnI9V0aHeAuaKnak")
Notez que si vous vous inscrivez avec le premier mot de passe et vous connectez avec le second, cela peut toujours signifier que le site utilise bcrypt(md5($password)), pas seulement md5($password). Un tel enveloppement de hash est parfois utilisé lors de la mise à niveau du hachage des mots de passe mais il ne devrait être utilisé que temporairement.
Voir le Projet HashClash de Marc si vous êtes intéressé par ces collisions réelles ou si vous souhaitez créer les vôtres.
Vraies collisions de hash LM par @solardiz (#35, merci !) :
db82323cb0693862 : 2275490 ou 0/*LUZ@44b3b60db75c15c1 : 2716388 ou 1}DC<XT585e239d32df1998 : 8351762 ou $;)5D|XVoir le tweet pour savoir comment en générer d'autres.