Volver |

SQL Injection ciego

Introducción

Se conoce como SQL Injection ciego o a ciegas a una inyección SQL como cualquiera pero con la caracaterística de que la aplicación web no devuelve mensajes de error al ejecutar una sentencia SQL. Es decir, la aplicación web oculta los errores y no da detalles de los mismos y solo devuelve valores booleanes (TRUE o FALSE).

Entonces, la idea principal es ir probando parámetros analizando si la sentencia devuelve TRUE o FALSE.

Existen dos tipos de SQL injection a ciegas: basados en contenido y basados en tiempo

 

SQL Injection ciego basado en contenido

En este tipo de ataque, el atancate verificará si la aplicación es vulnerable comparando los resultados de diferentes consultas que retornarán verdadero (true) o falso(false)

Veamos un ejemplo de un sitio web que busca un item por id y lo muestra por pantalla. Supongamos que que estamos analizando el item con id = 2. La url podría ser algo como:

http://www.tienda-vulnerable/items?id=2

Esta url nos devolverá el html con los datos del item con id 2

Podríamos suponer que la consulta SQL que está utilizando es similar a la siguiente:

SELECT nombre, descripcion, precio FROM items WHERE id = 2

Un atacante podría manipular la url para verificar si el sitio es o no vulnerable. Por ejemplo haciendo una perición a:

http://www.tienda-vulnerable/items?id=2 and 1=2

La sentencia SQL quedaría en este caso como:

SELECT nombre, descripcion, precio FROM items WHERE id = 2 and 1=2

Esto dará FALSE y el item no se mostrará en la página web.

Si ahora intentamos la misma petición pero con los parámetros necesarios para que devuelva TRUE, por ejemplo

http://www.tienda-vulnerable/items?id=2 and 1=1

en donde la sentencia quedaría: SELECT nombre, descripcion, precio FROM items WHERE id = 2 and 1=1

Esto retorna TRUE y el detalle del item se mostrará en pantalla. 

Si esto ocurre, podemos afirmar que la página es vulnerable a SQL Injection a ciegas

 

¿Cómo explotarlo?

Probando distintas consultas y analizando, en este caso, si nos devuelve o no el contenido, es decir si devuelve TRUE o devuelve FALSE.

Por ejemplo, queremos obtener el nombre de la base de datos. En primero lugar trataremos de obtener el largo del nombre, para ello debemos pensar en una sentencia que sirva para obtener el largo pero que solo puede devolver true o false.

Por ejemplo, siguiendo con la consulta anterior, podemos pensar la consulta algo como lo siguiente:

SELECT nombre, descripcion, precio FROM items WHERE id = 2 AND (SELECT LENGTH(database()))=1#

Es decir, la petición debe ser: http://www.tienda-vulnerable/items?id=2 AND (SELECT LENGTH(database()))=1#

Si al colocar esta url en el navegador nos devuelve el item que número 2 quiere decir que la base de datos tiene un nombre de largo 1. En caso contrario, debemos seguir intentando con distintos números hasta la consulta devuelva true y así conocer el largo del nombre de la base de datos.

Bueno esto sería el primer paso, ahora, para conocer el nombre, podemos probar con letra por letra hasta dar con el nombre de la base.

Por ejemplo con un vector de ataque como: AND (SELECT ASCII(SUBSTRING(database(), 1, 1)))=99 

En este caso, si probamos este vector y la aplicación devuelve el contenido quiere decir que el nombre de la base de datos comienza con 'c'.

De esta manera podemos continuar y obtener más información de la estructura de la base de datos y una vez conocida esta de los datos de la misma.

Para esto en primer lugar podemos intentar conocer el largo del nombre de la misma. 

 

SQL Injection ciego basado en tiempo

Otra manera de saber si una aplicación es vulnerable a SQL Injetion es analizando el tiempo de respuesta de una aplicación web si se le pasa un vector de ataque que corresponda a una operación intensiva que consuma mucho tiempo o bien alguna función que produzca un delay tal como la función sleep(). Si se usa un vector de ataque de estas características y la aplicación demora en responder la solicitud, quiere decir que la misma es vulnerable.

Veamos un ejemplo utilizando la función sleep()

Vamos a hacer una petición a http://www.tienda-vulnerable/items pasando como parámetro id=2 AND if(1=1, sleep(7), false). Es decir, quedaria http://www.tienda-vulnerable/items?id=2 AND if(1=1, sleep(7), false).

Ahora, si al hacer la petición, vemos que la misma se demora 7 segundos, estamos en condiciones de afirmar que la aplicación es vulnerable y ya podemos empezar a inyectar nuestros vectores de ataque como mostramos anteriormente.

Enlaces

En este artículo participaron: