
Magic Hashes – PHP-Hash-"Kollisionen"
Registriere dich mit Passwort 1 und melde dich dann mit Passwort 2 an. Wenn du drin bist, verwendet der Speicher den angegebenen Algorithmus, um das Passwort zu hashen, und PHP verwendet ==, um sie zu vergleichen (für MD5, SHA-1 und Klartext).
Für MD5, SHA-1 und die SHA-2-Familie wird der seit langem bekannte Trick verwendet, dass in PHP '0e1' == '00e2' == '0' gilt (es ist eigentlich ein dokumentiertes Feature, siehe PHP-Typvergleichstabellen & Gleitkommazahlen); er wird hier nur für praktische Zwecke genutzt. Jedes Passwort matcht jedes andere Passwort aus der Liste. Das ist ein anderer Trick als ganzzahlige Strings, die in Gleitkommazahlen überlaufen, sieh dir einfach den Unterschied zwischen diesen beiden Zeilen an.
Das sind alle Algorithmen mit magischen Hashes:
md5(md5(password))Um @0xb0bb zu zitieren: „Es gibt andere Anwendungen für magische Hashes außer Passwortvergleichen (wie Caching-Ebenen oder Daten, die aus der Ausgabe einer Hash-Funktion abgeleitet werden), bei denen diese bekannten unsicheren, weniger bekannten und Pseudo-Hash-Algorithmen leichter zu finden sind."
Für Klartext werden verschiedene Konvertierungstricks verwendet. Das erste Passwort matcht nur das zweite. Die Tricks sind nach PHP-Versionen gruppiert, die sie ermöglichen.
bcrypt kürzt Passwörter auf eine maximale Länge von 72 Zeichen. Die Passwörter matchen, wenn die ersten 72 Zeichen beider Passwörter übereinstimmen.
descrypt (traditionelles UNIX-DES-crypt) kürzt Passwörter auf eine maximale Länge von 8 Zeichen. Die Passwörter matchen ebenfalls, wenn die ersten 8 Zeichen beider Passwörter übereinstimmen, siehe Abschnitt „Allgemeiner Quervergleich".
Wenn du ein Passwort verwendest, das länger als 64 Bytes ist, und es mit PBKDF2-HMAC-SHA1 hashest, wird es zuerst mit SHA1 vorab gehasht, sodass PBKDF2-HMAC-SHA1(password1) === PBKDF2-HMAC-SHA1(password2) gilt, weil sha1(password1) === bin2hex(password2). Ein ähnliches Vorab-Hashing wird bei PBKDF2-HMAC-SHA224 und PBKDF2-HMAC-SHA256 angewendet.
Derzeit gibt es dank Norbert Tihanyi in jedem nur einen magischen Hash; hoffentlich werden in Zukunft weitere hinzugefügt.
Verwende === beim Vergleich von allem* in PHP, nicht ==. Verwende außerdem password_hash() und password_verify() für das Passwort-Hashing in PHP, nicht MD5 oder SHA-1. *Verwende hash_equals() beim Vergleich von Hashes.
Alles begann mit diesem Tweet. Ich habe QNKCDZO und 240610708 im Februar 2014 generiert, und es hat sich seither über das gesamte Internet verbreitet. Googel einfach danach.