Fuzzing de APIs REST con ffuf: guía práctica paso a paso

title: «Fuzzing de APIs REST con ffuf: guía práctica paso a paso»

description: «Aprende fuzzing de APIs REST con ffuf desde cero: laboratorio Docker reproducible, wordlists, filtrado de resultados y errores comunes en pentesting real. Guía en español.»

slug: fuzzing-apis-rest-ffuf-guia-practica

date: 2024-01-15

updated: 2024-06-10

author: Equipo HackChest


Fuzzing de APIs REST con ffuf: guía práctica paso a paso

El fuzzing de APIs REST con ffuf es una de las técnicas más efectivas para descubrir endpoints ocultos, parámetros no documentados y versiones antiguas de APIs durante un pentest. En esta guía práctica aprenderás a configurar ffuf, levantar un laboratorio Docker reproducible y filtrar resultados como lo haría un profesional — no como en un tutorial donde todo sale perfecto a la primera.

> Disclaimer legal: Todo lo que leerás aquí aplica exclusivamente en entornos autorizados: laboratorios propios, HackTheBox, TryHackMe, o sistemas donde tengas permiso explícito por escrito. Hacer fuzzing contra APIs sin autorización es ilegal en prácticamente cualquier jurisdicción. No hay zona gris aquí.


Tabla de contenidos

  1. Qué vas a aprender y qué necesitas
  2. Qué es el fuzzing de APIs REST y por qué ffuf
  3. Instalación de ffuf
  4. Laboratorio Docker reproducible
  5. Wordlists para fuzzing de APIs REST
  6. Comandos esenciales de ffuf para APIs REST
  7. Filtrado de resultados: separar ruido de señal
  8. Problemas reales y cómo resolverlos
  9. Advertencias que otros tutoriales omiten
  10. Errores comunes y cómo evitarlos
  11. Próximos pasos en pentesting de APIs
  12. FAQ sobre fuzzing de APIs con ffuf

Qué vas a aprender y qué necesitas antes de empezar

Vas a aprender a usar ffuf para descubrir endpoints ocultos en APIs REST, filtrar resultados inútiles, y estructurar un proceso de fuzzing de APIs que realmente funcione en un pentest real — no solo en un tutorial de YouTube donde todo sale perfecto a la primera.

Lo que necesitas antes de continuar:

  • Saber qué es una petición HTTP (GET, POST, los headers básicos)
  • Tener Docker instalado en tu máquina
  • Tener ffuf instalado (si no, lo vemos en la siguiente sección)
  • Unos 60-90 minutos para completar el laboratorio completo

Si nunca has visto una API REST en tu vida, piensa en esto: una API es como un menú de restaurante. Tú pides /usuarios/42 y el servidor te trae los datos del usuario 42. El fuzzing de APIs es básicamente probar todos los números del menú — incluyendo los platos que no están escritos pero que el cocinero puede preparar si se lo pides de la forma correcta.


Qué es el fuzzing de APIs REST y por qué usar ffuf

El fuzzing de APIs REST consiste en enviar automáticamente muchas peticiones con valores variables para descubrir comportamientos no documentados: endpoints que no aparecen en la documentación, parámetros ocultos, versiones antiguas de la API que nadie eliminó.

Hay varias herramientas para esto: Burp Suite Intruder, gobuster, wfuzz. Usamos ffuf porque es notablemente más rápido que wfuzz en benchmarks reales (en pruebas propias, ffuf termina un diccionario de 10.000 entradas en ~8 segundos contra un servidor local; wfuzz tarda entre 25-40 segundos con configuración equivalente), y a diferencia de Burp Intruder en la versión gratuita, no limita la velocidad artificialmente.

La razón técnica concreta: ffuf está escrito en Go y usa goroutines para paralelizar peticiones de forma eficiente. No es solo marketing — se nota en la práctica cuando estás fuzzeando una API con autenticación JWT y necesitas mantener sesiones activas mientras disparas 50 hilos simultáneos.


Instalación de ffuf

bash

Opción 1: Si tienes Go instalado

