Seguridad Web

Clase: 3

Instituto Educación IT

Autor: Maximiliano Cañellas

Sobre el curso

Módulo 3/4: Inyecciones SQL

Temas:

· ¿Qué es SQL? · Inyecciones SQL · Tipos de inyecciones SQL · Authentication ByPass · Consultas anidadas · Algunas herramientas: SQLMap, Acunetix

¿Qué es SQL?


El lenguaje de consulta estructurado o SQL (por sus siglas en inglés Structured Query Language) es un lenguaje declarativo de acceso a bases de datos relacionales que permite especificar diversos tipos de operaciones en ellas

Una de sus características es el manejo del álgebra y el cálculo relacional que permiten efectuar consultas con el fin de recuperar de forma sencilla información de interés de bases de datos, así como hacer cambios en ellas.

Algunos ejemplos de este lenguaje (consultas)


Agregar una columna a la tabla

ALTER TABLE 'ALUMNOS' ADD EDAD INT UNSIGNED;

Cláusula select

SELECT matricula, marca FROM Coches  ORDER BY marca,modelo;

Cláusula where

SELECT matricula, marca FROM Coches WHERE matricula = MF-234-ZD';

Inyecciones SQL


Un ataque de Inyección SQL consiste en la inserción o “inyección” de datos en una consulta SQL desde un cliente de la aplicación.

En caso de éxito en una inyección SQL, eventualmente se podria leer datos sensibles de la base de datos, modificar contenido (insertar/actualizar/borrar) y, en algunos casos, ejecutar comandos en el sistema operativo.

OWASP: SQLi

Tipos de SQLi: graphic injection


Se dice que existe o se produjo una inyección SQL cuando, de alguna manera, se inserta o "inyecta" código SQL invasor dentro del código SQL programado, a fin de alterar el funcionamiento normal del programa y lograr así que se ejecute la porción de código "invasor" incrustado, en la base de datos.

Al realizar este tipo de ataque tenemos una respuesta visual del error:


You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''''' at line 1

Ejemplo de código vulnerable:


consulta := "SELECT * FROM usuarios WHERE nombre = '" + nombreUsuario + "';"

Si el operador escribe un nombre, por ejemplo "Maxi", nada anormal sucederá, la aplicación generaría una sentencia SQL similar a la siguiente, que es perfectamente correcta, en donde se seleccionarían todos los registros con el nombre "Maxi" en la base de datos:


SELECT * FROM usuarios WHERE nombre = 'Maxi'

Ejemplo de código vulnerable:


Pero si un usuario malintencionado escribe como nombre de usuario lo siguiente:


Maxi'; DROP TABLE usuarios; SELECT * FROM datos WHERE nombre LIKE '%

Se generaría la siguiente consulta SQL:


SELECT * FROM usuarios WHERE nombre = 'Maxi';
DROP TABLE usuarios;
SELECT * FROM datos WHERE nombre LIKE '%';

En la base de datos se ejecutaría la consulta en el orden dado, se seleccionarían todos los registros con el nombre 'Maxi', se borraría la tabla 'usuarios' y finalmente se seleccionaría toda la tabla "datos", que no debería estar disponible para los usuarios web comunes.

Tipos de SQLi: blind injection


Un ataque blind SQL injection es un caso particular de inyección SQL. Se evidencia cuando un sitio web no muestran mensajes de error pese a la exitosa inyección de código SQL malicioso.

Owasp Blind SQLi reference

Ataques blind SQLi


El problema con los ataques blind SQLi es que no sabemos a ciencia cierta si el resultado de una injección SQL tuvo resultado o no.

Una forma facil de detectar este caso particular de SQLi y es utilizando ataques que se conocen como "time based injections"

Un ejemplo de blind SQLi


Supongamos que tenemos la siguiente URL vulnerable:


http://www.site.com/vulnerable.php?id=1

La forma clásica de probar si es vulnerable a una inyección SQL sería agregar una comilla al final del id del producto:

http://www.site.com/vulnerable.php?id=1'

Pero en blind SQLi esto no produciria ningun resultado visible que nos permita detectar fallas en la aplicación.

Un ejemplo de blind SQLi


Entonces ¿cómo detectamos una inyección de tipo blind?

Volvemos a la URL vulnerable anterior:


http://www.site.com/vulnerable.php?id=1

Ahora además de la comilla inyectamos el siguiente código:

http://www.site.com/vulnerable.php?id=1' waitfor delay '00:00:10'--
En caso de que nuestra inyección sea exitosa, demorariamos la respuesta de la aplicación por 10 segundos, confirmando entonces que la misma es vulnerable.

Authentication Bypass


Authentication ByPass es el nombre de un caso particular de inyección SQL. Esta se da casi exclusivamente en formularios de acceso los cuales, por lo general, chequean las credenciales de acceso contra una base de datos.

Un ejemplo de este caso sería la siguiente consulta:

SELECT * FROM accounts WHERE username='Maxi' AND password='asd123'

La cual podemos atacar mediante el comando:

x' OR '1'='1

Quedando la consulta:

SELECT * FROM accounts WHERE username='Maxi' AND password='x' OR '1'='1'

Consultas anidadas


El operador union es usado en las inyecciones SQL para unir una consulta, lógicamente creada por el auditor, a la consulta original. El resultado deseado es construir una query que ejecute la consulta válida pero además la inyección necesaria.

Ejemplo de consultas anidadas

En el caso de tener la siguiente consulta:

SELECT Name, Phone, Address FROM Users WHERE Id=$id

Usariamos el parámetro id para inyectar el operador union de la siguiente forma:

$id=1 UNION ALL SELECT creditCardNumber,1,1 FROM CreditCardTable

La query final tendria el siguiente aspecto:

SELECT Name, Phone, Address FROM Users WHERE Id=1 UNION ALL SELECT creditCardNumber,1,1 FROM CreditCardTable

Lo que uniría la consulta original del ID con la información de los campos de las tarjetas de crédito de toda la tabla.

Veamos en Mutillidae estos ejemplos de forma práctica


SQLi cheat sheet

Herramientas


¡Fin de la clase! :)

¿Dudas? ¿Preguntas?