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 — Kit de detección y explotación para CVE-2026-39987, un RCE sin autenticación previa en notebooks Marimo. Incluye un escáner en Python y un script NSE de Nmap para identificar instancias vulnerables mediante comprobaciones del endpoint WebSocket. | Kitploit
Herramientas/GitHubGitHub/keraattin/cve-2026-39987
Escáneres de VulnerabilidadesAnálisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebRecopilación de InformaciónSeguridad WebSeguridad de RedesPruebas de Penetración
GitHubkeraattin/cve-2026-39987

CVE-2026-39987

Kit de detección y explotación para CVE-2026-39987, un RCE sin autenticación previa en notebooks Marimo. Incluye un escáner en Python y un script NSE de Nmap para identificar instancias vulnerables mediante comprobaciones del endpoint WebSocket.

1hace 4 mesesAún no revisado
Ver Repositorio

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 — Ejecución Remota de Código Pre-Autenticada en Marimo Python Notebook

CVE-2026-39987 CVSS 9.3 CWE-306 Marimo Pre-Auth RCE

TL;DR

Una vulnerabilidad de ejecución remota de código pre-autenticada en Marimo, un notebook Python de código abierto para ciencia de datos e IA/ML. El endpoint WebSocket de terminal (/terminal/ws) omite por completo la validación de autenticación, mientras que el endpoint vecino de notebook (/ws) la aplica correctamente. Un atacante no autenticado puede conectarse a /terminal/ws y obtener un en el sistema host sin credenciales.

shell PTY interactivo completo

Explotada en la naturaleza en menos de 10 horas desde su divulgación. Los atacantes robaron credenciales de AWS en menos de 3 minutos.

Afecta a Marimo <= 0.20.4. Corregido en Marimo 0.23.0.


Tabla de Contenidos

  • Datos Rápidos
  • ¿Qué es Marimo?
  • Análisis Profundo de la Vulnerabilidad
    • Los Dos Endpoints WebSocket
    • La Verificación de Autenticación Ausente
    • El Ataque: Del Aviso a las Claves de AWS en 3 Minutos
  • Análisis de Impacto
  • Versiones Afectadas
  • El Panorama General: La Cadena de Herramientas de IA/ML Bajo Ataque
  • Detección
    • Escáner en Python
    • Script Nmap NSE
    • Verificación Manual
  • Indicadores de Compromiso
  • Remediación
  • Referencias
  • Autor

Datos Rápidos

CampoDetalle
ID CVECVE-2026-39987
ProveedorProyecto Marimo
ProductoMarimo (Notebook Python)
Versiones Afectadas<= 0.20.4
CVSS v3.19.3 (Crítico)
CWECWE-306 — Autenticación Ausente para Función Crítica
Vector de AtaqueRed
AutenticaciónNo se requiere
Interacción del UsuarioNinguna
Madurez del ExploitExplotado activamente en la naturaleza
Tiempo hasta la Explotación~10 horas después de la divulgación
Corregido EnMarimo 0.23.0

¿Qué es Marimo?

Marimo es un notebook Python reactivo de código abierto diseñado como una alternativa moderna a Jupyter. Está construido para ciencia de datos, experimentación con IA/ML y análisis de datos interactivo. Sus características clave incluyen seguimiento automático de dependencias, ejecución reproducible y una experiencia de desarrollo más limpia en comparación con los notebooks tradicionales.

Marimo está ganando rápidamente tracción en la comunidad de Python e IA/ML, especialmente entre los profesionales que desean flujos de trabajo de notebook más estructurados de los que ofrece Jupyter.

Como todos los entornos de notebook, las instancias de Marimo suelen tener acceso a recursos sensibles: credenciales en la nube (AWS, GCP, Azure), cadenas de conexión a bases de datos, claves API para servicios de IA (OpenAI, Anthropic, etc.) y acceso a la red interna. A diferencia de las aplicaciones web tradicionales, los notebooks están diseñados para ejecutar código arbitrario. Ese es su propósito principal.