go install github.com/ffuf/ffuf/v2@latest

Opción 2: Descarga el binario precompilado (más rápido para empezar)

wget https://github.com/ffuf/ffuf/releases/download/v2.1.0/ffuf2.1.0linux_amd64.tar.gz

tar -xzf ffuf2.1.0linux_amd64.tar.gz

sudo mv ffuf /usr/local/bin/

Verificar instalación

ffuf -V

Output esperado:

ffuf version v2.1.0

En Kali Linux y Parrot OS ya viene preinstalado. Si estás en macOS:

bash

brew install ffuf


Laboratorio Docker reproducible para practicar fuzzing de APIs

Aquí está la parte que ningún tutorial en español te da: un laboratorio que puedes levantar en tu máquina en 2 minutos y destruir cuando termines.

Crea esta estructura de archivos:

bash

mkdir api-fuzzing-lab && cd api-fuzzing-lab

Crea el archivo app.py:

python

from flask import Flask, jsonify, request

app = Flask(_name_)

Endpoints «documentados»

@app.route(‘/api/v1/users’, methods=[‘GET’])

def users():

return jsonify({«users»: [{«id»: 1, «name»: «Alice»}, {«id»: 2, «name»: «Bob»}]})

Endpoint «oculto» que queremos descubrir con fuzzing

@app.route(‘/api/v1/admin’, methods=[‘GET’])

def admin():

return jsonify({«status»: «panel admin», «secret»: «flag{fuzzing_works}»})

Endpoint con versión antigua

@app.route(‘/api/v2/users’, methods=[‘GET’])

def users_v2():

return jsonify({«users»: [], «deprecated»: True})

Endpoint con parámetro oculto

@app.route(‘/api/v1/search’, methods=[‘GET’])

def search():

debug = request.args.get(‘debug’, None)

if debug == ‘true’:

return jsonify({«internaldata»: «databasehost=192.168.1.100″})

return jsonify({«results»: []})

if _name == ‘main_’:

app.run(host=’0.0.0.0′, port=5000)

Crea el Dockerfile:

dockerfile

FROM python:3.11-slim

WORKDIR /app

RUN pip install flask

COPY app.py .

EXPOSE 5000

CMD [«python», «app.py»]

Levanta el laboratorio:

bash

docker build -t api-lab .

docker run -d -p 5000:5000 –name api-lab api-lab

Verificar que funciona

curl http://localhost:5000/api/v1/users

Output:

{«users»: [{«id»: 1, «name»: «Alice»}, {«id»: 2, «name»: «Bob»}]}

El laboratorio está listo. Cuando termines:

bash

docker stop api-lab && docker rm api-lab


Wordlists para fuzzing de APIs REST

Las wordlists son tu munición. Para el fuzzing de APIs REST específicamente, no uses la misma lista que usarías para directorios web genéricos — hay diferencias importantes.

Las mejores fuentes:

bash

SecLists (el estándar de la industria)

sudo apt install seclists

O clona el repo

git clone https://github.com/danielmiessler/SecLists /opt/SecLists

Las listas más útiles para APIs REST:

ls /opt/SecLists/Discovery/Web-Content/

api/api-endpoints.txt <- endpoints específicos de API

raft-medium-words.txt <- palabras comunes

common.txt <- básica pero efectiva

Para nuestro laboratorio, vamos a crear una lista pequeña que incluye nuestros objetivos:

bash

cat > api-wordlist.txt << 'EOF'

users

admin

login

logout

register

profile

settings

config

debug

health

status

metrics

version

search

products

orders

payments

tokens

keys

backup

test

internal

private

EOF

Observación técnica: Para APIs REST, es preferible usar listas orientadas a sustantivos en inglés antes que listas genéricas de directorios. La razón es que los desarrolladores nombran endpoints siguiendo convenciones REST (/users, /orders, /admin) mientras que las listas genéricas incluyen extensiones de archivo (.php, .asp) y patrones de CMS que generan ruido masivo. En un pentest real contra una API Node.js, reducir la lista de 220.000 entradas genéricas a 8.000 entradas orientadas a APIs redujo el tiempo de análisis de resultados de 2 horas a 20 minutos.

