Buen día.
Siguiendo nuestra
racha de publicaciones acerca de Joomla, hoy vamos a tratar de
explicar el funcionamiento en cuanto al manejo de password , y
también miraremos paso a paso cómo podemos crear nuestra propia
tool para crackear dichas password. Espero que lo disfruten y que lo
aprovechen, he de suponer que esto será de más ayuda para los
defacer y pentester, pero igualmente va dirigido a todos.
En principio muchos
habrán notado que Joomla tiene una manera peculiar de almacenar la
información en la base de datos, por ejemplo, para los datos de
usuario tenemos que generalmente siguen esta estructura.
admin : d2552f10d5944bd1a35bcd4698f875ca : cViv5nlotJsHIP5g
user2 : a5180b2c5080dd5278f54e36a87fefbb : 69Gn7Z4m4I58djM1
user3 : 5011972ed6674b7a23df71e974c90c33 : ewewzsIWDAAtE5yn
Si miramos con detenimiento, podemos determinar varias características particulares de está estructura, por ejemplo observamos que hay 3 tipos de datos que están separados por “:”, y como estamos hablando de los datos que son usados para el inicio de sesión de un usuario, sabemos que el primer dato corresponde al nombre de Usuario, el segundo dato al Hash generado por la contraseña y el último dato es algo conocido como Salt, ya vamos a hablar más acerca de él.
¿Pero
en realidad cómo funciona un sistema de Logueo de usuarios?, aunque
existen muchas maneras de hacer un sistema de logueo, todos se basan
sobre el mismo principio, y es la verificación de los datos
ingresados por el usuario con los datos previamente almacenados en
la base de datos, para ver esto un poco más claro, vamos a colocar
un código básico en php.
<?php
$usuario=$_POST['user']; //recibimos
el usuario
$password=$_POST['password']; //recibimos
la password
$Query=Mysql_query(
“SELECT * FROM usuarios WHERE user='$usuario' AND pass='$password'” ); //hacemos la petición a la base de datos
if
(Mysql_num_rows($Query)>0){ //verificamos los datos
print('Bienvenido al Sistema'); //verificación exitosa
}else{
print('Usuario y/o contraseña,
erróneos'); //verificación fallida
}
?> |
Bueno, quizás algunos hayan notado que el código de ejemplo es vulnerable a SQL Inyección, pero ese es tema de otro post, así que concentrémonos; cómo podemos observar, nosotros recibimos dos datos que nos envía el cliente, en este caso recibimos el ‘user’ y el ´password´, y los almacenados en variables, después hacemos una consulta a la base de datos con los parámetros que hemos obtenido, en este caso la consulta consiste en verificar que en la tabla ‘usuarios’ exista un dato o un registro que cumpla con dos requerimientos. El primero es que la columna ‘user’ coincida con la variable $usuario y el segundo requerimiento es que la columna ‘pass’ coincida con la variable $password (con el AND indicamos que es obligatorio el cumplimiento de ambas).
Entonces
el sistema de login simplemente consiste en una verificación de los
datos ingresados con los datos almacenados, pero tenemos que en
Joomla esta información se guarda con un parámetro adicional, el
tan conocido Salt. ¿Pero qué es el Salt?, en principio lo podemos
definir como una cadena de tipo string o integer, que es generada
aleatoriamente y que es adicionada a la contraseña antes de
guardarse en la base de datos, veamos un ejemplo de cómo funciona o
se genera.
1)
Tenemos que al momento del registro, nosotros ingresamos nuestro
usuario, en este caso nos llamaremos TrackMaze.
$usuario=”TrackMaze”;
|
2)
También tenemos que definir una contraseña, así que utilizaremos
“HackingAndSecurity”.
$password=”HackingAndSecurity”;
|
3)
Pero ahora solo nos falta el Salt, y como ya lo definimos
anteriormente, tenemos que Joomla lo genera utilizando una función
interna llamada getSalt, el cual nos genera una cadena alfanumérica
de N Bytes y que posteriormente utilizaremos después (leer
openssl_random_pseudo_bytes).
$salt=getSalt();
|
Una
vez obtenidos todos los datos, tenemos que en la base de datos no se
guarda la contraseña en texto claro, sino que por defecto se utiliza
la función hash MD5
sobre la contraseña y se almacena el hash generado, pero no podemos
olvidar el Salt, dado que este debe concatenarse con la contraseña
antes de generar hash, de la siguiente manera.
$crypto=md5($password.$salt); //concatenamos
|
Bueno,
en este punto es donde almacenamos todos estos datos en la base de
datos, pero debemos tener en cuenta que el usuario jamás sabrá o
conocerá que Salt se le ha asignado a su password, entonces al
momento de hacer la verificación de logueo no lo podrá hacer, por
ende también debemos guardar el Salt en la base de datos y así
cuando se intente verificar un usuario, después de que dicho usuario
exista, utilizaremos el Salt que tiene asignado y volveremos a
calcular el hash con la password que ingreso, y si este coincide, el sistema le da paso afirmativo a su ingreso.
Y
ahora si vamos con el hacking, teniendo los datos de
Usuario:Hash:Salt de una base de datos a la que tuvimos acceso (legal
- ilegal) a dichos datos, nos sería de gran utilidad saber la
password original en texto plano de un usuario cualquiera
(generalmente el admin). ¿pero cómo lo podremos hacer?.
En
nuestro poder tenemos tanto el Hash del Password+Salt y además
también conocemos el Salt utilizado, entonces tenemos varias
opciones de ataque, pero fundamentalmente la misma, en este caso por
ejemplo tenemos los siguientes datos:
Usuario
|
Hash | Password + Salt
|
Salt
|
admin | d2552f10d5944bd1a35bcd4698f875ca | cViv5nlotJsHIP5g |
user2 | a5180b2c5080dd5278f54e36a87fefbb | 9Gn7Z4m4I58djM1 |
user3 | 5011972ed6674b7a23df71e974c90c33 | ewewzsIWDAAtE5yn |
Lo que podemos hacer
es utilizar una lista N de posibles password, y como ya conocemos el
Salt utilizado, entonces volvemos a generar el
$crypto=md5($password.$salt); pero cada vez con un password distinto
siempre verificando si este nuevo hash es coincide con el que ya tenemos (el
de la BDD original) en caso de ser verdadero, quiere decir que el
password que hemos utilizado para hacer el ataque, es el mismo que
utilizo dicho usuario para registrarse en el sistema.
Basicamente en eso
consiste todo, probar cientos de miles de posibles password
concatenadas con el Salt y generar su respectivo hash en MD5, pero
verificando si este coincide con el almacenado en la base de datos.
Hay dos variaciones de este ataque.
1) Ataque por Fuerza
Bruta:
Consiste en probar
todas las posibles password de longitud N, por ejemplo tenemos que
empezamos con “aaaa”, luego iremos probando con “aaab”,
luego con “aaac” ,y al final culminaremos con “zzzz”. También
se pueden utilizar caracteres numéricos y especiales.
2) Ataque por
Diccionario:
Bueno, este ataque
es un poco más especializado, consiste en probar palabras de
diccionario o palabras comunes de un vocabulario, esto se debe a que
muchas personas generalmente las utilizan de password, por ejemplo
tenemos las password por defecto, “admin”, “root”, “toor”,
“1234” y también tenemos otras que son las comunes como nombres
de ciudades, países, mascotas, personas, etc..
Nuestra TOOL
consiste en el manejo de dos archivos, el primero de ellos será el
diccionario (la tecnica 2) que utilizaremos para hacer el ataque, este será un
archivo preferiblemente .txt y en donde cada posible password esta
separa por un salto de línea (enter), hacemos enfasis en esto, dado que nuestro programa esta diseñado para que en cada salto de linea reconozca un password distinto, entonces así no tendremos ningún inconveniente a la horad de utilizarlo. Después tenemos nuestro
segundo archivo que será el de los datos a crackear, en este deben
seguir el formato propio de Joomla y también separando los datos de cada nuevo usuario con un salto de linea, como lo podemos observar.
También adjuntamos nuestra tool y un pequeño diccionario de 4,4MB posibles password, espero que lo disfruten:
Descarga: http://www.4shared.com/rar/OU6o3zWR/JoomlaCracker.html
Pass: trackmazehg
Bytez.
Izquierda esta el diccionario | Derecha estan los datos a Crackear |
Lo que hacemos es un
manejo sencillo de archivos con python, separamos todas las password
del diccionario utilizando el atributo archivo.readlines(), quien nos devuelve una lista (array) con todos los datos que esten separados por un salto de linea, por ejemplo, si tenemos el siguiente archivo:
Al aplicarle el atributo .readlines(), nos devolvera una lista de este tipo:
o de este tipo:
¿Pero por qué dos tipos distintos de listas?, lo que sucede es que según nuestro sistema operativo, solo voy a suponer que usamos Windows y Linux, los saltos de linea son interpretados de manera diferente, en este caso nuestro primer ejemplo de "\n" es en Windows, y él "\r\n" es el Linux. Pero ¿por qué hacer esta aclaración?, pues como ya lo habran notado, nosotros no necesitamos esos caracteres, entonces es necesario quitarlos de la palabra original para seguir el proceso normal, y esto lo hacemos declarando dos variables seguidas con el atributo .replace("x","") quien como su nombre lo indica, nos remplaza una cadena por otra.
He de destacar que aunque en Linux se utiliza "\r\n", con estas dos sentencias estamos definiendo que nuestro code funcione en ambos sistenas (win, linux) sin generar problema, ps estamos eliminando ambos caracteres y no es necesario poner .replace("\r\n","") dado que primero eliminamos el "\n" y luego el "\r" y si no existen, tampoco nos genera ningún tipo de error.
Este proceso lo hacemos tanto para sacar los datos a Crackear como para sacar los datos que estan dentro del diccionario y para esto tenemos definidas respectivamente las funciones:
Me veo en la necesidad de decir, que este código esta hecho en python2.7, y es por esto que a muchos les dará algunos errores, pues pueden estar utilizando un python anterior o el más reciente python3. ¿Cómo lo solucionamos?, fácil, si estas en Linux y actualizas automaticamente el paquete de python quiere decir que el anterior se conserva, simplemente deja de ser llamado al momento de teclear por consola:
# python
Pero no se elimina o se borra por complero, así que ellos pueden probar algo como:
# python2.7 JoomlaCracker.py
Y solo con eso estarán utilizando python2.7 para correr el programa. El code funciona tanto en windows como en linux sin ningún inconveniente, aunque de ser lo contrario, rogamos enormemente que nos avisen para corregirlo lo más pronto posible.
Juanita
Pedrito
Marianita
Danielita
Al aplicarle el atributo .readlines(), nos devolvera una lista de este tipo:
["Juanita\n", "Pedrito\n", "Marianita\n", "Danielita\n"]
o de este tipo:
["Juanita\r\n", "Pedrito\r\n", "Marianita\r\n", "Danielita\r\n"]
¿Pero por qué dos tipos distintos de listas?, lo que sucede es que según nuestro sistema operativo, solo voy a suponer que usamos Windows y Linux, los saltos de linea son interpretados de manera diferente, en este caso nuestro primer ejemplo de "\n" es en Windows, y él "\r\n" es el Linux. Pero ¿por qué hacer esta aclaración?, pues como ya lo habran notado, nosotros no necesitamos esos caracteres, entonces es necesario quitarlos de la palabra original para seguir el proceso normal, y esto lo hacemos declarando dos variables seguidas con el atributo .replace("x","") quien como su nombre lo indica, nos remplaza una cadena por otra.
delete1=dato[x].replace("\n","")
y
delete2=delete1.replace("\r","")
He de destacar que aunque en Linux se utiliza "\r\n", con estas dos sentencias estamos definiendo que nuestro code funcione en ambos sistenas (win, linux) sin generar problema, ps estamos eliminando ambos caracteres y no es necesario poner .replace("\r\n","") dado que primero eliminamos el "\n" y luego el "\r" y si no existen, tampoco nos genera ningún tipo de error.
Este proceso lo hacemos tanto para sacar los datos a Crackear como para sacar los datos que estan dentro del diccionario y para esto tenemos definidas respectivamente las funciones:
- Recoleccion(direccion): #obtenemos todos los datos a crackear
- Diccionario(dicc): #Creamos la lista de password que estaba en el archivo .txt
- Cracker(palabra, datos): #le pasamos la palabra y una lista con 3 datos (usuario:hash:salt)
- empezar(u_diccionario,u_datos): #esta es la funcion madre
Me veo en la necesidad de decir, que este código esta hecho en python2.7, y es por esto que a muchos les dará algunos errores, pues pueden estar utilizando un python anterior o el más reciente python3. ¿Cómo lo solucionamos?, fácil, si estas en Linux y actualizas automaticamente el paquete de python quiere decir que el anterior se conserva, simplemente deja de ser llamado al momento de teclear por consola:
# python
Pero no se elimina o se borra por complero, así que ellos pueden probar algo como:
# python2.7 JoomlaCracker.py
Y solo con eso estarán utilizando python2.7 para correr el programa. El code funciona tanto en windows como en linux sin ningún inconveniente, aunque de ser lo contrario, rogamos enormemente que nos avisen para corregirlo lo más pronto posible.
Si tienen alguna
duda siempre serán bienvenidas y respondidas los antes posible.
Espero que lo hayan disfrutado y entendido, cualquier cosa, el equipo
TrackMaze estará disponible para ayudarlos…
También adjuntamos nuestra tool y un pequeño diccionario de 4,4MB posibles password, espero que lo disfruten:
Descarga: http://www.4shared.com/rar/OU6o3zWR/JoomlaCracker.html
Pass: trackmazehg
Bytez.
No hay comentarios:
Publicar un comentario