1. Descripción técnica
Time-Based Blind SQL Injection es una variante de SQL Injection en la cual la aplicación no devuelve el resultado de la consulta ni un error útil, pero una entrada controlada todavía modifica la sentencia SQL.
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
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 otras variantes de SQL Injection, la automatización permite reconstruir información de forma sistemática. La gravedad real depende de los permisos de la cuenta de base de datos y de los datos accesibles desde la consulta vulnerable.
3. Condiciones necesarias
- Una entrada no confiable se concatena o incorpora de forma insegura a una consulta SQL.
- El motor admite una operación que produce un retraso observable, como
SLEEP(),pg_sleep()oWAITFOR DELAY. - La aplicación espera la finalización de la consulta antes de responder.
- La latencia permite distinguir una condición verdadera de una falsa mediante varias mediciones.
4. Explotación documentada en los writeups
4.1. 080-talk
El writeup utiliza un script que prueba cada carácter y decide si coincide a partir del tiempo de respuesta.
Estrategia del script
- Definición de caracteres válidos:
string.ascii_letters + string.digits + "_@.-:$"posibles caracteres del nombre de tablas/columnas/datos.
- 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.
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.
- Primero el nombre de la base de datos (
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:5f4dcc3b5aa765d61d8327deb882cf99Esto muestra cómo, aunque no hay errores SQL ni respuestas visibles, es posible reconstruir todo el esquema y los datos sensibles.
5. Validación y 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 presenta un retraso repetible respecto de la segunda, existe evidencia de un canal temporal. Una medición aislada no basta, porque la carga del servidor y la red también producen variaciones.
- Automatizada:
Herramientas como:- sqlmap (
--technique=T) - BurpSuite (con Intruder + payloads de tiempo)
- Scripts personalizados en Python.
- sqlmap (
6. Mitigación
Consultas parametrizadas (prepared statements).
Evitan la concatenación de cadenas con entrada del usuario.Validación estricta de entrada.
Ejemplo: siiddebe ser numérico, asegurarse que solo acepte enteros.Principio de privilegios mínimos.
La aplicación no debería conectarse comoroota la base.Uso de WAF para filtrar patrones como
SLEEP(),pg_sleep(),WAITFOR DELAY.Errores genéricos.
No mostrar trazas SQL ni información sensible.
7. Clasificación
Tipo: Blind Injection (Time-Based)
OWASP Top 10: A03:2021 Injection
CWE:
- CWE-89: Improper Neutralization of Special Elements used in an SQL Command