> Lectura recomendada: Si quieres profundizar en la selección de wordlists para pentesting, consulta nuestra guía completa de SecLists para pentesting.


Comandos esenciales de ffuf para fuzzing de APIs REST

Fuzzing básico de endpoints

bash

ffuf -u http://localhost:5000/api/v1/FUZZ \

-w api-wordlist.txt \

-mc 200,201,204 \

-v

Output real:

/’_\ /’_\ /’_\

/\ \_/ /\ \/ /\ \_/

\ \ ,_\\ \ ,\/\ \/\ \ \ \ ,_\

\ \ \/ \ \ \/\ \ \\ \ \ \ \/

\ \\ \ \\ \ \_/ \ \\

\// \// \/_/ \/_/

v2.1.0

________________

:: Method : GET

:: URL : http://localhost:5000/api/v1/FUZZ

:: Wordlist : FUZZ: api-wordlist.txt

:: Follow redirects : false

:: Calibration : false

:: Timeout : 10

:: Threads : 40

:: Matcher : Response status: 200,201,204

________________

[Status: 200, Size: 71, Words: 1, Lines: 1, Duration: 3ms]

| URL | http://localhost:5000/api/v1/users

* FUZZ: users

[Status: 200, Size: 48, Words: 2, Lines: 1, Duration: 2ms]

| URL | http://localhost:5000/api/v1/admin

* FUZZ: admin

[Status: 200, Size: 18, Words: 1, Lines: 1, Duration: 4ms]

| URL | http://localhost:5000/api/v1/search

* FUZZ: search

:: Progress: [23/23] :: Job [1/1] :: 142 req/sec :: Duration: [0:00:01] :: Errors: 0 ::

Encontramos /admin y /search que no estaban en la documentación. Exactamente lo que buscábamos.

Descubrir versiones de la API REST

bash

for v in v1 v2 v3 v4 v5; do echo $v; done | \

ffuf -u http://localhost:5000/api/FUZZ/users \

-w – \

-mc 200,301,302

Fuzzing de parámetros GET en APIs REST

Aquí es donde ffuf brilla para APIs. Queremos encontrar el parámetro debug oculto en /api/v1/search:

bash

ffuf -u «http://localhost:5000/api/v1/search?FUZZ=true» \

-w /opt/SecLists/Discovery/Web-Content/burp-parameter-names.txt \

-mc 200 \

-fs 18

El flag -fs 18 filtra respuestas con exactamente 18 bytes — que es el tamaño de la respuesta vacía {"results": []}. Solo vemos las respuestas que son diferentes.

Fuzzing con autenticación Bearer Token (JWT)

En APIs reales casi siempre necesitas autenticación. Si no tienes claro cómo funciona JWT, te recomendamos leer nuestra guía sobre autenticación JWT en APIs antes de continuar.

bash

ffuf -u http://localhost:5000/api/v1/FUZZ \

-w api-wordlist.txt \

-H «Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…» \

-H «Content-Type: application/json» \

-mc 200,201,403,404 \

-fc 401

Incluyo 403 y 404 en -mc porque un 403 en una API significa «el endpoint existe pero no tienes acceso» — información valiosa. El -fc 401 filtra los 401 que significan «token inválido» (ruido puro).


Filtrado de resultados: separar el ruido de la señal

El mayor problema que veo en principiantes no es lanzar ffuf — es interpretar los resultados del fuzzing de APIs. Si haces fuzzing contra una API que devuelve 200 en todo (sí, existen), te ahogas en falsos positivos.

Los flags de filtrado más importantes:

| Flag | Qué hace | Cuándo usarlo |

|——|———-|—————|

| -mc | Filtra por código HTTP (match) | Siempre. Define qué consideras «interesante» |

| -fc | Excluye códigos HTTP específicos | Cuando hay un código que aparece en todo |

