Skip to content
KitploitKITPLOIT
工具漏洞利用博客
Log in
提交
工具漏洞利用博客
提交

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

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

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

工具目录

分类

查看所有分类
Loading categories
Kestra-cve-2026-53576 — CVE-2026-53576(Kestra 中未经身份验证的 RCE)的端到端复现与跨层检测——超越基础 PoC,展示常见的 Docker socket 错误配置如何将容器 root 权限升级为完整的主机沦陷。 | Kitploit
工具/GitHubGitHub/atlasvector/kestra-cve-2026-53576
权限提升容器安全持久化机制漏洞分析漏洞利用后渗透利用渗透测试论文与研究红队

最受欢迎

查看全部 →

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

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享
事件响应
实验室与实践
GitHubatlasvector/kestra-cve-2026-53576

Kestra-cve-2026-53576

CVE-2026-53576(Kestra 中未经身份验证的 RCE)的端到端复现与跨层检测——超越基础 PoC,展示常见的 Docker socket 错误配置如何将容器 root 权限升级为完整的主机沦陷。

查看仓库
2天前尚未审核

Kestra 中通过尾部路径认证绕过实现的未认证 RCE(CVE-2026-53576)

目录

  • 执行摘要
  • 1. 概述
  • 2. 受影响 / 已修复版本
  • 3. 测试环境与预检
  • 4. 根本原因
  • 5. 攻击模拟
  • 6. 检测工程
  • 7. ATT&CK 映射
  • 8. 修复与加固
  • 9. 参考资料

执行摘要

Kestra 是一个开源工作流编排平台,其发布的认证过滤器通过检查 URL 是否以 /configs 结尾来判断请求是否需要凭据——这一检查本意是暴露一个无害的公共端点。

由于该检查只查看字符串的尾部,任何 URL 恰好以该方式结尾的请求都会完全跳过认证,包括那些创建并运行任意代码的端点。 结果:任何能够通过网络访问存在漏洞的 Kestra 实例的人,都可以在零凭据的情况下以 root 身份运行命令,无需钓鱼、无需猜测密码、无需任何权限提升步骤。

在本次演练中,这一单一缺口被端到端地应用于一个自托管实验实例:

  • 未认证代码执行。
  • 发现暴露的 Docker socket。
  • 提升为底层主机上的完整 root 访问权限。
  • 两种独立的持久化机制(一个 SSH 后门密钥和一个计划信标)。

每个阶段都针对防御遥测(网络 IDS、主机运行时安全、Linux 审计和系统日志)进行了捕获。

未修补时的业务影响: 运行 Kestra 的主机被完全攻陷,而不仅仅是应用程序——进而波及从该主机可访问的任何其他内容。

修复: 升级到 Kestra 1.0.45 / 1.3.21 或更高版本(仅补丁即可关闭主要漏洞;提升和持久化阶段需要单独的、独立的修复——不要将 Docker socket 挂载到应用程序容器中,参见第 8 节)。

1. 概述

本报告记录了 CVE-2026-53576,这是一个 CVSS 10.0 的未认证远程代码执行漏洞,存在于 Kestra ≤1.3.20 中,由路径后缀认证绕过(AuthenticationFilter.java,endsWith("/configs"))引起。

攻击者将工作流的命名空间和 ID 命名为 configs,即可在无凭据的情况下,以 root 身份在 Kestra 容器内创建并执行任意 shell 命令。已在 1.0.45 和 1.3.21 中修复。同一漏洞也被独立报告为 CVE-2026-49869,这是与真实野外利用相关的 CISA KEV 列出的编号。两者应一并引用,因为公开来源和扫描器可能引用其中任意一个。

2. 受影响 / 已修复版本

受影响Kestra ≤ 1.3.20(以及 1.0.x 系列中 1.0.45 之前的版本)
已修复1.0.45 / 1.3.21+
CVECVE-2026-53576
孪生公告CVE-2026-49869 - 同一漏洞,CISA KEV 列出(野外利用)

时间线

日期事件
2026-06-02Kestra 1.3.21 发布;变更日志提到“认证过滤器中潜在的认证绕过”
2026-06-03Kestra 1.0.45 在 1.0.x 系列上发布
2026-09-02CVE-2026-49869(孪生公告)被添加到 CISA KEV 目录
2026-09-22 至 09-24本次实验复现、检测构建和跨层验证

3. 测试环境与预检

自托管家庭实验室: - Debian 主机(主机名 docker,内核 6.12.107+deb13-amd64), - Docker Engine 29.8.1。 - Kestra 以官方 kestra/kestra:v1.3.20 镜像部署,可通过 kestra.int.atlasvec.com 上的 Caddy 反向代理访问。 - 被测遥测栈:Falco(运行时/eBPF,主机级), - Suricata 8.0.3 IDS(被动 SPAN 镜像),转发至 Splunk。

在接触任何东西之前,我确认了目标确实存在漏洞,并且遥测栈处于活动状态。我还对攻击前状态进行了快照,以便完成后可以还原。

