Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
工具/GitHubGitHub/rootdirective-sec/cve-2026-39987-lab
容器安全漏洞分析漏洞利用Web安全学习与教育实验室与实践
GitHubrootdirective-sec/cve-2026-39987-lab

CVE-2026-39987-Lab

本地 Docker 实验环境,复现 CVE-2026-39987——marimo 终端 WebSocket 中的未授权远程代码执行漏洞。对比存在漏洞与已修复版本,并附带危害最小的 PoC 脚本,供教育性安全研究使用。

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享
查看仓库
1104个月前尚未审核

CVE-2026-39987 — marimo 预认证终端 WebSocket RCE 实验环境

仅限本地的 Docker 实验环境,用于复现和理解 marimo 中的 CVE-2026-39987。 本项目将存在漏洞的 marimo 服务与已修复的 marimo 服务并排对比,然后使用最小危害证明脚本演示两者之间的差异。


执行摘要

CVE-2026-39987 是 marimo(一个响应式 Python 笔记本框架)中的一个严重的预认证远程代码执行漏洞。

漏洞行为存在于终端 WebSocket 端点:

root@kitploit:~
/terminal/ws

在受影响版本中,该端点无需有效认证即可访问,并且可以创建交互式终端会话。能够访问存在漏洞的 marimo 编辑服务器的未认证攻击者,可以以 marimo 进程的权限执行命令。

本实验环境在受控的本地 Docker 环境中复现该漏洞:

服务版本URL预期行为
vulnmarimo 0.20.4http://127.0.0.1:8081/terminal/ws 接受未认证的 WebSocket 连接
patchedmarimo 0.23.0http://127.0.0.1:8082/terminal/ws 以 403 Forbidden 拒绝未认证的 WebSocket 连接

目标不是提供武器化的漏洞利用代码。目标是使用仅限本地的、可复现的证据,展示存在漏洞版本与已修复版本之间可观察到的安全差异。


漏洞概述

受影响组件

受影响的组件是 marimo 的终端 WebSocket 端点:

root@kitploit:~
/terminal/ws

该端点由 marimo 的编辑环境使用,通过浏览器连接的 WebSocket 会话提供终端功能。

根本原因

存在漏洞的端点接受 WebSocket 连接,而未强制执行受保护的 marimo 编辑功能所预期的相同认证检查。

重要区别在于:

root@kitploit:~
存在漏洞的行为:
  未认证客户端可以连接到 /terminal/ws
  创建终端会话
  可以通过 WebSocket 发送命令

已修复的行为:
  未认证客户端被拒绝
  WebSocket 握手失败并返回 403 Forbidden
  不创建终端会话

该补丁在允许建立终端会话之前,向终端 WebSocket 流程添加了认证验证。

影响

如果存在漏洞的 marimo 编辑服务器暴露在可访问的网络中,未认证的攻击者可以以运行 marimo 进程的用户身份执行命令。

在本实验环境中,marimo 进程特意以低权限的非 root 用户身份运行:

root@kitploit:~
uid=10001(marimo) gid=10001(marimo) groups=10001(marimo)

这使演示更加安全,同时仍然证明了漏洞的存在。


实验环境目标

本实验环境旨在证明三件事:

  1. 存在漏洞的版本接受对 /terminal/ws 的未认证 WebSocket 连接。
  2. 可以通过该未认证的终端 WebSocket 执行良性命令。
  3. 已修复的版本以 403 Forbidden 拒绝相同的未认证 WebSocket 尝试。

本实验环境刻意避免破坏性命令、持久化、反向 Shell、凭据窃取或任何面向互联网的目标。


仓库结构

root@kitploit:~
.
├── docker-compose.yml
├── vuln/
│   ├── Dockerfile
│   └── notebook.py
├── patched/
│   ├── Dockerfile
│   └── notebook.py
├── poc/
│   ├── poc.py
│   ├── rce_poc.py
│   └── requirements.txt
├── SAFETY.md
├── README.md
└── .gitignore

重要文件


实验环境架构

root@kitploit:~
宿主机

127.0.0.1:8081  ─────►  vuln 容器
                         marimo 0.20.4
                         /terminal/ws 接受未认证的 WebSocket

127.0.0.1:8082  ─────►  patched 容器
                         marimo 0.23.0
                         /terminal/ws 拒绝未认证的 WebSocket