Esta combinación hace que cualquier omisión de autenticación en un entorno de notebook sea particularmente devastadora.``` Typical Marimo Deployment:

┌──────────────┐ ┌────────────────────────────────┐ │ │ HTTP │ Marimo Server │ │ Browser │────────>│ │ │ (User) │ │ ┌──────────────────────────┐ │ │ │<────────│ │ /ws (Notebook) │ │ └──────────────┘ WS │ │ ✅ validate_auth() │ │ │ └──────────────────────────┘ │ │ │ │ ┌──────────────────────────┐ │ │ │ /terminal/ws │ │ │ │ ❌ NO AUTH CHECK │ │ │ └──────────────────────────┘ │ │ │ │ ┌──────────────────────────┐ │ │ │ Python Environment │ │ │ │ .env files │ │ │ │ AWS credentials │ │ │ │ API keys │ │ │ └──────────────────────────┘ │ └────────────────────────────────┘

root@kitploit:~
---

## Análisis Profundo de la Vulnerabilidad

### Los Dos Endpoints WebSocket

El servidor de Marimo implementa múltiples endpoints WebSocket para diferentes funciones. La diferencia crítica entre los dos endpoints principales es la presencia (o ausencia) de una verificación de autenticación:```
  Authentication Flow Comparison:

  /ws (Notebook WebSocket):
  ┌─────────┐    ┌───────────────┐    ┌──────────┐    ┌───────────┐
  │ Connect │───>│ validate_auth │───>│  Accept  │───>│ Notebook  │
  └─────────┘    └───────┬───────┘    └──────────┘    └───────────┘
                         │
                    ❌ Reject if
                    not authenticated

  /terminal/ws (Terminal WebSocket):
  ┌─────────┐    ┌───────────────┐    ┌──────────┐    ┌───────────┐
  │ Connect │───>│ Check mode &  │───>│  Accept  │───>│ PTY Shell │
  └─────────┘    │ platform only │    └──────────┘    └───────────┘
                 └───────────────┘
                 ⚠️ No auth check!
                 Anyone gets a shell!

La Verificación de Autenticación Faltante

El endpoint del notebook (/ws) llama correctamente a validate_auth() para verificar la identidad del usuario antes de aceptar conexiones WebSocket. Este es el comportamiento de seguridad esperado.

El endpoint del terminal (/terminal/ws) solo verifica si el servidor está en modo de ejecución y si la plataforma soporta la funcionalidad del terminal. Nunca llama a validate_auth(). Después de pasar estas verificaciones básicas, acepta la conexión y crea una sesión PTY (pseudo-terminal) completa.```python

/ws (Notebook) — CORRECT implementation

async def websocket_connect(self, message): await self.validate_auth() # ✅ Checks authentication await self.accept() # ... notebook communication

/terminal/ws (Terminal) — VULNERABLE implementation

async def websocket_connect(self, message): if not self.is_running_mode(): # Only checks mode await self.close() return if not self.is_platform_supported(): # Only checks platform await self.close() return await self.accept() # ❌ No auth! Anyone gets a shell # ... PTY shell creation

root@kitploit:~
Esto es **CWE-306: Falta de Autenticación para Funciones Críticas**. El endpoint más peligroso del servidor (el que proporciona un shell interactivo) no tiene autenticación alguna.

### El Ataque: De Advisory a Claves de AWS en 3 Minutos

La línea de tiempo de explotación muestra lo rápido que operan los actores de amenazas modernos:```
  ┌──────────────────────────────────────────────────────────────┐
  │                   CVE-2026-39987 Timeline                    │
  ├──────────────────────────────────────────────────────────────┤
  │                                                              │
  │  T+0h        Advisory published                              │
  │  ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─                       │
  │  T+9h        First exploit built from advisory               │
  │  T+10h       Exploitation in the wild confirmed              │
  │  ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─                       │
  │  T+10h 0m    Attacker connects to /terminal/ws               │
  │  T+10h 1m    Full PTY shell obtained                         │
  │  T+10h 2m    .env file located and read                      │
  │  T+10h 3m    AWS keys exfiltrated                            │
  │              Total attack time: ~3 minutes                   │
  └──────────────────────────────────────────────────────────────┘

