7. SQL injection
SQL Injection (SQLi)
SQL Injection. Es una vulnerabilidad que manipula consultas a bases de datos SQL legitimas para obtener información sensible almacenado en las bases de datos. La información puede variar, desde información de los clientes, información del mismo sistema, credenciales privilegiadas o credenciales de otros usuarios. En algunos casos, el atacante incluso tiene la posibilidad de modificar o eliminar los datos dentro de la base de datos causando cambios persistentes en el contenido o comportamiento.
Detección
Es posible detectar este tipo de vulnerabilidades de forma manual usando una serie de pruebas semánticas en cada punto de entrada de la aplicación además de la existencia de múltiples herramientas que automatizan la labor, entre las que destaca sqlmap por su popularidad, eficiencia y simplicidad.
Ejemplos
Un escenario puede darse en el sitio web de una tienda que muestra los productos en diferentes categorías. Cuando el usuario da click en la categoría Gifts, el buscador realiza una petición al URL: https://insecure-website.com/products?category=Gifts Lo que causa que la aplicación realice una consulta SQL para retornar los detalles relevantes de los productos almacenados en la base de datos, la consulta completa, usando el valor Gifts obtenido desde el parámetro category podría verse así: SELECT * FROM products WHERE category = 'Gifts' AND released = 1 Lo que se traduce en una petición que retorne:
Todos los detalles (
SELECT *)De la tabla productos (
FROM products)Donde la categoría sea
Gifts(WHERE category = 'Gifts')Y el valor de
releasedsea igual a1, lo que puede significar que el siguiente parámetro sea que el producto ya esté a la venta y que nos ayuda a inferir la existencia de productos con valorreleasediferente a1que no se encuentren a la venta actualmente (AND released = 1) En este escenario, la aplicación no implementa defensa alguna contra SQL injection. Lo que significa que el atacante puede manipular la consulta para envenenarla para alterar su comportamiento como en el siguiente ejemplo:https://insecure-website.com/products?category=Gifts'--Lo que resultaría en la siguiente consulta:SELECT * FROM products WHERE category = 'Gifts'--' AND released = 1Truncando la consulta hasta acabar el filtro por categoría igual aGiftsal inyectar los caracteres--que son reservados para los comentarios dentro de SQL al igual que el conjunto de caracteres/*
comentarios simples Los comentarios simples comienzan con dos guiones consecutivos (--) y finalizan con el final de línea. comentarios compuestos Los comentarios compuestos empiezan por /* y finalizan por */ - IBM Docs
Lo que significa que todo después de los caracteres -- será invalidado, en este caso, no se aplicará el filtro released = 1 anidado haciendo que la consulta: SELECT * FROM products WHERE category = 'Gifts'--' AND released = 1 Sea equivalente a solo: SELECT * FROM products WHERE category = 'Gifts' Derivando en retornar todos los productos de la categoría Gifts incluyendo los no puestos a la venta aún. Puedes usar un ataque similar para causar que la aplicación muestre todos los productos en cualquier categoría, incluyendo esos productos de los que no conoces su categoría: https://insecure-website.com/products?category=Gifts'+OR+1=1-- Esto resulta en la siguiente consulta SQL: SELECT * FROM products WHERE category = 'Gifts' OR 1=1--' AND released = 1 La consulta modificada retorna:
Todos los productos (
SELECT * FROM products)Donde la categoría sea igual a
Gifts(WHERE category = 'Gifts')O todo lo demás (
OR 1=1--) Este último puede ser el más confuso de todos, pero revisando de cerca puedes ver que el fragmento de consulta indica una condición, que se puede leer así Que se cumpla X condición o 1=1-- donde X es el filtro por categoríaGiftsentonces también sería equivalente a Que la categoría sea igual a Gifts o 1=1-- La parte de1=1es una operación condicional simple, que resulta en verdad, se puede leer de la siguiente forma ¿Uno es igual a cero? y el resultado que sería true o verdad sería el cual funcionara como parámetro a evaluar, lo que significa que también la consulta equivale a Que la categoría sea igual a Gifts o verdad-- Ahora es cuestión de aislar los filtros para entender su resultado, los filtros serían categoría igual a Gifts y Categoría igual a verdad, el primero es intuitivo, pero el segundo no tanto, pero lo único que se tiene que entender es que evalúa la existencia de Categoría, indistintamente de su valor, lo que significa que no importa cual sea su Categoría siempre y cuando exista, entonces los filtros también se pueden leer como Que la Categoría sea igual a Gifts o que contenga una Categoría, terminando en una lectura simple y amigable después de todo el proceso ==Selecciona todos los productos que su categoría sea igual a Gifts o que tengan categoría== En un inicio puede parecer un proceso complejo, por lo que recomiendo asentar bases de lógica matemática sí se busca profundizar en las consultas de bases de datos, además de estudiar conjuntos y todo tema teórico que ayude a su comprensión.
Cuando se realice una consulta a una base de datos que involucre
1=1y métodos de alteración o destrucción como lo son UPDATE y DELETE, ya que puedes alterar todos los datos dentro de la tabla o todos los datos globales.
Este mismo concepto se puede extrapolar en consultas más sensibles, como consultas a bases de datos durante un formulario de inicio de sesión, un ejemplo puede ser un formulario con los campos Username y Password los cuales manda los valores al back-end para hacer una consulta a la base de datos que podría ser la siguiente: SELECT * FROM users WHERE username = '' AND password = '' Así quedaría en un ejemplo práctico donde usemos un supuesto username con valor winie y un password de valor peter que son credenciales legitimas, la consulta final se vería de la siguiente forma: SELECT * FROM users WHERE username = 'winie' AND password = 'peter' La consulta retornará un resultado existente, lo que corrobora el correcto empate entre usuario y contraseña registrado en una base de datos. Pero usando la misma metodología basada en una operación lógica que devuelva verdad como resultado, seguido de caracteres para comentar y anular el resto de la consulta, podemos crear una consulta maliciosa que nos ayuda a evadir la necesidad de empate entre usuario y contraseña, podemos usar un username existente conocido, en este caso el mismo winie pero dentro del campo password en vez de poner la contraseña legítima, se manda el payload que truncará la consulta y evitará empatar usuario y contraseña ' OR 1=1-- Lo que nos dejará con una consulta final: SELECT * FROM users WHERE username = 'winie' AND password = '' OR 1=1-- Que se puede leer como Selecciona todos los usuarios donde username sea igual a winie y password vacía o verdad que a su vez se puede leer como Selecciona todos los usuarios donde username sea igual a winie y password vacía o que contenga contraseña y así haciendo una consulta que en caso de existencia de un usuario de nombre winie y que tenga contraseña, entonces devuelva el usuario, permitiendo el acceso a la cuenta de usuario. En el supuesto anterior, se conocía previamente el nombre de usuario winie y su contraseña, pero un atacante puede probar con cualquier nombre de usuario, incluso probando con los nombres de usuario con privilegios más habituales como admin, y que al tampoco requerir la contraseña real del usuario, puede acceder de forma ilegítima sustituyendo el nombre de usuario winie por el deseado, dejando una consulta: SELECT * FROM users WHERE username = 'admin' AND password = '' OR 1=1-- Que le brindará privilegios administrativos.
References
Last updated