两个服务都暴露 marimo 的内部端口 2718,但宿主机端口不同:

root@kitploit:~
vuln    -> 127.0.0.1:8081
patched -> 127.0.0.1:8082

服务仅绑定到 127.0.0.1。它们不打算暴露给局域网或互联网。


Docker 加固说明

容器在可能的情况下配置了多项防护措施:

root@kitploit:~
- 仅将端口绑定到 127.0.0.1
- 以非 root 用户身份运行
- 丢弃 Linux 能力
- 启用 no-new-privileges
- 使用只读根文件系统
- 仅提供有限的 tmpfs 写入位置
- 将服务隔离在专用的 Docker 桥接网络中

这些控制措施不会消除存在漏洞服务中的漏洞。它们减少了本地演示的爆炸半径。


先决条件

已测试的假设:

root@kitploit:~
- Linux x86_64 或带 Docker Desktop 的 macOS
- Docker Compose v2
- Python 3.9+
- 仅限 localhost 测试

所需工具:

root@kitploit:~
docker --version
docker compose version
python3 --version

设置

克隆或进入项目目录:

root@kitploit:~
cd cve-2026-39987

构建并启动两个服务:

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

检查两个容器是否都在运行:

root@kitploit:~
docker compose ps

预期服务:

root@kitploit:~
cve-2026-39987-vuln
cve-2026-39987-patched

验证版本

检查存在漏洞服务的版本:

root@kitploit:~
docker compose exec vuln marimo --version

预期:

root@kitploit:~
0.20.4

检查已修复服务的版本:

root@kitploit:~
docker compose exec patched marimo --version

预期:

root@kitploit:~
0.23.0

安装 PoC 依赖项

创建 Python 虚拟环境:

root@kitploit:~
python3 -m venv .venv
source .venv/bin/activate

安装依赖项:

root@kitploit:~
python -m pip install -r poc/requirements.txt

最小危害 PoC

主要证明脚本是:

root@kitploit:~
poc/poc.py

它尝试连接到:

root@kitploit:~
/terminal/ws

然后仅发送良性证明命令:

root@kitploit:~
id
whoami
hostname

不使用反向 Shell、文件写入、持久化、凭据访问或破坏性命令。

测试存在漏洞的服务

运行:

root@kitploit:~
python poc/poc.py --base-url http://127.0.0.1:8081

预期结果:

root@kitploit:~
[*] 目标 WebSocket: ws://127.0.0.1:8081/terminal/ws
[*] 仅发送良性证明命令: id; whoami; hostname
[+] websocket 无需凭据即可连接
[result] 存在漏洞: 观察到未认证的命令执行
[proof]
uid=10001(marimo) gid=10001(marimo) groups=10001(marimo)
marimo
<容器主机名>

如果脚本打印原始终端输出但包含以下块,则漏洞仍然得到确认:

root@kitploit:~
CVE39987_PROOF_START
uid=10001(marimo) gid=10001(marimo) groups=10001(marimo)
marimo
<容器主机名>
CVE39987_PROOF_END

这意味着 WebSocket 连接成功,并且命令输出从终端会话返回。

测试已修复的服务

运行:

root@kitploit:~
python poc/poc.py --base-url http://127.0.0.1:8082

预期结果:

root@kitploit:~
[*] 目标 WebSocket: ws://127.0.0.1:8082/terminal/ws
[*] 仅发送良性证明命令: id; whoami; hostname
[-] websocket 连接被拒绝/失败: 握手状态 403 Forbidden
[result] 此未认证检查无法利用

这表明已修复的服务在创建终端会话之前拒绝未认证访问。


实时学习客户端

以下文件仅用于本地学习:

root@kitploit:~
poc/rce_poc.py

它通过连接到存在漏洞的终端 WebSocket 并允许终端交互,以更实时的方式演示相同的问题。

仅可针对本地 Docker 实验环境使用。

针对存在漏洞的服务运行

root@kitploit:~
python poc/rce_poc.py --base-url http://127.0.0.1:8081

预期行为:

root@kitploit:~
[+] 连接成功(预认证 RCE)
✓ 交互式 Shell 已准备好使用!

可尝试的安全命令:

