SQLI guide
Guía sobre SQLI
Certificaciones
- eWPT
- eWPTXv2
- OSWE
- BSCP
Descripción
Explicación técnica de la vulnerabilidad SQLI. Detallamos cómo identificar y explotar esta vulnerabilidad, tanto manualmente como con herramientas automatizadas. Además, exploramos estrategias clave para prevenirla, incluyendo el uso de consultas parametrizadas y buenas prácticas de seguridad
¿Qué es una inyección SQL?
La inyección SQL (SQLi) es una vulnerabilidad de seguridad web que permite a un atacante interferir con las consultas que una aplicación realiza a su base de datos. Esto puede permitir que un atacante vea datos que normalmente no debería poder recuperar, lo que podría incluir datos que pertenecen a otros usuarios o cualquier otro dato al que la aplicación tenga acceso
En muchos casos, un atacante puede modificar o eliminar estos datos, causando cambios persistentes en el contenido o el comportamiento de la aplicación. Hay casos en los que un atacante puede escalar un ataque de inyección SQL para comprometer el servidor subyacente u otra infraestructura de backend. Además de esto, también puede permitirles realizar ataques de denegación de servicio
Inyección SQL en diferentes partes de la consulta
La mayoría de las vulnerabilidades de inyección SQL ocurren dentro de la cláusula WHERE de una consulta SELECT, sin embargo, las vulnerabilidades de inyección SQL pueden ocurrir en cualquier parte de la consulta y dentro de diferentes tipos de consultas. Algunas otras ubicaciones comunes donde surgen inyecciones SQL son:
- En sentencias - UPDATE, dentro de los- valores actualizadoso en la cláusula- WHERE
- En sentencias - INSERT, dentro de los- valores insertados
- En sentencias - SELECT, dentro del- nombre de la tablao- nombre de la columna
- En sentencias - SELECT, dentro de la cláusula- ORDER BY
Tipos de inyecciones SQL
- SQL injection with filter bypass - https://justice-reaper.github.io/posts/SQLI-Lab-18/ (PostgreSQL) 
- Blind SQL injection with out-of-band data exfiltration - https://justice-reaper.github.io/posts/SQLI-Lab-17/ (Oracle) 
- Blind SQL injection with time delays and information retrieval - https://justice-reaper.github.io/posts/SQLI-Lab-15/ (PostgreSQL) 
- Visible error-based SQL injection - https://justice-reaper.github.io/posts/SQLI-Lab-13/ (PostgreSQL) 
- Blind SQL injection with conditional errors - https://justice-reaper.github.io/posts/SQLI-Lab-12/ (Oracle) 
- Blind SQL injection with conditional responses - https://justice-reaper.github.io/posts/SQLI-Lab-11/ (PostgreSQL) 
- SQL injection UNION attack - https://justice-reaper.github.io/posts/SQLI-Lab-10/ (PostgreSQL) - https://justice-reaper.github.io/posts/SQLI-Lab-6/ (Oracle) - https://justice-reaper.github.io/posts/Validation/ (MariaDB) - https://justice-reaper.github.io/posts/GoodGames/ (MySQL) 
- SQL injection into outfile - https://justice-reaper.github.io/posts/Validation/ (MySQL) 
- SQL injection read files - https://justice-reaper.github.io/posts/Union/ (MySQL) 
- SQL injection vulnerability allowing login bypass - https://justice-reaper.github.io/posts/SQLI-Lab-2/ 
Cheatsheet
Usaremos estas cheatsheet para facilitar la detección y explotación de esta vulnerabilidad:
- Hacking tools https://justice-reaper.github.io/posts/Hacking-Tools/
¿Cómo detectar y explotar una inyección SQL?
Teniendo en cuenta que los términos y herramientas mencionados a continuación se encuentran en la cheatsheet mencionada anteriormente, llevaremos a cabo los siguientes pasos:
- Instalarlas extensiones- Active Scan ++,- Error Message Checks,- Additional Scanner Checks,- Collaborator Everywherey- Backslash Powered Scannerde- Burpsuite
- Añadirel- dominioy sus- subdominiosal- scope
- Hacer un - escaneo generalcon- Burpsuite. Como- tipo de escaneomarcaremos- Crawl and audity como- configuración de escaneousaremos- Deep
- Escanearemos partes específicas de la peticiónusando el- escáner de Burpsuite. Para- escanearlos- insertion pointsdebemos seleccionar en- tipo de escaneola opción- Audit selected items
- Analizar la query con sqlmap 2 veces, debido a que- puede fallar en ocasiones
- Analizar la query con ghauri 2 vecespara- confirmar que sqlmap no se saltó nada
- Realizar un - ataque de fuerza brutacon el- Intrudery los- diccionariosde- Loxs. Si no encontramos nada, usaremos los- payloadsde los- diccionariosmencionados en- hacking toolsque contengan- payloadsde- SQLIy si tampoco encontramos nada, usar la extensión- Agarthade- Burpsuite. Es recomendable setear la opción- Delay between requestsen- 1y desactivar el- Automatic throttlingpara que- el tiempo de respuesta del servidor varíe lo menos posible. También debemos- disminuirel- número de hilospara- no colapsarel- servidor
- Si lo anterior no funciona, nos centraremos en buscar - inyecciones SQL de forma manualutilizando las- cheatsheetsde- Portswigger,- PayloadsAllTheThingsy- Hacktricks. Si vemos- payloadso- diccionariospara aplicar- fuerza brutadebemos probarlos
Prevenir inyecciones SQL
Se puede prevenir la mayoría de los casos de inyección SQL utilizando consultas parametrizadas en lugar de concatenación de cadenas dentro de la consulta. El siguiente código es vulnerable a inyección SQL porque la entrada del usuario se concatena directamente en la consulta
1
String query = "SELECT * FROM products WHERE category = '"+ input + "'"; Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery(query);
Reescribiendo el código de manera segura, evitamos que la entrada del usuario interfiera con la estructura de la consulta
1
PreparedStatement statement = connection.prepareStatement("SELECT * FROM products WHERE category = ?"); statement.setString(1, input); ResultSet resultSet = statement.executeQuery();
Podemos usar consultas parametrizadas en cualquier situación donde una entrada no confiable aparezca como datos dentro de la consulta, incluyendo la cláusula WHERE y los valores en una declaración INSERT o UPDATE. No podemos usarlas para manejar entradas no confiables en otras partes de la consulta, como nombres de tablas o columnas o la cláusula ORDER BY
La funcionalidad de la aplicación que coloca datos no confiables en estas partes de la consulta necesita tomar un enfoque diferente, por ejemplo:
- Incluir en una - whitelistlos- valores de entrada permitidos
- Usar una - lógica diferentepara obtener el- comportamiento requerido
Para que una consulta parametrizada sea efectiva en la prevención de la inyección SQL, la cadena utilizada en la consulta siempre debe ser una constante hardcodeada de forma fija. Este sería un ejemplo de una constante hardcodeada de forma fija
1
consulta = "SELECT * FROM usuarios WHERE rol = 'admin'"
Es importante recordar que la consulta nunca debe contener datos variables de ninguna procedencia. Este es un ejemplo de una entrada variable
1
consulta = "SELECT * FROM usuarios WHERE rol = '" + rol + "'"
No debemos decidir caso por caso si un dato es confiable y seguir usando la concatenación de cadenas con entradas variables dentro de la consulta para casos que se consideren seguros. Debido a que es fácil cometer errores sobre el posible origen de los datos o que cambios en otra parte del código modifiquen datos que considerábamos confiables
