Inyección Sql es una vulnerabilidad muy conocida, existen diversidad de documentos explicando su peligrosidad y explotación, sin embargo, en la actualidad muchos sitios web son vulnerables a este ataque. Por este motivo decidí escribir sobre este tema, para crear un poco de conciencia y mostrar que a pesar de que es una técnica antigua es muy fácil, hasta sin el uso de herramientas, obtener información de la base de datos de la entidad.
Este ataque consiste en introducir sentencias SQL en variables que puedan ser controladas por el usuario final, permitiéndole tener acceso a la base de datos desde su navegador. Si una aplicación web posee este tipo de fallo, el atacante podrá leer, modificar, eliminar y crear registros de la base de datos, dependiendo de los privilegios o permisos que posea este usuario. Todo esto es posible debido a una mala validación o filtrado de las variables que son enviadas al servidor, de esta manera se permite la manipulación de la consulta original por una creada por el atacante. Estas variables pueden ser llevadas tanto por el método POST, GET o por medio de las cabeceras http.
En este post solo hablaré de uno de los tipos de inyección sql, la basada en mensajes de error, la cual se caracteriza porque al insertar un carácter de sql en una variable vulnerable, presentará en el navegador el error ocasionado a la consulta original. De esta manera nos permite obtener información sobre el motor de base de datos usado o sobre la estructura de la consulta.
Para identificar si una aplicación es vulnerable a este tipo de ataque, se debe recorrer y analizar todo el sitio web en busca de las variables en donde el usuario pueda ingresar datos, en este caso código sql. Una vez obtenido todos los puntos de entrada, se prueba cada uno de ellos en busca de esta clase de fallo, insertando caracteres usados en sql para modificar la consulta que se esté realizando, como por ejemplo:
Se tiene el siguiente sitio, en el cual se usa la variable id para identificar una página y cargar su contenido en el navegador:
www.vulnerable.com/index.php?id=2
Se inserta uno de los símbolos usados en sql para modificar la consulta y tratar de provocar un error.
www.vulnerable.com/index.php?id=2’
Al realizar la petición nos traerá como respuesta el error generado en la base de datos con información que nos permitirá identificar qué tipo de motor de base de datos se está usando, para este ejemplo es MySql.
A continuación, se intentará obtener el número de campos que se están utilizando en la consulta. Esto se logra usando la instrucción order by acompañada de un valor que deberá estar dentro del rango campos que tenga la consulta, puesto que si se sobrepasa mostrará error, como se observa en la siguiente imagen.
Como se puede observar en la anterior imagen, para este ejemplo el error se presenta al darle el valor de 12, por lo que se deduce que el número correcto de campos que posee la consulta es de 11. Obtenido este dado, se intentará sacar información adicional agregándole una consulta creada por nosotros, para ello se hará uso de la instrucción unión, que nos permitirá unificar en una sola las dos consultas: la nuestra con la original. Para poder usar esta sentencia correctamente se debe, junto con la sentencia select, especificarle el número de campos de la consulta original, como se presentará a continuación:
www.vulnerable.com/index.php?id=-2 union select 1,2,3,4,5,6,7,8,9,10,11--
Para facilitarnos la obtención de información, a la variable id se le colocará un valor inexistente, de esta manera no presentará el contenido de la página solicitada en el navegador, permitiendo así ver el resultado de nuestra consulta, la cual arrojará el número del campo del select que se usará para obtener más información sobre la base de datos.
Como se sabe que el motor de base de datos usado es MySql, se podrá recolectar información de la base de datos usando algunas funciones que éste posee para este fin, como lo son:
- versión(): muestra la versión de la base del servidor
- user(): presenta el nombre del usuario y del host
- database(): devuelve el nombre de la base de datos
En la siguiente dirección se encuentra un listado más amplio:
http://dev.mysql.com/doc/refman/5.0/es/information-functions.html
Teniendo en cuenta el listado anterior presentaré un ejemplo usando una de las funciones, la cual nos dirá el nombre de la base de datos.
www.vulnerable.com/index.php?id=-2 union select 1,2,3,database(),5,6,7,8,9,10,11--
Otra forma de recolectar información es por medio de information_schema, la cual nos permitirá recurrir a los metadatos de la base de datos que contenga el servidor MySql, de la siguiente forma:
www.vulnerable.com/index.php?id=-2 union select 1,group_concat(table_name),3,4,5,6,7,8,9,10,11 from information_schema.tables--
Con la anterior consulta, buscamos obtener todos los nombres de las tablas que se encuentran en la base de datos de information_schema. Para hacerlo mas rápidamente, usé la función group_concat() la cual, me traerá en un string la concatenación de todas las tablas.
Hay una tabla usuarios, como lo que me interesa, para esta ocasión, son las credenciales de los usuarios, extraeré las columnas de esa tabla de la siguiente forma:
www.vulnerable.com/index.php?id=-2union select 1,group_concat(column_name),3,4,5,6,7,8,9,10,11 from information_schema.columns where table_schema=’BasedeDatos’ and table_name=’usuarios’—
El error que nos muestra es porque esta filtrando la comilla simple, para saltarnos ese filtrado lo codificare en hexadecimal.
www.vulnerable.com/index.php?id=-2union select 1,group_concat(column_name),3,4,5,6,7,8,9,10,11 from information_schema.columns where table_schema=0x4261736564654461746f73 and table_name=0x7573756172696f73—
Por último, obtenemos los valores de las dos columnas: usuario y password.
www.vulnerable.com/index.php?id=-2union select 1,group_concat(usuario),group_concat(password),4,5,6,7,8,9,10,11 from usuarios—
Como se puede apreciar en la imagen anterior, ya tenemos las credenciales de los usuarios., lo cual fue muy fácil. Aclaro nuevamente, no todos los sitios se explotan de la misma forma, ni se podrá obtener toda la información que deseemos, todo dependerá de los privilegios que tenga el usuario, del motor de base de datos y de los errores que se hayan cometido al programarlo.
Existen multitud de herramientas que son usadas para la explotación de este tipo de vulnerabilidades, las cuales permitirán la automatización de este ataque, tales como, sqlmap, sqlInjector, m4x, pangolín, SQlier, SQLier entre otras. En el siguiente enlace se encuentra un listado de varias tools con su respectivo sitio de descarga:
http://www.hackplayers.com/2008/08/herramientas-sql-injection.html
Saludos!
Este articulo lo escribí inicialmente para Flu-Project, se puede acceder a el siguiendo este link: http://www.flu-project.com/inyeccion-sql-a-pesar-del-tiempo-aun-sigue-vigente.html