SQL-Inyection

Diciembre 24, 2023

Introducción

Un ataque de SQL-Inyection permite a un atacante manipular las consultas SQL que una aplicación web envía a su base de datos. La mayoría de las aplicaciones web necesitan tener interacción con la base de datos a través de consultas SQL.

Un ataque SQL-Inyection se produce cuando un atacante consigue insertar instrucciones SQL maliciosas en los campos de entrada de una aplicación web, consiguiendo alterar el funcionamiento normal de la consulta.

Funcionamiento

En las páginas web, la mayoría de estas reciben datos a través de formularios, cuando estos campos no están correctamente sanetizados pueden darse este tipo de ataques.

Un ejemplo de esto podría ser cuando un usuario solicita un nombre de usuario y contraseña, un atacante podría insertar el siguiente código como instrucción maliciosa para tratar realizar el login en la aplicación sin necesidad de introducir las credenciales válidas.

' OR '1' = '1' -- -

Con la inyección de este último código estaríamos modificando la consulta original y haría que la condición siempre sea verdadera, consiguiendo eludir la autenticación y conseguir el acceso a la información no autorizada.

Ejemplo SQL-Inyection

Imaginemos el siguiente caso. Disponemos de una aplicación web y queremos comprobar que esta es vulnerable a un ataque SQLInyection.
El código en la consulta SQL podría quedar de la siguiente manera.

SELECT * FROM usuarios WHERE nombre_usuario = 'usuario' AND contraseña = 'clave';

Si realizamos el ataque en el campo del usuario introduciendo una consulta maliciosa, como podría ser:

' OR '1' = '1' -- -

En caso de ser vulnerable, estaremos modificando la consulta original creando una nueva consulta maliciosa que quedaría de la siguiente manera:

SELECT * FROM usuarios WHERE nombre_usuario = '' OR '1' = '1' -- -' AND contraseña = 'clave';

En este caso específico, las comillas simples realizar el cierre de la cadena usuario, seguido del código malicioso ‘ OR ‘1’ = ‘1’. Este código malicioso le está indicando a la base de datos que en el caso de que el usuario sea ‘ ‘ o 1 sea igual 1 (condición verdadera) nos devuelva toda la información de la tabla usuarios. El doble guion se utiliza para indicar a la base de datos que resto de texto que sigue en la consulta sea interpretado como un comentario, evitando de esta forma que la consulta sea errónea.

Detección de vulnerabilidad

Puede que hayamos encontrado en alguna aplicación un punto de ataque con las siguientes características.

'
"
`
')
")
`)
'))
"))
`))

Al realizar este tipo de ataque puede que nos muestre información relacionada con el error en la misma página, facilitando la detección de la vulnerabilidad.

Cierre de la consulta

MySQL
#comentario
-- comentario [Nota: espacio después de los dos guiones]
/*comentario*/
/*! MYSQL Special SQL */

PostgreSQL
--comentario
/*comentario*/

MSQL
--comentario
/*comentario*/

Oracle
--comentario

SQLite
--comentario
/*comentario*/

Es importante, cuando realizamos este tipo de ataque comentar el resto de la inyección para que la consulta sea válida. Dependiendo de la base de datos a la que estemos realizando la consulta SQL deberemos utilizar un estilo de comentario u otro.

Añadiendo complejidad a la consulta

Este tipo de taques son posibles porque en ningún momento se realiza la comprobación si la entrada proporcionada por el usuario se ajusta a los valores esperados por la aplicación. Es muy importante realizar este tipo de saneamiento con el fin de evitar entradas ilegales.
Como ejemplo, en el caso de que coincida con la cuenta del administrador o el nombre de algún usuario un atacante podría realizar el inicio de sesión como ese usuario sin la necesidad de conocer la contraseña.

admin' -- -

La sentencia que modificamos queda de la siguiente manera.

select * from usuarios where username = 'admin' -- - and password = ' '

La cláusula WHERE es la responsable de validar que los campos username y password sean correctos.

Mediante la siguiente consulta nos estaremos autenticando como un usuario inexistente en la tabla usuarios suponiendo que la tabla cuenta con 4 campos.

' union select 1, 'usuario_inexistente', 'contraseña nueva', 1 -- -

La sentencia que modificamos queda de la siguiente manera.

select * from usuarios where username = '' union select 1, 'usuario_inexistente', 'contraseña nueva', 1 -- - and password = ''

Conclusión

Es de vital importancia realizar correctamente la sanetización de la entrada de los datos que realiza el usuario ya que si no lo hacemos correctamente podrían realizar este tipo de ataque llegando a comprometer el servidor.


Dejo por aquí el pasado artículo sobre la herramienta Wfuzz.

«Herramienta de penetración y evaluación de seguridad. Esta herramienta es capaz de realizar ataques de fuerza bruta contra aplicaciones web»

Enlace: Wfuzz.