root@kitploit:~
id
whoami
hostname
pwd
python -c 'import marimo; print(marimo.__version__)'
exit

针对已修复的服务运行

root@kitploit:~
python poc/rce_poc.py --base-url http://127.0.0.1:8082

预期行为:

root@kitploit:~
[-] 连接失败: 403 Forbidden
[!] 这很可能是已修复的版本。
    WebSocket 端点现已受到保护。

实时模式的安全说明

实时客户端的存在是为了帮助理解存在漏洞的 WebSocket 的行为方式。它不应针对本本地实验环境之外的任何系统使用。

对于作品集发布,推荐的主要证据仍然是 poc/poc.py,因为它是有界的、可重复的且危害最小的。


预期安全差异

主要实验环境结果应总结为:

root@kitploit:~
vuln / marimo 0.20.4:
  对 /terminal/ws 的未认证 WebSocket 握手成功
  可以观察到良性命令输出

patched / marimo 0.23.0:
  对 /terminal/ws 的未认证 WebSocket 握手失败
  服务器返回 403 Forbidden
  不创建终端会话

这是 CVE 复现的核心证明。


手动 WebSocket 检查

如果您想手动检查该行为,请使用支持 WebSocket 的客户端并连接到:

root@kitploit:~
ws://127.0.0.1:8081/terminal/ws
ws://127.0.0.1:8082/terminal/ws

预期:

root@kitploit:~
8081 -> 连接被接受
8082 -> 403 Forbidden

PoC 脚本是首选,因为它们产生更清晰的证据。


检测和监控思路

在真实环境中,有用的指标包括:

root@kitploit:~
- 对 /terminal/ws 的 WebSocket 请求
- 对 marimo 编辑服务器的未认证访问尝试
- marimo 生成的意外终端会话
- marimo 进程启动的命令
- 访问 .env、SSH 密钥、云凭据或笔记本机密
- /terminal/ws 连接后不久出现的外向网络流量

可检查的本地工件示例:

root@kitploit:~
docker compose logs vuln
docker compose logs patched
docker compose ps
docker compose exec vuln ps aux

清理

停止并移除容器:

root@kitploit:~
docker compose down

同时移除卷:

root@kitploit:~
docker compose down -v

如果需要,移除本地 Python 虚拟环境:

root@kitploit:~
rm -rf .venv

安全规则

本仓库仅用于本地安全研究和作品集演示。

允许:

root@kitploit:~
- localhost 测试
- 仅限 Docker 的复现
- 良性证明命令,如 id、whoami、hostname
- 比较存在漏洞和已修复的行为
- 记录根本原因和检测思路

不允许:

root@kitploit:~
- 针对公共 marimo 服务器进行测试
- 测试您不拥有或管理的系统
- 反向 Shell
- 持久化
- 凭据窃取
- 破坏性命令
- 横向移动
- 僵尸网络或恶意软件行为

免责声明

本项目仅用于授权的本地测试和防御性安全教育。请勿针对您不拥有或未经明确许可测试的系统使用这些脚本。


参考

  • GitHub 安全公告 — GHSA-2679-6mx9-h9xc:
    https://github.com/advisories/GHSA-2679-6mx9-h9xc

  • NVD — CVE-2026-39987:
    https://nvd.nist.gov/vuln/detail/CVE-2026-39987

  • marimo 上游仓库:
    https://github.com/marimo-team/marimo

  • 补丁提交 — 向终端 WebSocket 添加认证验证:
    https://github.com/marimo-team/marimo/commit/c24d4806398f30be6b12acd6c60d1d7c68cfd12a

  • 补丁 PR — marimo PR #9098:
    https://github.com/marimo-team/marimo/pull/9098

下载工具
文件用途
docker-compose.yml定义存在漏洞和已修复的 marimo 服务
vuln/Dockerfile构建存在漏洞的 marimo 服务
patched/Dockerfile构建已修复的 marimo 服务
vuln/notebook.py存在漏洞服务使用的最小 marimo 笔记本文件
patched/notebook.py已修复服务使用的最小 marimo 笔记本文件
poc/poc.py仅运行良性命令的最小危害证明脚本
poc/rce_poc.py用于在本地实验环境中观察终端行为的实时学习客户端
poc/requirements.txtPoC 脚本的 Python 依赖项
SAFETY.md安全规则和范围边界