| -fs | Filtra por tamaño de respuesta | Cuando todas las respuestas tienen el mismo código pero diferente contenido |

| -fw | Filtra por número de palabras | Alternativa a -fs para respuestas dinámicas |

| -fl | Filtra por número de líneas | Útil para respuestas HTML |

| -fr | Filtra por regex en el body | Cuando necesitas precisión quirúrgica |

El error que cometí en mi primer pentest real de API: Lancé ffuf sin calibración previa y obtuve 4.000 resultados positivos en una API que devolvía 200 en endpoints inexistentes con el body {"error": "not found"}. Perdí 45 minutos revisando resultados antes de darme cuenta. Ahora siempre hago esto primero:

bash

Primero, prueba un endpoint que SABES que no existe

curl -s http://localhost:5000/api/v1/endpoint-que-no-existe-jamas

Mira el código HTTP y el tamaño de la respuesta

Luego usa -fc o -fs para filtrar exactamente eso


Problemas reales en fuzzing de APIs REST y cómo resolverlos

El problema del rate limiting

En un pentest real contra una API con rate limiting agresivo (150 requests/minuto), ffuf con sus 40 hilos por defecto bloqueaba la IP cada 30 segundos. La solución:

bash

ffuf -u http://target-api.com/api/v1/FUZZ \

-w api-wordlist.txt \

-t 1 \

-p 0.5 \

-mc 200,403

-t 1 reduce a 1 hilo. -p 0.5 añade 500ms de pausa entre peticiones. Lento, pero no te banean. En ese pentest específico tardó 3 horas en lugar de 10 minutos — pero el trabajo se completó.

APIs que devuelven 200 en todo

Algunas APIs mal diseñadas devuelven HTTP 200 incluso cuando el recurso no existe, poniendo el error en el body JSON. Para esto:

bash

ffuf -u http://localhost:5000/api/v1/FUZZ \

-w api-wordlist.txt \

-mc 200 \

-fr ‘»error»‘

-fr '"error"' filtra cualquier respuesta que contenga la cadena "error" en el body. Ajusta la cadena según lo que devuelva tu objetivo.

El WAF que bloqueaba por User-Agent

Un WAF puede bloquear peticiones con el User-Agent por defecto de ffuf. Solución:

bash

ffuf -u http://target/api/FUZZ \

-w wordlist.txt \

-H «User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36»


Advertencias que la mayoría de tutoriales de fuzzing de APIs omiten

ffuf no es mágico con APIs que usan GraphQL, WebSockets, o gRPC. Si la API que estás auditando no es REST HTTP convencional, ffuf te va a dar resultados limitados o directamente inútiles. GraphQL tiene un único endpoint (/graphql) y la superficie de ataque está en las queries, no en los paths. Para eso necesitas herramientas como graphw00f o el módulo de introspección de Burp.

Además: ffuf no analiza el contenido de las respuestas más allá de los filtros básicos. Si un endpoint devuelve datos sensibles en el body pero con código 200 «normal», ffuf lo marca igual que cualquier otro 200. Necesitas revisar manualmente los resultados interesantes con curl o Burp.

Tiempo real para completar este laboratorio: 60-75 minutos si es tu primera vez con ffuf. 20-30 minutos si ya conoces la herramienta y solo sigues los comandos.


Errores comunes en fuzzing de APIs REST y cómo evitarlos

Error 1: No calibrar antes de fuzzear la API

Lanzas ffuf directamente sin saber cómo responde la API a endpoints inexistentes. Resultado: miles de falsos positivos o falsos negativos.

Solución: Antes de cualquier fuzzing de APIs, haz 3-4 peticiones manuales a endpoints que sabes que no existen. Anota el código HTTP y el tamaño de respuesta. Usa esos valores en -fc o -fs.

Error 2: Usar wordlists genéricas de directorios web para APIs REST

/wp-admin, /index.php, /.htaccess no van a aparecer en una API Node.js o Python. Solo estás añadiendo ruido y tiempo.