Kestra 运行着存在漏洞的版本: 01-kestra-version-v1.3.20

容器本身已启动并可访问: 06-docker-kestra-running

Falco 的单元已在主机上加载: 02-falco-units-one-active

Falco 正在主动发出事件(现代 eBPF 模式): 03-falco-modern-bpf-active-emitting

Suricata 服务处于活动状态: 04-suricata-systemctl-active

并且其 eve.json 正在实时写入事件: 05-suricata-eve-json-live

4. 根本原因

这是两个错误叠加在一起,而不是一个。

首先,认证过滤器通过匹配请求路径的末尾来决定请求是否可以跳过认证:```java // AuthenticationFilter.java — the vulnerable check, confirmed against the self-hosted v1.3.20 source if (path.endsWith("/configs")) { // treated as a public, unauthenticated path }

root@kitploit:~
这个检查的存在是为了暴露一个无害的端点,即公开的实例配置。由于 `endsWith` 只读取字符串的尾部,它无法区分一个安全路径和任何其他恰好以相同方式结尾的路径。

其次,Kestra 的路由器仍然会将这些看起来相似的路径分发到它们真正的、敏感的处理器。`/api/v1/main/flows/configs` 会到达 flow-create 处理器。`/api/v1/main/executions/configs/configs` 会到达 execution 处理器。过滤器将两者都作为公开路径放行,而路由器无论如何都会执行它们。将一个 flow 的 namespace 和 ID 都命名为 `configs`,一个可执行代码的端点现在就以 `/configs` 结尾,因此它继承了公开路径的免费通行证。

捕获的请求对清楚地展示了这一点。`GET /api/v1/main/flows/search` 在无凭据的情况下返回 `401`。`POST /api/v1/main/flows/configs` 在相同的空 auth 头下返回 `200` 并存储了该 flow(见 §5.1)。

## 5. 攻击模拟

> 下面的每一步都附有自己的截图。所有这些都在我自己的隔离 homelab 中运行,针对的是反向代理后面的自托管 Kestra 实例。

### 5.1 阶段 1 - 认证绕过 -> Kestra 容器内的 root

**对照:** `GET /api/v1/main/flows/search` 在无凭据的情况下 → `401 Unauthorized`。
确认正常路由上强制执行了认证。
![01-burp-control-401](https://assets.kitploit.com/production/public/readmes/56348/2a6d266e96b2b4e09bc32c0ccf3609159eaf5bacdc204989d5572211e616e6ff/8a8bab993fd7ba08656d03ad85822001996be4c391de87c535751cc9e14542a1-display-v1.webp)
_____

**植入:** 发送 `POST /api/v1/main/flows/configs`,不带 auth 头。请求体是一个 flow YAML,其 `namespace` 和 `flow id` 都是 `configs`,包含一个使用 Process 任务运行器的 Commands 任务。服务器返回 `200 OK` 并存储了该 flow。一个原本受保护的路由上的 `/configs` 后缀正是触发绕过的原因 **(见第 4 节)。**
![02-burp-plant-flow-200](https://assets.kitploit.com/production/public/readmes/56348/5d2a2db2d70e9d60e7136c765a7a85f4d8b684ea945da5b84e84d85a2b05a151/1ee6d8f7efd58d22ef41b536f32acbbdd417d68ac030ed28e2d06f9d6d4ccb93-display-v1.webp)
**监听与等待**:出于测试目的,使用 nc 启动一个简单的监听器,以便我们捕获反向 shell。

![03-kali-listener-4444](https://assets.kitploit.com/production/public/readmes/56348/88d7d3516aaeef900bbb9b372d9006323a3d7391078b693124ee24710da557ac/aa9806454d3742b7e958611a5c6ed2d3dfb3072eec3c14e4bb3f050a41220803-display-v1.webp)




**触发 / 执行** `POST /api/v1/main/executions/configs/configs`,不带 auth 头 → `200 OK`,创建了新的执行。
![04-burp-execute-200](https://assets.kitploit.com/production/public/readmes/56348/e70d1cd38f3825dca36c25e722bdfcf4a7614b1402fe1b6d0ccebdf992738bbe/9a394373a293d22ef55e3b6ee32eae6991feac73a5ccbc7909536bdf3435172d-display-v1.webp)

**BaaaaM:** 我们已经弹出了 shell,但请记住——我们是“隔离的”,`root` **但是** 在 Kestra docker 容器内部,所以我们“不应该”能够从这里逃逸。“**好吧,我原本是这么想的**”
![05-kali-revshell-container](https://assets.kitploit.com/production/public/readmes/56348/97257430abd2415f37f12c790a738d73e12f0c2509c193b1b7d24545453a1a70/9880399e445d4b8b602c1f381bbd8523a83c8c3c097b9a919e2b1871c7f1129e-display-v1.webp)


该任务的命令作为 Kestra JVM 进程的直接子进程运行,已通过宿主机侧的进程树确认,并且根据 Kestra 自己的执行日志成功完成。

**Kestra 的日志仪表板**
![06-kestra-ui-pwn-log](https://assets.kitploit.com/production/public/readmes/56348/b447d0d268daa119b1d64a9d7d95a588b80a7cb228613b81a6bfd69777aea7bb/467a61936f8779b533cc83a297d651957e17f9d00241ff97cc7640df917450fe-display-v1.webp)


**Kestra 的进程树**
![07-kestra-process-tree](https://assets.kitploit.com/production/public/readmes/56348/a7e20df484e1c5759fca4f5e403bc280ffc45b03b47dae22804321bb8398858c/0a0e30aa6c0537adf8ddd204453c8d51e808de2d5ff764fc5ad8f551cf059665-display-v1.webp)

**结果:** 在 Kestra 容器内以 root 身份实现未认证远程代码执行。这是 **CVE-2026-53576** 的完整、自包含证明。


### 5.2 阶段 2 - 通过暴露的 Docker socket 提权(homelab 特有,不属于 CVE 本身)

从阶段 1 的 shell 中,发现 `/var/run/docker.sock` 被挂载到了容器内——这是一种 Docker-outside-of-Docker (DooD) 模式,当 Kestra 自己的 `Docker` 任务运行器被配置时很常见,因为它需要一个守护进程来通信。

能够访问该 socket 本身就等同于宿主机 **root**:Docker API 允许客户端为其启动的容器配置任意宿主机绑定挂载以及宿主机 PID/网络命名空间,而 socket 背后的守护进程已经在宿主机上以 root 身份运行。

这不是内核或容器逃逸漏洞——这是 Docker API 在做它被设计来做的事情,只是从一个本不应能访问它的地方被访问到了。

使用该 socket,我创建了一个兄弟容器,绑定了宿主机文件系统并使用了宿主机 PID 和网络命名空间,然后启动了它。

**注意:** 测试期间还出现了第二个更隐蔽的变体,不过我没有单独截图。同样的 socket 访问不是总是创建新的兄弟容器,而是允许你对一个已经在运行的容器执行 `POST /containers/{id}/exec`,因此根本不会有容器创建事件。在这个 Docker 宿主机上我同时有 Kestra 和 Portainer,任何一个都可以用于同样的逃逸。这对检测很重要:任何专注于新特权容器被创建的规则都会漏掉这个变体。

确认 root 并发现 socket 就在那里,未受任何限制地挂载:
![08-docker-socket-present](https://assets.kitploit.com/production/public/readmes/56348/d2a34fd7db05bb2966a540410dbc8e76cfec416a545786349372984902b128f9/ca3ce180476010ee482b60c42687751f27a072aa2c0b78fbb6400b8406cee5e5-display-v1.webp)

检查 Docker 守护进程确实可以通过该 socket 访问:
![09-docker-api-version](https://assets.kitploit.com/production/public/readmes/56348/7ce4365a9c48db827aa3c6e53c73622bef0ee7a99f530b5e37a065601b3892b0/d6debd41ca945cd5812add55df46cc5dd2f7bbaba1c88965f438ee7d5c9a4bcc-display-v1.webp)

列出本地已有的镜像,这样我就不需要拉取任何东西:
![10-docker-images-enum](https://assets.kitploit.com/production/public/readmes/56348/aa1ff3ff76e92437899afc7b603925eeb53838f99f4d8586df69f8a96ff23622/34cd26942854c4c4bf59135beb54cac278aaad304faac4a3f5b64bec9e1a84de-display-v1.webp)

第一次尝试:一个绑定了宿主机文件系统的特权容器:
![11-docker-create-privileged](https://assets.kitploit.com/production/public/readmes/56348/38f4f42a486e3f46f4d798e131b3eb3bd58a7e7507b7a9e88845ed52ee32bd29/673b8ab3de93e21c6fbe23b343c4cd7fc4ddac11554ad56c0d656e2ae46467dd-display-v1.webp)

第二次尝试,这次添加了宿主机 PID 和网络命名空间:
![12-docker-create-hostns](https://assets.kitploit.com/production/public/readmes/56348/f2a5c239adbabc9b3cef7f24d2ff60b49765bfec2ec231520d18edbcaec597cb/c387405779506f4d5e8f30715d359550b69d2c1a899525b293e8b69ce61c6e73-display-v1.webp)

第三次尝试,直接 chroot 进入挂载的宿主机文件系统:
![13-docker-create-chroot](https://assets.kitploit.com/production/public/readmes/56348/dc38f66a291764a224f2982d22b9ca3cb37bdb31d39c48344b8030448f452e41/23519a1a158885f8b9b5691ffab18ef6eb1b5c989af00bf7c4caf6fe58ee7176-display-v1.webp)

监听器已启动并在逃逸 shell 将回调的端口上等待:
![14-host-listener-4491](https://assets.kitploit.com/production/public/readmes/56348/37b558192ffff02366b4d219e2393d1f9fe468e82555c90a236e2cf1bdd35aa7/116c772ff659ec661cad22e023a6179eb8ffd1ebf409624b4832a27a4e947626-display-v1.webp)

启动容器:
![15-docker-container-start](https://assets.kitploit.com/production/public/readmes/56348/277f7899c2fbb23d86a1918621f5efe79c635bd84af584811e98bdf37b7ab253/3f02d6a19613662df1b32fb8fa1bdbb03043f6b232844d2de3a23f552873103e-display-v1.webp)


**Root,但这次是宿主机,而不是容器:**
![16-host-root-id](https://assets.kitploit.com/production/public/readmes/56348/0a77d4e6c239354c2c79737c51f492005cf129af8c5a595614c1005c0a125405/02ed259073555446cd67e2ce2ab86c7408fb9c2e7864ce3daac8bc50fbd2db36-display-v1.webp)

内核版本与真实宿主机匹配,而不是容器的隔离视图:
![17-host-root-uname](https://assets.kitploit.com/production/public/readmes/56348/9f059686a831bfb8b5196412b9fd10492e8aeeb211dcb7d45fc98b3b6c0f999c/2c2dbd97e8c41b21085d9230d3b2ffb74f76c693947d9831007cff197fe3647d-display-v1.webp)


升级为适当的交互式 shell 以用于会话的其余部分:
![18-host-pty-upgrade](https://assets.kitploit.com/production/public/readmes/56348/34894e77c38df22cbbd807a14fd14b8e49aadc6f894d990e4022bc5b85978b62/0f81e4ed6fa6dfef8867eed194e7e4cdf12dc025b00c5763b2884530199c15d7-display-v1.webp)

### 5.3 阶段 3 - 持久化,确认触发

从宿主机 root shell 中,我设置了两个独立的持久化机制,

**第一**,一个 SSH 密钥。我检查了谁已经拥有访问权限:
![19-host-authkeys-enum](https://assets.kitploit.com/production/public/readmes/56348/553f3a2b399361ce652e836fab2525686519f44dee9d94d8b7c9d45b1b939d44/0a2c697dc0f216566dba1b4cb38f134ce23ff7b57bc40dc87032016a558e2668-display-v1.webp)

然后检查了 sshd 自己的配置,看是否有任何会阻止新密钥的内容:
![20-host-sshd-config-enum](https://assets.kitploit.com/production/public/readmes/56348/a25dd7b5a8376e48cee6c75e64264fa973def1db09a9d7ea520b705e32021ef3/adbfee0a5f27442b43fa318a36ef281d5abc1d998c367f2e5978b11d8282677d-display-v1.webp)

在攻击机上生成了一对密钥:
![21-attacker-keygen](https://assets.kitploit.com/production/public/readmes/56348/4b560189f5ab37c619d941dfedadd77a4fa8a49420aa720eafd6fccc44f7f734/f90cf5f5b1ebb76fe1505b063ef844e17c9c7b8e9f21a2f92213eb36f9428dec-display-v1.webp)

确认 sshd 确实在监听:
![22-host-sshd-active](https://assets.kitploit.com/production/public/readmes/56348/bd0ee4ae0a24f08b096c16eff66fd4ff87efccd92f1c1b509078d24f65af0e0f/78518194b025287cdf07b81a3335ea8b02239fcca6cbd2f32b507e28cc908cf9-display-v1.webp)

将公钥放入 root 的 `authorized_keys`:
![23-host-authkeys-implant](https://assets.kitploit.com/production/public/readmes/56348/e2faba217e62433f6dcd9777fa85c8dcd24858ab1c6a2f5d1293515d744003bc/0c1ca3973a85e0ade63514eaa9ad4f3d0fd63f047dc7be19b112058f24632cfd-display-v1.webp)

并使用匹配的私钥登录:
![24-ssh-root-login-proof](https://assets.kitploit.com/production/public/readmes/56348/14b698fb9eae32aff09e6ec7d179ecf1c2ef665d7b87be8d6f9fac956e68db2b/a2ced84629d34de099a598e38f71ba54411a890eaadb50a2dc8dd8dc099a6459-display-v1.webp)

**附注:** 这是独立于原始 RCE 链的 root 访问。即使 Kestra 被修补,这个密钥仍然有效。

**第二**,一个 cron 信标。我放置了一个 root 级别的回调,设置为按间隔运行,然后用一个新的监听器测试它是否真的按计划触发:
![25-host-cron-persist](https://assets.kitploit.com/production/public/readmes/56348/3dfa92072c55dd052127ef69943a6c43a855534420b286e0dbd62ce833dc441f/7a75828de1e323b44a4c792a2eed2713cf656433685deef7931026f815b2dd98-display-v1.webp)

**它触发了。在宿主机上的第二个立足点,独立于 RCE 和 SSH 密钥。**


### 5.4 已验证的 kill-chain 时间线。

下面的时间线不同:它完全是从独立的防御方遥测(网络 IDS + 宿主机运行时安全)重建的,并针对真实的 Splunk 数据实时提取和验证。

**主要 RCE - 网络检测到投递,宿主机确认执行,相隔 103 秒:**

| 时间 (EDT)   | 层              | 事件                                                                                        |
| ------------ | ------------------ | -------------------------------------------------------------------------------------------- |
| 02:46:09.778 | 网络 (Suricata) | 针对此确切 CVE 的公开 ET 签名触发                                                 |
| 02:47:52.277 | 宿主机 (Falco)       | 在 Kestra 容器内确认反向 shell,捕获了确切的命令和容器 ID |

**提权 - 网络和宿主机各自独立地佐证了同一事件的不同部分:**

| 时间 (EDT)   | 层              | 事件                                                                                                                              |
| ------------ | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------- |
| 03:48:55.503 | 宿主机 (Falco)       | 来自提权容器的反向 shell                                                                                        |
| 03:51:57.360 | 网络 (Suricata) | TCP 流 **和** 一个基于内容的告警 - 当运行 `id` 时,字面字符串 `uid=0(root)` 被看到以明文离开宿主机 |


## 6. 检测工程

我针对真实捕获的遥测构建了检测,然后针对重放测试了每一个。矩阵显示了在我开始之前覆盖存在的地方以及不存在的地方。

### 6.0 检测覆盖矩阵

| 阶段 | 网络 (Suricata) | 宿主机 (Falco) | 宿主机 (auditd/journald) | 状态 |
| --- | --- | --- | --- | --- |
| 初始漏洞利用请求 | 公开 ET 签名触发 | 无应用层可见性 | - | 已覆盖(预先存在) |
| RCE 执行 | - | 原生规则,标记为 T1059 | - | 已覆盖(预先存在) |
| Docker-socket 提权(该技术) | - | 缺口:只捕获结果 shell,而不是 socket 滥用 API 调用 | EXECVE 记录捕获确切的 `curl --unix-socket` 调用 | 发现缺口,用 auditd + 自定义 Falco 规则关闭 |
| 提权影响确认 | 对泄露的 `id` 输出的内容告警 | 相同的通用 shell 规则 | - | 已覆盖(预先存在,跨层) |
| SSH 持久化 | - | - | journald:完整的 PAM 生命周期加上密钥指纹 | 已覆盖(仅宿主机) |
| Cron 持久化 | - | - | journald 和 linux_audit,两个来源,确切的 5 分钟节奏 | 已覆盖(仅宿主机) |

缺口是 docker-socket 提权。Falco 的默认规则会捕获被入侵容器生成的 shell,但稳定默认集中没有任何东西会标记一个进程访问 `/var/run/docker.sock` 来直接驱动 Docker API。那些会涉及特权容器启动的规则,`Launch Privileged Container` 和 `Launch Sensitive Mount Container`,以 `incubating` 和 `sandbox` 成熟度发布,因此默认规则集也不会加载它们。我用一个 auditd 关联搜索(检测 03)和一个自定义 Falco 规则(§6.3)关闭了这个缺口。

### 6.1 Splunk - 五个关联搜索,已部署并调度

所有五个都在 Splunk 中实时运行(`*/5 * * * *`,启用了告警跟踪,按字段节流),而不仅仅是写下来留作文本。每个的完整 SPL、确切的 FP 说明、严重性、MITRE 标签和响应运行手册都在 `detections/splunk/*.spl` 中。下面的状态表是每个的实时测试结果,包括我发现并修复的一个真实 bug。

| #   | 检测                                                  | MITRE                | 状态                                                                                                                              |
| --- | ---------------------------------------------------------- | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| 01  | 网络漏洞利用签名(消费 Suricata ET 告警) | T1190                | **已触发** - 历史重放确认,此后无新事件(在当前回溯窗口之外)                                             |
| 02  | 宿主机 RCE 执行(Falco 重定向到网络规则)        | T1059                | **已触发** - 历史重放确认                                                                                             |
| 03  | Docker-socket 滥用(auditd,缺口关闭者)               | T1610, T1611         | **在实时调度器本身上触发** - 在真实的 `*/5 * * * *` 运行中确认 `triggered_alert_count: 1`,而不仅仅是手动测试 |
| 04  | SSH root 登录持久化                                 | T1098.004, T1021.004 | **已触发** - 历史重放确认                                                                                             |
| 05  | Cron 信标持久化                                    | T1053.003            | **已部署,但我发现并实时修复了一个 bug。** `-10m` 调度窗口只容纳了 `distinct_intervals >= 3` 阈值所需的三个 5 分钟桶中的两个,因此尽管信标在真实数据中仍在运行,它永远无法触发。将其扩大到 `-30m` 并重新部署 - 此后调度器已触发它 53 次,所以修复有效。 |

检测 03 的分工是刻意的:与其在 SPL 中重新实现 Suricata 自己的签名逻辑,或者试图让 Falco 捕获一个它并非为此构建的 socket 级技术,这里的 SIEM 层消费 auditd 对确切 `curl --unix-socket` 调用的 EXECVE 记录——这是被证明对此特定技术最可靠的遥测来源。

1. **检测 01** - ET 签名触发(`suricata:eve` 告警):```spl
index=main sourcetype=suricata:eve event_type=alert
  alert.signature="ET WEB_SPECIFIC_APPS Kestra Unauthenticated Remote Code Execution (CVE-2026-53576)"