El ataque en sí es trivialmente simple:``` Step 1: Attacker opens WebSocket connection to /terminal/ws (No authentication needed, no special tools required)

Step 2: Server creates a PTY (pseudo-terminal) session Attacker now has an interactive shell

Step 3: Attacker runs commands: $ cat .env AWS_ACCESS_KEY_ID=AKIA... AWS_SECRET_ACCESS_KEY=... DATABASE_URL=postgres://... OPENAI_API_KEY=sk-...

Step 4: Credentials exfiltrated Attacker now has cloud access, database access, and API keys for AI services

Total time: under 3 minutes Authentication required: none Tools required: any WebSocket client

root@kitploit:~
No se necesita desarrollo de exploits. Sin shellcode. Sin corrupción de memoria. Solo un cliente WebSocket y una verificación de autenticación ausente.

---

## Análisis de Impacto

**Impacto inmediato en el host de Marimo:**
- Shell interactivo completo con los privilegios del proceso de Marimo
- Acceso a todos los archivos legibles por el proceso (código fuente, datos, credenciales)
- Acceso a variables de entorno que contienen claves API y secretos
- Capacidad de ejecutar comandos arbitrarios en el sistema host

**Exposición de credenciales (el objetivo principal del ataque):**
- Claves de acceso y claves secretas de AWS desde archivos `.env` o variables de entorno
- Credenciales de cuentas de servicio de GCP/Azure
- Cadenas de conexión a bases de datos con contraseñas
- Claves API de OpenAI, Anthropic y otros servicios de IA
- Claves SSH y otro material de autenticación

**Impacto posterior (mediante credenciales robadas):**
- Acceso no autorizado a infraestructura en la nube (EC2, S3, Lambda, etc.)
- Exfiltración de datos desde almacenamiento en la nube y bases de datos
- Abuso de recursos (criptominería, robo de créditos de API de IA)
- Movimiento lateral hacia redes en la nube y locales

**Factores de amplificación de riesgo:**
- Los entornos de notebooks están diseñados para ejecutar código arbitrario (ese es su propósito)
- Los entornos de ciencia de datos suelen tener acceso amplio a la nube para trabajos de entrenamiento
- Muchas instancias de Marimo están expuestas a internet para colaboración y trabajo remoto
- El endurecimiento de seguridad suele ser una ocurrencia tardía en entornos de investigación/experimentación

---

## Versiones Afectadas

| Versión | Estado |
|---------|--------|
| Marimo 0.23.0+ | **Corregido** |
| Marimo 0.20.5 a 0.22.x | **Probablemente vulnerable** (entre el rango del aviso y la corrección) |
| Marimo <= 0.20.4 | **Vulnerable** (rango confirmado) |

---

## El Panorama General: La Cadena de Herramientas de IA/ML Bajo Ataque

CVE-2026-39987 no es un incidente aislado. Es parte de un patrón claro que surgió en abril de 2026:

| CVE | Producto | Tipo | Estado |
|:---|:---|:---|:---|
| **CVE-2026-39987** | Marimo | RCE Pre-Auth (WebSocket) | Explotado en 10 horas |
| **CVE-2026-33017** | Langflow | RCE | CISA KEV (26 de marzo) |
| **CVE-2026-5059** | aws-mcp-server | Inyección de comandos RCE | Aviso público |
| **TorchGeo** | TorchGeo | RCE por eval() | Aviso público |

Cuatro herramientas de desarrollo de IA/ML afectadas por vulnerabilidades críticas de RCE en un solo mes. El pipeline de desarrollo de IA/ML se está convirtiendo en el nuevo shadow IT: herramientas desplegadas con acceso amplio, supervisión de seguridad mínima y almacenes de credenciales ricos.```
  ┌─────────────────────────────────────────────────┐
  │        Why AI/ML Tools Are Prime Targets        │
  ├─────────────────────────────────────────────────┤
  │                                                 │
  │  1. DESIGNED to execute arbitrary code          │
  │     (that's literally what notebooks do)        │
  │                                                 │
  │  2. Run with elevated privileges                │
  │     (GPU access, cloud SDKs, network access)    │
  │                                                 │
  │  3. Contain high-value credentials              │
  │     (AWS keys, API tokens, DB connections)      │
  │                                                 │
  │  4. Often exposed to the network                │
  │     (for collaboration and remote access)       │
  │                                                 │
  │  5. Security hardening is an afterthought       │
  │     (focus on features and UX, not security)    │
  │                                                 │
  │  6. Users are researchers, not security experts │
  │     (default configs, weak passwords, no VPN)   │
  └─────────────────────────────────────────────────┘

Detección

Escáner en Python

El script en Python detecta instancias vulnerables de Marimo mediante un análisis de múltiples pasos.

Cómo funciona:

  1. Identificación de Marimo — Consulta /api/status, /api/health y / en busca de indicadores de Marimo en el contenido de las respuestas y cabeceras
  2. Extracción de versión — Analiza la información de versión de las respuestas de la API, cabeceras del servidor y contenido HTML
  3. Prueba de handshake WebSocket — Envía una solicitud segura de actualización HTTP a /terminal/ws (no se transmiten datos a través de la conexión)
  4. Comprobación de autenticación diferencial — Compara el comportamiento de /terminal/ws (debería requerir autenticación) frente a /ws (se sabe que requiere autenticación) para confirmar la inconsistencia
  5. Comprobación de vulnerabilidad por versión — Compara la versión detectada con el rango vulnerable (<= 0.20.4) y la versión parcheada (>= 0.23.0)

No se ejecutan comandos en los sistemas objetivo. El handshake WebSocket se prueba, pero no se envían datos a través de la conexión. La comprobación es completamente pasiva y segura para producción.

Uso:```bash

Install dependencies

pip install -r requirements.txt

Single target (Marimo default port: 2718)

python CVE-2026-39987_Marimo_RCE_detector.py -t http://marimo-host:2718

HTTPS target

python CVE-2026-39987_Marimo_RCE_detector.py -t https://marimo-host:443

Bulk scan from file with verbose output

python CVE-2026-39987_Marimo_RCE_detector.py -f targets.txt -o results.json -v

Increased timeout for slow networks

python CVE-2026-39987_Marimo_RCE_detector.py -t http://10.0.0.5:2718 --timeout 15

root@kitploit:~
**Opciones:**

| Bandera | Descripción | Predeterminado |
|------|-------------|---------|
| `-t`, `--target` | URL de destino única (p. ej., `http://host:2718`) | — |
| `-f`, `--file` | Archivo con URLs de destino, una por línea (se admiten comentarios con `#`) | — |
| `-o`, `--output` | Guardar resultados en archivo JSON | — |
| `--timeout` | Tiempo de espera de conexión en segundos | `10` |
| `--verify-ssl` | Habilitar verificación de certificado SSL | Deshabilitado |
| `-v`, `--verbose` | Salida detallada con información completa | Desactivado |

**Ejemplo de salida:**```
[*] CVE-2026-39987 Marimo Pre-Auth RCE Scanner
[*] Scanning 1 target(s)...
[*] NOTE: This scanner only checks for endpoint exposure.
[*]       No commands are executed on target systems.

======================================================================
Target: http://10.0.0.5:2718
Scan Time: 2026-04-14T16:00:00Z
Risk Level: CRITICAL
======================================================================
  Is Marimo:             YES
  Marimo Version:        0.19.2
  /terminal/ws Open:     YES — UNAUTHENTICATED
  Vulnerable:            YES

  *** CRITICAL: Pre-authenticated RCE is possible! ***
  *** An attacker can get a full PTY shell without any auth ***

  Details:
    - Marimo instance detected via /api/status
    - Marimo version: 0.19.2
    - WebSocket upgrade accepted — /terminal/ws accessible WITHOUT auth
    - CONFIRMED: /terminal/ws accepts unauthenticated connections while
      /ws requires auth — classic CVE-2026-39987 signature
    - Version 0.19.2 <= 0.20.4 — VULNERABLE to pre-auth RCE

======================================================================
[*] Scan Complete: 1 targets scanned
[*] Marimo Instances: 1 | Vulnerable: 1 | Critical: 1
======================================================================

Script NSE de Nmap```bash

Install the NSE script

sudo cp CVE-2026-39987_Marimo_RCE.nse /usr/share/nmap/scripts/ sudo nmap --script-updatedb

Basic scan (Marimo default port: 2718)

nmap -p 2718 --script CVE-2026-39987_Marimo_RCE

Scan common ports where Marimo might run

nmap -p 2718,8080,8443,443 --script CVE-2026-39987_Marimo_RCE

Subnet scan

nmap -p 2718 --script CVE-2026-39987_Marimo_RCE 10.0.0.0/24

Scan targets from a file

nmap -p 2718 --script CVE-2026-39987_Marimo_RCE -iL targets.txt

With service version detection

nmap -sV -p 2718 --script CVE-2026-39987_Marimo_RCE

root@kitploit:~
**Ejemplo de salida de Nmap:**```
PORT     STATE SERVICE
2718/tcp open  http
| CVE-2026-39987_Marimo_RCE:
|   VULNERABLE:
|   Marimo Pre-Auth RCE (CVE-2026-39987)
|     State: VULNERABLE
|     Risk level: CRITICAL
|     Marimo Version: 0.19.2
|     /terminal/ws: accessible without authentication
|     Description:
|       The Marimo /terminal/ws WebSocket endpoint accepts connections
|       without authentication, enabling pre-authenticated RCE.
|       An attacker can obtain a full PTY shell without any credentials.
|     References:
|_      https://nvd.nist.gov/vuln/detail/CVE-2026-39987

Verificación manual

Si tienes acceso a la instancia de Marimo:```bash

Check Marimo version via API

curl -s http://:2718/api/status | python3 -m json.tool

Test WebSocket upgrade on /terminal/ws (should NOT succeed without auth)

curl -s -o /dev/null -w "%{http_code}"
-H "Upgrade: websocket"
-H "Connection: Upgrade"
-H "Sec-WebSocket-Key: dGVzdC1rZXktMTIzNDU2Nzg="
-H "Sec-WebSocket-Version: 13"
http://:2718/terminal/ws

If it returns 101 (Switching Protocols), the endpoint is open without auth

If it returns 401/403, authentication is enforced (patched or hardened)

For comparison, test /ws (should always require auth)

curl -s -o /dev/null -w "%{http_code}"
-H "Upgrade: websocket"
-H "Connection: Upgrade"
-H "Sec-WebSocket-Key: dGVzdC1rZXktMTIzNDU2Nzg="
-H "Sec-WebSocket-Version: 13"
http://:2718/ws

root@kitploit:~
Si `/terminal/ws` devuelve 101 mientras que `/ws` devuelve 401/403, esta es la firma clásica de CVE-2026-39987.

---

## Indicadores de compromiso

Busque estas señales en su entorno:

| Indicador | Dónde comprobar | Qué buscar |
|:---|:---|:---|
| Conexiones WebSocket no autorizadas | Registros del servidor/proxy | Conexiones a `/terminal/ws` desde IPs inesperadas |
| Creación de sesiones PTY | Monitoreo de procesos | Procesos de shell inesperados generados por el servidor Marimo |
| Acceso a archivos | Registros de auditoría de archivos | Lecturas de `.env`, archivos de credenciales o claves SSH |
| Uso de credenciales | Registros de auditoría del proveedor de nube | Llamadas a la API que utilizan claves almacenadas en el entorno de Marimo |
| Transferencia de datos salientes | Monitoreo de red | Tráfico de salida inusual desde el host de Marimo |

**Comandos de investigación:**```bash
# Check for active WebSocket connections
ss -tnp | grep <MARIMO_PORT>

# Review process tree for unexpected shells
ps aux --forest | grep -A5 marimo

# Check if .env or credential files were recently accessed
stat .env
stat ~/.aws/credentials

# Review cloud provider activity logs for unauthorized access
aws cloudtrail lookup-events --lookup-attributes AttributeKey=AccessKeyId,AttributeValue=<KEY_ID>

# Check for unauthorized outbound connections
netstat -tnp | grep ESTABLISHED | grep -v 127.0.0.1

Remediación

Acciones inmediatas (hazlas ahora):

  1. Actualiza a Marimo 0.23.0 o posterior (pip install --upgrade marimo)
  2. Restringe el acceso de red a las instancias de Marimo mediante reglas de firewall (enlaza solo a localhost o IPs de confianza)
  3. Comprueba si hay conexiones no autorizadas en los registros de tu servidor

A corto plazo (esta semana):

  1. Rota TODAS las credenciales que eran accesibles desde los entornos de Marimo (claves de AWS, tokens de API, contraseñas de bases de datos, cuentas de servicios en la nube)
  2. Audita los registros de actividad de tu proveedor de nube en busca de llamadas API no autorizadas que utilicen credenciales potencialmente comprometidas
  3. Revisa los archivos .env y las variables de entorno para detectar cualquier dato sensible que pueda haber quedado expuesto
  4. Comprueba si hay mecanismos de persistencia (claves SSH no autorizadas, trabajos cron, scripts de inicio modificados)

A largo plazo:

  1. Nunca expongas los entornos de notebooks directamente a internet (usa VPN o túneles SSH)
  2. Trata los entornos de desarrollo de IA/ML como activos de alta seguridad (contienen credenciales de nube y tienen capacidades de ejecución de código)
  3. Incluye los servidores de notebooks en tu programa de escaneo de vulnerabilidades habitual
  4. Implementa monitorización de red para las instancias de servidores de notebooks con alertas ante conexiones inesperadas

Referencias

  • The Hacker News — Marimo RCE Flaw CVE-2026-39987 Exploited Within 10 Hours
  • SecurityWeek — Critical Marimo Flaw Exploited Hours After Public Disclosure
  • BleepingComputer — Critical Marimo Pre-Auth RCE Flaw Now Under Active Exploitation
  • Security Affairs — CVE-2026-39987: Marimo RCE Exploited in Hours After Disclosure
  • CSA Labs — Marimo Pre-Auth RCE: AI Development Toolchain Under Attack
  • GBHackers — Marimo RCE Vulnerability Exploited Within 10 Hours
  • InfoWorld — Critical Flaw in Marimo Python Notebook Exploited Within 10 Hours

Autor

Kerem Oruç — Ingeniero de Ciberseguridad

  • GitHub: @keraattin
  • Twitter: @keraattin
Descargar herramienta