cd ~/blog

~/vulns/blind-sqli-time-based.md

Blind SQLi (Time-Based)

web 25-08-2025
SQLSQLiSQLi-BlindTime-Basedtalk

~3 min de lectura


1. Descripción del ataque

Blind SQL Injection basada en tiempo (Time-Based Blind SQLi), es una variante de SQL Injection, en la cual la aplicación web no devuelve mensajes de error ni resultados visibles de la consulta SQL, pero sigue siendo vulnerable a inyecciones.
El atacante explota la vulnerabilidad provocando retrasos medibles en la respuesta del servidor mediante funciones como SLEEP() en MySQL o pg_sleep() en PostgreSQL.

De esta forma, si una condición es verdadera, la consulta se ralentiza artificialmente; si es falsa, responde al instante.
Esto permite reconstruir, carácter por carácter, información de la base de datos.

Ejemplo de payload time-based:

' AND IF(SUBSTRING(DATABASE(),1,1)='t', SLEEP(2), 0) -- -
  • Si el primer carácter del nombre de la base es t, el servidor tardará 2 segundos más en responder.

  • Si no lo es, la respuesta será inmediata.

Repitiendo el proceso, el atacante puede extraer todo el nombre de la base, tablas, columnas y finalmente registros sensibles.

2. Impacto de la vulnerabilidad

Con una Blind SQLi Time-Based, el atacante puede llegar a:

  • Descubrir la base de datos activa con consultas del tipo DATABASE().

  • Enumerar tablas y columnas de information_schema.

  • Volcar datos sensibles (usuarios, contraseñas, correos, tokens).

  • Comprometer toda la aplicación, especialmente si las credenciales permiten privilegios de administrador.

Aunque es más lenta que una SQLi clásica o Error-Based, sigue siendo crítica:
👉 Un ataque automatizado puede reconstruir miles de registros de forma sistemática.

3. Ejemplo de explotación con script

Estrategia del script:

  1. Definición de caracteres válidos:
    string.ascii_letters + string.digits + "_@.-:$"

posibles caracteres del nombre de tablas/columnas/datos.

  1. Payload genérico con SLEEP():
    1' AND (SELECT IF(SUBSTRING((consulta),{pos},1)='{char}', SLEEP(0.5), 0)) -- -
  • Cambia {pos} por la posición del carácter.

  • Cambia {char} por cada posible carácter hasta encontrar el correcto.

  1. Extracción paso a paso:

    • Primero el nombre de la base de datos (DATABASE()).
    • Luego tablas de information_schema.tables.
    • Luego columnas de cada tabla.
    • Finalmente, concatenación de campos sensibles como username:password.
  2. Medición del tiempo de respuesta:
    Si la respuesta tarda más del umbral (ej. 0.4s), el carácter probado es correcto.

Ejemplo de salida del script:

[*] Extrayendo nombre de base de datos...
[+] db_name: secure_app
[*] Extrayendo nombres de tablas...
  [+] Tabla 1 -> users
  [+] Tabla 2 -> messages
[*] Extrayendo columnas de `users`...
  [+] Columna 1 -> username
  [+] Columna 2 -> password
[*] Extrayendo registros de `users`...
  [+] Registro 1 -> admin:5f4dcc3b5aa765d61d8327deb882cf99

Esto muestra cómo, aunque no hay errores SQL ni respuestas visibles, es posible reconstruir todo el esquema y los datos sensibles.

4. Detección

  • Manual:
    Probar payloads como:
    1' AND IF(1=1, SLEEP(2), 0) -- - 1' AND IF(1=2, SLEEP(2), 0) -- -

Si la primera consulta tarda más que la segunda → vulnerable.

  • Automatizada:
    Herramientas como:
    • sqlmap (--technique=T)
    • BurpSuite (con Intruder + payloads de tiempo)
    • Scripts personalizados en Python.

5. Mitigación

  1. Consultas parametrizadas (prepared statements).
    Evitan la concatenación de cadenas con entrada del usuario.

  2. Validación estricta de entrada.
    Ejemplo: si id debe ser numérico, asegurarse que solo acepte enteros.

  3. Principio de privilegios mínimos.
    La aplicación no debería conectarse como root a la base.

  4. Uso de WAF para filtrar patrones como SLEEP(), pg_sleep(), WAITFOR DELAY.

  5. Errores genéricos.
    No mostrar trazas SQL ni información sensible.

6. Clasificación

  • Tipo: Blind Injection (Time-Based)

  • OWASP Top 10: A1 – Injection

  • CWE:

    • CWE-89 – Improper Neutralization of Special Elements used in an SQL Command
    • CWE-20 – Improper Input Validation

7. Resumen

La Blind SQLi Time-Based demuestra que incluso sin errores visibles ni resultados directos, una aplicación vulnerable sigue siendo explotable.
El atacante aprovecha diferencias de tiempo de respuesta para inferir información de forma gradual, hasta comprometer totalmente la base de datos.
Aunque más lenta que otros métodos, sigue siendo igual de peligrosa y debe ser tratada como una vulnerabilidad crítica.

// relacionados