| stats count min(_time) as first_seen max(_time) as last_seen
        values(src_ip) as source_ips
  by dest_ip dest_port
| eval first_seen=strftime(first_seen,"%Y-%m-%d %H:%M:%S")
| eval last_seen=strftime(last_seen,"%Y-%m-%d %H:%M:%S")

det01-network-et-signature

  1. 检测 02 - Falco 的重定向到网络规则,按容器拆分。源 IP 从 Kestra 容器的桥接地址(172.17.0.3,端口 4489 上的主要 RCE)转移到宿主机本身(172.66.66.67,端口 4491 上的提权)——容器到宿主机的提权变得可见——而目标保持不变:攻击者的监听器位于 172.66.66.125: det02-falco-redirect-revshell

  2. 检测 03 - curl --unix-socket docker.sock 的 auditd EXECVE 记录: det03-auditd-docker-sock

  3. 检测 04 - journald root SSH 登录,密钥指纹已捕获: det04-ssh-root-login

  4. 检测 05 - 隐藏点文件 cron 信标(/usr/local/bin/.sysmon)以 root 身份按精确的 5 分钟节奏运行:在约 6.5 小时内(04:30-11:00 EDT)有 79 个不同的间隔。distinct_intervals >= 3 阈值正是将周期性信标与一次性 cron 任务区分开来的关键: det05-cron-beacon

