
Hash magici – "collisioni" di hash PHP
Registrati con password 1 e poi accedi con password 2. Se riesci ad accedere, l'archiviazione usa l'algoritmo specificato per calcolare l'hash della password e PHP usa == per confrontarle (per MD5, SHA-1 e plaintext).
Per MD5, SHA-1 e la famiglia SHA-2, usa il trucco noto da tempo (in realtà è una funzionalità documentata, vedi tabelle di confronto dei tipi PHP e numeri a virgola mobile) per cui in PHP '0e1' == '00e2' == '0', lo usa semplicemente per scopi pratici. Qualsiasi password corrisponde a qualsiasi altra password della lista. Questo è un trucco diverso dalle stringhe intere che traboccano in numeri a virgola mobile, basta notare la differenza tra queste due righe.
Questi sono tutti gli algoritmi con hash magici:
md5(md5(password))Per citare @0xb0bb, "ci sono altre applicazioni per gli hash magici oltre al confronto delle password (come i livelli di cache o i dati derivati dall'output di una funzione di hash) in cui questi algoritmi noti come insicuri, meno conosciuti e pseudo-hash possono essere trovati più facilmente."
Per plaintext, usa vari trucchi di conversione. La prima password corrisponderà solo alla seconda. I trucchi sono raggruppati per versioni PHP che li consentono.
bcrypt tronca le password a una lunghezza massima di 72 caratteri. Le password corrispondono se i primi 72 caratteri di entrambe le password coincidono.
descrypt (crypt DES UNIX tradizionale) tronca le password a una lunghezza massima di 8 caratteri. Le password corrispondono anche se i primi 8 caratteri di entrambe le password coincidono, vedi la sezione "General cross-check".
Se usi una password più lunga di 64 byte e la sottoponi a hash con PBKDF2-HMAC-SHA1, viene prima pre-hashata con SHA1, quindi PBKDF2-HMAC-SHA1(password1) === PBKDF2-HMAC-SHA1(password2) perché sha1(password1) === bin2hex(password2). Un pre-hashing simile viene applicato in caso di PBKDF2-HMAC-SHA224 e PBKDF2-HMAC-SHA256.
Al momento c'è solo un hash magico in ciascuno grazie a Norbert Tihanyi, si spera che in futuro ne vengano aggiunti altri.
Usa === quando confronti qualsiasi cosa* in PHP, non ==. E usa password_hash() e password_verify() per l'hashing delle password in PHP, non usare MD5 o SHA-1. *Usa hash_equals() quando confronti gli hash.
Tutto è iniziato con questo tweet, ho generato QNKCDZO e 240610708 a febbraio 2014 e da allora si è diffuso in tutta la rete. Basta cercarlo su Google.