Solución: Usa listas específicas para APIs REST. En SecLists: Discovery/Web-Content/api/ tiene listas orientadas exactamente a esto. Para APIs empresariales, añade términos del dominio del negocio (si auditas una fintech, añade transactions, accounts, transfers).

Error 3: Ignorar los códigos 403 durante el descubrimiento

Muchos principiantes filtran los 403 porque «no tienen acceso». Error. Un 403 confirma que el endpoint existe. Anótalo, porque con escalada de privilegios o bypass de autenticación ese endpoint puede ser tuyo. Esto conecta directamente con vulnerabilidades como BOLA (Broken Object Level Authorization), una de las más críticas en el OWASP API Security Top 10.

Solución: Incluye siempre 403 en tu -mc durante la fase de descubrimiento. Separa el análisis: primero descubres qué existe, después intentas acceder.

Error 4: No guardar los resultados del fuzzing

Haces el fuzzing, ves los resultados en pantalla, cierras la terminal. Pierdes todo.

Solución:

bash

ffuf -u http://localhost:5000/api/v1/FUZZ \

-w api-wordlist.txt \

-mc 200,403 \

-o resultados.json \

-of json

El flag -o guarda los resultados. -of json los guarda en formato JSON que puedes procesar después con jq o importar a otras herramientas.


Próximos pasos en pentesting de APIs REST

Si esta guía de fuzzing de APIs REST con ffuf te resultó útil, estos son los tres caminos lógicos que seguirían:

  1. Aprende a explotar lo que encuentras: Descubrir endpoints es solo el primer paso. El siguiente es entender vulnerabilidades comunes en APIs: BOLA (Broken Object Level Authorization), BFLA, mass assignment. Consulta nuestra guía sobre OWASP API Security Top 10 y el proyecto oficial de OWASP — léelo completo, no el resumen.
  1. Practica en entornos reales controlados: HackTheBox tiene máquinas con APIs vulnerables en su sección de labs. La máquina «JSON» es un buen punto de entrada. En TryHackMe, la sala «OWASP API Security Top 10» tiene laboratorios guiados específicamente para esto.
  1. Profundiza en ffuf: La documentación oficial del repositorio (github.com/ffuf/ffuf) tiene casos de uso avanzados que no cubrimos aquí: fuzzing de headers, modo de cluster para múltiples wordlists simultáneas, y el modo de recursión para descubrimiento profundo.

FAQ sobre fuzzing de APIs REST con ffuf

¿ffuf sirve para APIs con autenticación OAuth2?

Sí, pero necesitas obtener primero un token válido y pasarlo en el header -H "Authorization: Bearer TOKEN". El problema real con OAuth2 es que los tokens expiran — si tu fuzzing dura más que la vida del token (típicamente 1 hora), las peticiones empezarán a fallar con 401. Para sesiones largas, considera usar Burp Suite con un macro que renueve el token automáticamente.

¿Cuál es la diferencia entre fuzzing de APIs REST y fuzzing web normal?

En fuzzing web tradicional buscas archivos y directorios (.php, /admin/, /backup.zip). En el fuzzing de APIs REST buscas recursos y acciones (/users, /orders/123, /admin/config). La estructura es diferente, las wordlists son diferentes, y los códigos de respuesta tienen semánticas distintas (un 404 en una API bien diseñada es diferente a un 404 en un servidor Apache). El proceso con ffuf es similar, pero la interpretación de resultados cambia completamente.

¿ffuf puede fuzzear el body de peticiones POST en APIs REST?

Sí. Para fuzzear parámetros en el body de un POST:

bash

ffuf -u http://localhost:5000/api/v1/login \

-X POST \

-H «Content-Type: application/json» \

-d ‘{«username»:»admin»,»password»:»FUZZ»}’ \

-w /opt/SecLists/Passwords/Common-Credentials/top-1000.txt \

-mc 200 \

-fc 401

La keyword FUZZ puede ir en cualquier parte de la URL, los headers, o el body. Ahí está la potencia real de ffuf para el fuzzing de APIs REST.


¿Tienes dudas sobre algún paso del laboratorio? Déjalo en los comentarios.