全部五个都部署为计划保存搜索(*/5 * * * *): saved-searches-scheduled

证明 cron 调度器确实运行了这些搜索,而不仅仅是它们存在:全部五个都执行了 54 次。检测 03 触发了一次(docker-socket 滥用,06:35 EDT),检测 05 触发了 53 次(仍在活动的 cron 信标)。检测 01/02/04 显示 0 次触发,因为这些是一次性历史事件(漏洞利用请求、RCE、SSH 登录),已超出 -10m 回溯窗口,而实时或重复出现的实例仍会告警: scheduler-triggered-alert

6.2 Sigma - 可移植的主机进程生成规则

/dev/tcp/ 反向 shell 模式——在主要 RCE 和提权回调中都被使用。SigmaHQ 为此提供了一个规则:"Suspicious Reverse Shell Command Line"(id 738d9bcf-6999-4fdb-b4ac-3033037db8ab,由 Nextron Systems 的 Florian Roth 编写),其关键词之一是 bash -i >& /dev/tcp/——正是我们捕获中出现的内容。

因此我原样引入了该规则(detections/sigma/lnx_shell_susp_rev_shells.yml),并将其关键词与检测 02 已捕获的同一 Falco 事件进行比对。Sigma 本身不会"触发"——它是一个可移植的签名,而不是一个运行中的引擎——但我可以展示其关键词落在本次运行的真实遥测数据上,而不是教科书示例上。

