10 agosto 2010

No todo son md5 o sha1 en este mundo

Estamos acostumbrados a que todas las aplicaciones web utilizan siempre los mismos tipos de hash y que sea lo que sea lo que rompamos, al final se podrá utilizar los tropecientos gigas de tablas rainbow para obtener la contraseña en "un rato".

Desgraciadamente para unos y afortunadamente para otros, esto no siempre es así y últimamente los productos más conocidos utilizan distintos algoritmos para generar sus hash.

Sirva también como ejemplo para todos aquellos que desarrollan aplicaciones web o almacenan usuarios y contraseñas en bases de datos y ficheros a los que en algún momento alguien podría acceder.

En la siguiente tabla se muestra algoritmos y aplicaciones representativas de lo comentado anteriormente:


Aplicación Algoritmo
e107 md5(md5($pass)
EyeOS v1.8.5.3 md5($pass.md5($pass))
Invision Power Board 2.x.x md5(md5($salt).md5($pass)
Joomla 1.5.15 (default salted) md5($pass.$salt)
MediaWiki >= 1.1.0 md5($salt.md5($pass)
osCommerce md5($salt.$pass)
phpBB > 3.0.0RC5 phpass($pass)
SMF 2.0.x / 1.1.x sha1($username,$pass)
vBulletin md5(md5($pass).$salt)
WordPress > 2.5 phpass($pass)


Para ejecutar fuerza bruta sobre estos hashes se han diseñado múltiples herramientas en las que profundizaremos en otra entrada y que pueden hacer uso de las GPU de la tarjeta gráfica o no, como son hashcat, oclhashcat (GPU), Lightning Hash Cracker (GPU), PasswordsPro, Extreme GPU Bruteforce (GPU) o IGHASHGPU (GPU).

Mediante un pequeño script en php me he creado algunos de estos hashes para probar la herramienta hashcat y tomar algunas mediciones, usando como parámetros el hash de "12345", con el salt "abcdefghij" (para aquellos algoritmos que lo necesiten) y el nombre de usuario "admin":

<?php
require 'PasswordHash.php';
$pass="12345";
$salt='abcdefghij';
$username='admin';
$t_hasher = new PasswordHash(8, FALSE);
$hash = $t_hasher->HashPassword($pass);
echo 'md5(md5($pass): '.md5(md5($pass))."\n";
echo 'md5(md5($salt).md5($pass): '.md5(md5($salt).md5($pass))."\n";
echo 'md5($pass.$salt): '.md5($pass.$salt)."\n";
echo 'md5($salt.md5($pass): '.md5($salt.md5($pass))."\n";
echo 'md5($salt.$pass): '.md5($salt.$pass)."\n";
echo 'sha1($username,$pass): '.sha1($username.$pass)."\n";
echo 'md5(md5($pass).$salt): '.md5(md5($pass).$salt)."\n";
echo 'phpass($pass): '.$hash."\n";
?>

Una alternativa al script es utilizar la magnífica página: Hash Generator.

La ejecución se realizó mediante un ataque de fuerza bruta de 1 a 5 caracteres con un juego de caracteres amplio:

./hashcat-cli.bin -a 3 --bf-cs-buf \
 'ABCDEFGHIJKLMNÑOPQRSTUVWXYZ-_@\!$abcdefghijklmnñopqrstuvwxyz01234567890' \
--bf-pw-min=1 --bf-pw-max=5 -m MODO -n 4 ARCHIVO

Los resultados muestran una orientación de que algoritmos serán más lentos de atacar:



Algoritmo hash/sec Tiempo Hash
md5(md5($pass) 3.48M 6m27s 1f32aa4c9a1d2ea010adcf2348166a04
md5($pass.md5($pass)) no sop

md5(md5($salt).md5($pass) 2.32M 8m52s 380208ca0107157c64d25b23ee588d5d
md5($pass.$salt) 4.28M 5m22s bdb0f53fdd087dd9be9ca316a22ae83f
md5($salt.md5($pass) 2.81M 7m15s 99c2ec6d581dae0c04a02124790273fb
md5($salt.$pass) 4.22M 5m10s f304c3e7226f0284f0d5f7c4a384e6e2
phpass($pass) 4.51k 6745m $H$9abcdefghHix3FIPIQhE2AkCoctFaC/
sha1($username,$pass) 3.83M 5m43s d4e8e6deaa7b1f8381e09e3e6b83e36f0b681c5c
md5(md5($pass).$salt) 2.94M 7m36s b5e8fe63ed242468b7834289f3024955


Lo que lleva que el que mejor aguanta el ataque es PHPASS, desarrollado por la gente de OpenWall (conocidos por ser los creadores de john the ripper), aunque desgraciadamente esta función no está disponible nativamente en PHP y será necesario instalar la clase.

8 comments :

Unknown dijo...

Interesante, justo el otro día acabé leyendo sobre este tema, al migrar las bases de datos de entre dos gestores de tiendas basados en php.

Ultimamente estoy leyendo este blog, y tengo que decir que me gusta bastante el estilo con el que se tratan los temas.

Saludos,
Victor

vierito5 dijo...

A mi me parece alucinante lo mucho que la gente sigue usando md5, en fin. También es cierto que en parte es culpa de los desarrolladores que tampoco suelen ofrecer muchas opciones. Tuvo que pasar mucho mucho tiempo antes de que en PHP hubiese una implementación para usar sha512 por ejemplo, tenías que morir a md5 o sha1 si no usabas alguna clase externa. Así que todas las aplicaciones que tienen un tiempo usando md5 o sha1 en el caso mejor y se suele no tocar lo ya hecho.

Si no se pone fácil y directo, al que no le interesa/desconoce en particular el aspecto de la seguridad no se va a preocupar.

Y lo de hacer hash sobre hash sobre hash para aumentar la seguridad personalmente me parece una guarrada, no te va a proteger de colisiones con ese tipo de algoritmo.

Francisco dijo...

En la primera tabla, para Invision Power Board, faltó el último paréntesis de cierre!

Saludos :)

mgesteiro dijo...

al hilo de este mensaje (y de la serie de artículos de fortificación de mysql):

* mysql usa su propio algoritmo

* mysql recomienda NO USAR su función de hash en aplicaciones de usuario

por cierto, buena entrada. Espero con ganas la nueva sobre GPU-cracking.

Luna dijo...

Me gusta que te hayas hecho tu propio script, si quieres que estas cosas funcionen bien, es mejor hacerlas uno mismo!

Espero impaciente el siguiente post :D

Joseph dijo...

excelente. muy interesante.
de hecho en las aplicaciones web que realizo, hago un md5 de md5, pero ademas creo un algoritmo simple que agrega diversos caracteres en el HASH y en distintas partes, para evitar que decripten el hash.

Unknown dijo...

una pregunta absurda... y el hecho de que el algoritme sea 3 órdenes de magnitud más lento... no influye en el hecho de que se tarden 3 órdenes de magnitud más en romper???

Alejandro Ramos dijo...

@JuanRa: Efectivamente, la diferencia es que el sistema solo tiene que ejecutarlo una vez, lo que le lleva nanosegundos y alguien que quiere hacer fuerza bruta, unos cuantos miles de millones.