Buenas a tod@s,
Recientemente, un cliente se ha encontrado en el siguiente escenario: tiene una página web en Joomla! y pretende rehacerla en PrestaShop. Como no hay alternativa más que rediseñarla y reprogramarla desde cero en PrestaShop, nos ha pedido que le "ayudemos" a obtener las contraseñas de los usuarios que ya tiene registrados para poder migrarlos a su nueva página.
La idea es no tener que lidiar con todos los usuarios para que generen contraseñas nuevas, y que éstos cuando acudan a la nueva página, tengan todo como antes. Dado que no existe compatibilidad entre la forma en que Joomla! guarda las contraseñas y las lee Prestashop, hemos dedicido utilizar John The Ripper para obtenerlas y facilitárselas al cliente.
Curiosamente, en ciertas ocasiones el cracking no es usado en ámbitos ilícitos, si no que muchas veces se requiere para poder realizar migraciones u otro tipo de operaciones (al igual que el sniffing por ejemplo).
Antes de ponernos manos a la obra, tenemos que saber cómo Joomla! almacena las contraseñas y qué algoritmo criptográfico usa. Mirando un poco el código fuente de Joomla! (com_users/admin.users.php) se ve claramente:
// MD5 hash convert passwords
if ($isNew) {
// new user stuff
if ($row->password == '') {
$pwd = mosMakePassword();
$salt = mosMakePassword(16);
$crypt = md5($pwd.$salt);
$row->password = $crypt.':'.$salt;
} else {
$pwd = trim( $row->password );
$salt = mosMakePassword(16);
$crypt = md5($pwd.$salt);
$row->password = $crypt.':'.$salt;
}
Si el usuario es nuevo y la contraseña introducida no está vacia, sencillamente genera un cadena (string) aleatoria de 16 caracteres (salt) a través de la función mosMakePassword(16), y seguidamente llama a md5() concatenando la nueva contraseña introducida a la cadena aleatoria generada:
suponiendo que la contraseña introducida es "test", y suponiendo que la cadena o string aleatoria es "r7f5fd9XWmwYuKlR", hará "md5(testr7f5fd9XWmwYuKlR)", y el resultado (hash), lo almacenará en la base de datos.
Si buscamos un poco en la base de datos, vemos que las entradas en la tabla de usuario son de la forma:
tampax@Abyan ~ $ mysql -uroot -ppass -ssre "use DB_NAME; select * from jos_users limit 1\G;"
*************************** 1. row ***************************
id: 5935
name: Abyan
username: Abyan
email: info@abyan.es
password: b06b5ef56824f0433e5d919484d622ef:r7f5fd9XWmwYuKlR
usertype: ClienteC
block: 0
sendEmail: 0
gid: 33
registerDate: 2010-09-27 11:00:16
lastvisitDate: 2011-12-14 11:09:13
activation:
params: editor=
Como se puede observar, el usuario es "Abyan" y el campo de la contraseña contiene "hash:salt", donde el hash sería "b06b5ef56824f0433e5d919484d622ef" y el salt "r7f5fd9XWmwYuKlR".
Una vez sabemos exactamente cómo almacena las contraseñas y qué algoritmo se usa, podemos proceder a preparar el entorno de cracking.
Para utilizar john, hemos decidido usar la versión comunity, y sencillamente lo hemos bajado de Openwall y hemos cambiado la longitud máxima de la variable CHARSET_LENTGH a 10 porque sabemos que hay usuarios que pueden tener contraseñas de hasta 10 carácteres:
tampax@Abyan ~ $ wget http://www.openwall.com/john/g/john-1.7.9-jumbo-7.tar.gz
tampax@Abyan ~ $ tar xvzf john-1.7.9-jumbo-7.tar.gz
tampax@Abyan ~ $ cd john-1.7.9-jumbo-7/src
tampax@Abyan ~/src $ vim params.h
#define CHARSET_LENGTH 10
tampax@Abyan ~/john-1.7.9-jumbo-7/src $ make linux-x86-64-native
tampax@Abyan ~/john-1.7.9-jumbo-7/src $ cd ../run/
tampax@Abyan ~/john-1.7.9-jumbo-7/run $ ./john
John the Ripper password cracker, ver: 1.7.9-jumbo-7 [linux-x86-64-native]
Copyright (c) 1996-2012 by Solar Designer and others
Homepage: http://www.openwall.com/john/
...
* Para compilar John, es posible que se tengan que instalar los paquetes "openssl-devel" y "gcc".
Una vez tenemos a John The Ripper compilado, vamos a generar un charset (conjunto de carácteres que se van a utilizar para intentar adivinar las contraseñas) propio, que contenga únicamente los 26 caracteres del alfabeto (mayúsculas y minúsculas: a-z, A-Z) y los 10 dígitos (0-9), solamente para ahorar tiempo ya que conocemos que las contraseñas contienen únicamente esos posibles caracteres:
tampax@Abyan ~/john-1.7.9-jumbo-7/run $ echo :AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789 > john.pot
tampax@Abyan ~/john-1.7.9-jumbo-7/run $ ./john --make-charset=custom.chr
Loaded 1 plaintext
Generating charsets... 1 2 3 4 5 6 7 8 9 10 11 12 DONE
Generating cracking order... DONE
Successfully written charset file: custom.chr (62 characters)
Como vemos, John ha generado un charset de 62 carácteres, lo cual es correcto (26 letras del abecedario en minúscula + 26 letras del abecedario en mayúsculas + 10 dígitos)
Ahora, modificamos el john.conf para que entienda que existe un nuevo charset y que se llama "custom" (basta con añadir las siguientes líneas después de "[Incremental:LanMan]":
tampax@Abyan ~/john-1.7.9-jumbo-7/run $ vim john.conf
[Incremental:LanMan]
File = $JOHN/lanman.chr
MinLen = 0
MaxLen = 7
CharCount = 69
[Incremental:Custom]
File = custom.chr
MinLen = 1
MaxLen = 10
# Extra = +-$
La opción de configuración "Extra" nos permite añadir algunos otros carácteres por si acaso no los tenemos creados en el charset "custom". En el ejemplo hemos puesto "+-$" para que os hagáis una idea.
Por otro lado, hay que tener en cuenta que para utilizar john como motor de cracking de las contraseñas de los usuarios de Joomla!, debemos usar el formato (--format) "dynamic_1" que corresponde con el que genera Joomla!. El formato "dynamic_1", espera que el fichero que le pasemos como "password file", esté formado de la siguiente forma:
usuario:HASH$SALT
Por lo tanto, debemos extraer los hashes y los salt e introducirlos a un fichero de la forma indicada. Para ello, hemos ejecutado lo siguiente:
tampax@Abyan ~/john-1.7.9-jumbo-7/run $ mysql -uroot -ppass -ssre "use DB_NAME; select username,password from jos_users" | tr ':' '$' | tr '\t' ':' | tr -d ' ' > joomla_passwords
Básicamente lo que hacemos es, seleccionar los campos "username" y "password" de la tabla "jos_users", convertir los carácteres ':' existentes a '$', convertir las tabulaciones a ':' y finalmente quitar los posibles espacios que hayan en los usuarios.
El fichero contiene entre otras, las siguientes lineas:
tampax@Abyan ~/john-1.7.9-jumbo-7/run $ head -n2 joomla_passwords
juan71:b06b5ef56824f0433e5d919484d622ef$s699uDS3JbqgRiam
billyje:cd6a921e5fa65cdecfa4bdde461ff129$d4mCYXpqO2fZBIXS
Nota: hemos decidido borrar los espacios (tr -d ' ') de los nombres de usuario por simple conveniencia.
Una vez tenemos el John The Tipper preparado con todos los ingredientes (set de caracteres propio, fichero formateado correctamente con las contraseñas), lo ejecutamos tal que:
tampax@Abyan ~/john-1.7.9-jumbo-7/run $ ./john --session=joomla_recover --format=dynamic_1 --incremental=custom joomla_passwords
Loaded 3887 password hashes with 3881 different salts (dynamic_1: md5($p.$s) (joomla) [128/128 AVX intrinsics 10x4x3])
Warning: only 62 characters available
111111 (b2i)
010101 (motivama)
101010 (Regla)
111111 (TALUAN)
111111 (dpto)
000001 (juan71)
1111111 (cantarock)
212121 (juferez)
222222 (2222)
113211 (rrivero)
123123 (ave182)
112233 (xxxdesign)
11211121 (cxnimagen)
guesses: 13 time: 0:00:00:17 c/s: 21289K trying: bX6 - baB
En apenas 17 segundos ha encontrado 13 passwords de las 3887 existentes.
Ya solo queda esperar tranquilamente mientras nuestro amigo John hace el trabajo "sucio".
Y nada más, esperamos que os haya aportado una solución :)
Happy cracking!
Abyan.