公开的 SigmaHQ 规则 "Suspicious Reverse Shell Command Line"——其 bash -i >& /dev/tcp/ 关键词与检测 02 的同一真实事件比对:

sigma-devtcp-match-event

6.3 Falco - 自定义规则填补 docker-socket 空白

detections/falco/docker_socket_abuse.yaml——部署到实时 Falco 实例,并确认在真实重放中触发,2026-09-24T10:27:29Z。

Falco 的默认规则集不覆盖此场景。检测进程访问 /var/run/docker.sock 并非新想法——Sysdig 自己的 Falco 示例通过监视套接字路径上的 open_write 来实现——但随附/默认规则集中没有这样的规则(该项目有一个未解决的请求,falcosecurity/falco #2940),而唯一相邻的默认规则只能捕获 docker/kubectl CLI,而非原始的 curl --unix-socket。

问题在于:标准的 open_write-on-the-socket 方法在此设置中未能触发——在 modern_bpf 和被动镜像下,套接字是通过 connect() 而非 open() 访问的。因此我改为在进程生成时匹配进程命令行(spawned_process + proc.cmdline contains "docker.sock"),这是 Falco 在此已能可靠处理的同一事件类别。每次调用触发两次——shell 包装器和 curl 叶子进程——并带有完整上下文:``` priority=Critical, container_id=d417e027d444, image=kestra/kestra:v1.3.20, user=root, cmdline="curl -s --unix-socket /var/run/docker.sock http://localhost/version", tags=[T1610, T1611]

root@kitploit:~
自定义 Falco 规则触发 - “Unexpected Process Accessing Docker Socket”(T1610/T1611):
![det17-falco-custom-docker-sock](https://assets.kitploit.com/production/public/readmes/56348/6fa1b11a7c8c6a3c8619ac95a2950cf1f326df0ef1651324aa0b4f80db389a12/8ac8f1a2c5184a84ba2af0c9c85c3112506e19c62b0734105e5b74c90e4d8078-display-v1.webp)

触发的原生 Falco 规则 - 默认规则集没有 docker-socket 规则,这正是缺口所在:
![falco-rule-inventory](https://assets.kitploit.com/production/public/readmes/56348/5da667ac881b32f6bc633e58b4d00a08ea22cf3a5000b3ae8522cb3937b051a4/3fe1201158632dc6aef5257bf3620e83e087814f3da0108f7d2ef04fd5088ec9-display-v1.webp)

### 6.4 Suricata - 已有公开覆盖,自定义规则暂缓

主要漏洞利用的网络层已由一条公开的 Emerging Threats 签名覆盖,即 `ET WEB_SPECIFIC_APPS Kestra Unauthenticated Remote Code Execution (CVE-2026-53576)`,该签名在第二阶段对真实流量触发。

下面是同一绕过行为在网络层的表现,我根据漏洞模式构建了查询。所有路径以 `/configs` 结尾、位于 `flows` 或 `executions` 端点上的请求都返回 `200`,而正常路由(`/flows/search`)返回了预期的 `401`。

`Attacker IP (XFF)` 列是真实的 HTTP 源地址,读取自 `X-Forwarded-For` 头:`10.10.10.106`,即我运行 Burp 的 Mac。Suricata 自身的 `src_ip` 只能看到反向代理跳(`172.66.66.1`)。这与后来接收反向 shell 并完成 SSH 登录的 `172.66.66.125` Kali 主机是不同的机器,因此 HTTP 漏洞利用和回调来自不同的主机。

![suricata-raw-post-http](https://assets.kitploit.com/production/public/readmes/56348/d713d35f0d858af8dd5d477a9929ed6d07e55bce5e9e43946dfe1fb1cca73699/975155c6fe8a39a0de715497a7e5a659b17641a7ed4ed2d7f4d7bfcd02842398-display-v1.webp)

### 6.5 仪表盘

`cve_2026_53576_kill_chain` 已部署到 Splunk,包含:核心 KPI(检测层、ATT&CK 技术、已部署检测、持久化机制)、按遥测层着色的攻击时间线柱状图、带各阶段实时证据计数的 MITRE ATT&CK 杀伤链映射、§5.4 中的网络与主机关联时间线、按计划保存搜索的检测覆盖率、docker-socket 技术细分,以及从日志实时提取的失陷指标表。

- KPI、攻击时间线图以及 ATT&CK 映射的开头部分:
![dashboard-kill-chain-1](https://assets.kitploit.com/production/public/readmes/56348/e0fe4ac39189ed9b3c4741ab5c8fb3276484a482dcb476b11e14381700647afd/5f586685c93346bd1df629ea4092a5a61146d0a32c2d258dfba620b3dd984161-display-v1.webp)

- ATT&CK 映射的其余部分、关联杀伤链、检测覆盖率与 docker-socket 细分并列,以及 IOC 表:
![dashboard-kill-chain-2](https://assets.kitploit.com/production/public/readmes/56348/f4479575da20da3a4028a0abaac1c3b565c5b034582b157730599a15601e195f/8b18bbbdd05d8955c38f457d71029f3b2be53b409959a7560c0f8f08f038cbaf-display-v1.webp)


## 7. ATT&CK 映射

| 战术                 | 技术                                                      | 证据                                                                                                    |
| -------------------- | --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| 初始访问             | T1190 - 利用面向公众的应用                                | Control/plant/execute 请求(§5.1);Suricata ET 签名触发,§5.4                                          |
| 执行                 | T1059.004 - 命令和脚本解释器:Unix Shell                  | Kestra `Commands` 任务,主机进程树(`07-kestra-process-tree.png`);Falco 规则,§6.1 检测 02            |
| 命令与控制           | T1095 - 非应用层协议                                      | 原始 `/dev/tcp/` TCP 反向 shell - 未使用应用层 C2 封装                                                  |
| 发现                 | T1613 - 容器和资源发现                                    | 通过 socket 枚举 Docker 镜像(`10-docker-images-enum.png`)                                             |
| 权限提升             | T1610 - 部署容器                                          | 通过 Docker API 创建/启动兄弟容器(`11`–`15`);auditd EXECVE 记录,§6.1 检测 03                        |
| 权限提升             | T1611 - 逃逸到主机                                        | 主机 root 确认,主机名/内核匹配(`16`、`17`)                                                           |
| 持久化               | T1098.004 - 账户操纵:SSH 授权密钥                        | 向 `/root/.ssh/authorized_keys` 植入密钥(`23`)                                                        |
| 横向移动             | T1021.004 - 远程服务:SSH                                 | 基于密钥的 root 登录成功(`24`);journald,§6.1 检测 04                                                |
| 持久化               | T1053.003 - 计划任务/作业:Cron                           | Cron 信标,确认按计划触发(`25`);§6.1 检测 05                                                         |

## 8. 修复与加固

**主要修复措施。** 升级到 Kestra 1.0.45(1.0.x 系列)或 1.3.21+(1.3.x 系列)。仅此一项即可关闭认证绕过 - 即本次演练的第一阶段 - 并且是应用后无需进一步补偿控制的唯一修复措施。参见 [GHSA-2q47-568g-9h4f](https://github.com/kestra-io/kestra/security/advisories/GHSA-2q47-568g-9h4f)。

**如果无法立即打补丁**,按影响程度排序的补偿控制措施:

1. **反向代理强制执行** - 由于存在漏洞的过滤器仅在原始路径后缀上失败,位于 Kestra 前面的反向代理(本实验环境中为 Caddy)可以独立地对任何匹配 `/api/v1/*/(flows|executions)/.*` 的路径强制执行认证,无论其以什么结尾,从而在应用缺陷无法触及的层面关闭该绕过。
   
2. **限制 Docker socket 挂载** - 这可以完全关闭第二至第三阶段,且独立于 Kestra 补丁。不要将 `/var/run/docker.sock` 绑定挂载到 Kestra 容器中。如果确实需要 `Docker` 任务运行器,请使用限定范围的 socket 代理(例如 `docker-socket-proxy`),仅允许特定的 API 调用,而不是授予完整的守护进程访问权限 - 对 socket 的完全访问等同于主机 root,如 §5.2 所演示。
   
3. **SSH 加固** - 持久化链的第一个机制完全依赖于 root 可通过基于密钥的 SSH 访问。`PermitRootLogin no`(或要求 root 通过堡垒机/MFA)本可以阻止该特定持久化路径,无论初始 RCE 如何 - 值得独立于本 CVE 进行。
   
4. **临时检测覆盖** - 本次演练中部署并验证的 Splunk 关联搜索和自定义 Falco 规则,在安排补丁期间为该特定链条的各阶段提供临时覆盖。

**事件后清理**,如果发现此模式已被利用:应视为完整主机失陷,而不仅仅是应用失陷 - 轮换 Kestra 实例可访问的每一个凭据和密钥(KV 存储条目、下游系统的连接凭据),而不仅仅是 Kestra 自身的访问权限。

**在野状态。** `CVE-2026-49869`,同一漏洞的孪生公告,已列入 CISA 的 KEV 目录,并与已观察到的加密货币挖矿和云凭据窃取活动相关联。`CVE-2026-53576`(本报告)本身没有 KEV 条目,但它是同一个漏洞。仅跟踪两个 CVE 编号之一的漏洞管理工具可能会低报暴露情况。


## 9. 参考资料

- Kestra 安全公告 - [GHSA-2q47-568g-9h4f](https://github.com/kestra-io/kestra/security/advisories/GHSA-2q47-568g-9h4f)(CVE-2026-53576,本报告的主要来源)
- 孪生公告 - [GHSA-5vc5-wxxq-3fjx](https://github.com/kestra-io/kestra/security/advisories/GHSA-5vc5-wxxq-3fjx)(CVE-2026-49869,相同漏洞,已列入 CISA KEV)
- CVE.org - [CVE-2026-53576](https://www.cve.org/CVERecord?id=CVE-2026-53576)、[CVE-2026-49869](https://www.cve.org/CVERecord?id=CVE-2026-49869)
- CISA 已知被利用漏洞目录 - https://www.cisa.gov/known-exploited-vulnerabilities-catalog(CVE-2026-49869 条目,添加于 2026-09-02)
- 修复版本,均已确认存在并已打标签 - [v1.3.21](https://github.com/kestra-io/kestra/releases/tag/v1.3.21)(2026-06-02,变更日志明确提及“认证过滤器中的潜在认证绕过”)、[v1.0.45](https://github.com/kestra-io/kestra/releases/tag/v1.0.45)(2026-06-03)
- Docker socket 提权技术(§5.2)- [HackTricks: Docker Breakout / Privilege Escalation](https://hacktricks.wiki/en/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation/index.html)、[Trail of Bits: Understanding Docker Container Escapes](https://blog.trailofbits.com/2019/07/19/understanding-docker-container-escapes/)、[MindPatch: Docker Escape](https://www.mindpatch.net/posts/docker-escape/)
- Sigma 规则(§6.2)- 我使用而非自行编写的公开规则:[SigmaHQ "Suspicious Reverse Shell Command Line"](https://github.com/SigmaHQ/sigma/blob/master/rules/linux/builtin/lnx_shell_susp_rev_shells.yml)(id `738d9bcf-6999-4fdb-b4ac-3033037db8ab`,Florian Roth / Nextron Systems),依据 [Detection Rule License 1.1](https://github.com/SigmaHQ/sigma/blob/master/LICENSE.Detection.Rules.md) 使用
- Falco 规则(§6.3)- docker-socket 缺口是上游的一个未决请求([falcosecurity/falco #2940](https://github.com/falcosecurity/falco/issues/2940));自定义规则遵循 [Sysdig 的 Docker + Falco 示例](https://www.sysdig.com/blog/docker-falco-security)中的模式
下载工具