Percivalll/Dirty-Frag-Kubernetes-PoC

GitHub: Percivalll/Dirty-Frag-Kubernetes-PoC

利用 Dirty Frag(CVE-2026-43284)Linux 内核页缓存损坏漏洞,通过共享容器镜像层实现从非特权 Kubernetes Pod 到节点级代码执行的容器逃逸概念验证。

Stars: 7 | Forks: 1

# Dirty Frag (CVE-2026-43284) — Kubernetes 容器逃逸 PoC 这是一个概念验证,演示了**默认的非特权 Kubernetes Pod** 如何通过共享容器镜像层利用 Dirty Frag Linux 内核页缓存损坏漏洞,在 Amazon EKS 上实现**节点级代码执行**。 核心攻击原语是:**任何与攻击者控制的容器共享镜像层的特权 DaemonSet,都可以被武器化以实现容器逃逸**。此 PoC 使用 kube-proxy 作为一个具体示例,但该技术可推广至集群上的任何特权工作负载。 已在 **Amazon EKS**(内核 6.12.80)上验证——一个非特权 Pod 通过特权 kube-proxy DaemonSet 向宿主机文件系统写入了 `[*] success`: ![EKS PoC](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/76d21141d2035205.gif) ## 背景 Dirty Frag (CVE-2026-43284) 是 xfrm/ESP 接收路径中的一个 Linux 内核页缓存损坏漏洞。在受影响的路径中,`esp_input()` 会针对没有 `frag_list` 的非线性 skb 跳过 `skb_cow_data()`,从而允许 `crypto_authenc_esn_decrypt()` 将 4 字节的攻击者可控数据写入通过 `splice()` 访问的页缓存页中。 磁盘上的文件不会被修改。被损坏的字节存在于内核页缓存中,并且可以被后续读取同一缓存文件页的读取者观察到。 有关原始漏洞的完整详细信息,请参阅 [V4bel/dirtyfrag](https://github.com/V4bel/dirtyfrag)。 ## 攻击原理 该攻击利用了在 Kubernetes 集群中通常同时存在的三个属性: 1. **内核页缓存损坏 (CVE-2026-43284)** — 一个非特权进程(在支持用户命名空间的情况下)可以通过 xfrm/ESP splice 竞争条件,覆盖其可以只读方式打开的任何文件的内存中缓存页。 2. **镜像层共享** — 容器运行时(containerd, CRI-O)使用覆盖文件系统,其中相同的镜像层会映射到跨容器共享的相同页缓存页。 3. **特权 DaemonSet** — 许多集群运行具有提升权限(`privileged: true`、`hostNetwork: true`、宽泛的 capabilities 等)的 DaemonSet,这些 DaemonSet 会定期执行其镜像中的二进制文件。 当这些条件同时满足时,非特权 Pod 可以损坏共享镜像层中的二进制文件,并且同一节点上的特权 DaemonSet 将在不知情的情况下以提升的权限执行损坏的二进制文件——从而实现完整的节点级代码执行。 **漏洞目标并不限于 kube-proxy。** 任何特权 DaemonSet(监控代理、CNI 插件、日志收集器、安全代理等),只要其容器镜像与攻击者可控的镜像共享层,就是一个可行的目标。 ## 与 Copy Fail 的区别 本项目受 [Copy Fail Kubernetes PoC](https://github.com/Percivalll/Copy-Fail-CVE-2026-31431-Kubernetes-PoC) 中记录的 Kubernetes 利用模型启发,但使用了不同的内核原语。 | 属性 | Copy Fail | Dirty Frag | | --------------------- | ---------------------------------- | ----------------------------------------------------------------------------- | | CVE | CVE-2026-31431 | CVE-2026-43284 | | 内核路径 | `AF_ALG` + `splice()` | `xfrm/ESP` + `splice()` | | 命名空间要求 | 不需要 | 需要用户命名空间 | | 使用的主要能力 | 初始容器中无 | 新网络命名空间内的 `CAP_NET_ADMIN` | | 相关模块 | `algif_aead` | `esp4` | | 实际区别 | 如果 AF_ALG 向量被阻止则会失败 | 当 AF_ALG 不可用但启用了 ESP/用户命名空间时仍然有效 | ## 工作原理 攻击链包括三个阶段:**页缓存损坏**、**跨容器传播**和**特权执行**。 ### 1. 通过 xfrm/ESP 进行页缓存修补 PoC 二进制文件从非特权容器中执行以下序列: 1. 使用 `unshare(CLONE_NEWUSER | CLONE_NEWNET)` 进入新的用户和网络命名空间。 2. 注册许多 xfrm Security Association,其高序列字段编码了 4 字节的 payload 块。 3. 以只读方式打开共享镜像层中的目标二进制文件。 4. 使用 `splice()` 和精心构造的 ESP 输入触发易受攻击的内核路径。 5. 重复该原语,直到目标二进制文件的页缓存内容包含嵌入的 payload。 不需要对目标文件的写权限。磁盘上的文件保持不变——只有内存中的页缓存被损坏。 ### 2. 通过共享层进行跨容器传播 容器运行时通过内核页缓存处理来自 overlay 底层的读取。如果 PoC 容器和 `kube-proxy` 共享相同的底层文件,两者将观察到相同的缓存页。 此仓库中的 EKS 镜像构建自: ``` public.ecr.aws/eks-distro-build-tooling/eks-distro-minimal-base-iptables:2026-03-11-1773190710.2023 ``` 选择该基础镜像是为了匹配经验证环境中 EKS `kube-proxy` 用户空间工具链所使用的层。 ### 3. 由 kube-proxy 进行特权执行 当 `kube-proxy` 下次执行被修补的 iptables 系列二进制文件时,内核会加载损坏的缓存页。PoC payload 挂载宿主机根设备并将标记文件写入 `/root/res`。 预期的标记内容为: ``` [*] success ``` ### 攻击流程图 ``` ┌──────────────────────────────┐ ┌────────────────────────┐ ┌──────────────────────────┐ │ PoC Pod │ │ Kernel Page Cache │ │ kube-proxy DaemonSet │ │ unprivileged container │ │ │ │ privileged container │ │ │ │ │ │ │ │ 1. unshare user+net ns │ │ │ │ │ │ 2. install xfrm SAs │ │ │ │ │ │ 3. splice target binary │────▶│ shared-layer binary │────▶│ executes patched binary │ │ through ESP path │ │ page cache patched │ │ payload runs with │ │ │ │ │ │ node-level privileges │ └──────────────────────────────┘ └────────────────────────┘ └──────────────────────────┘ ``` ## 已验证环境 ### Amazon EKS | 属性 | 值 | | ----------------- | ------------------------------------------ | | 平台 | Amazon Elastic Kubernetes Service (EKS) | | 节点内核 | `6.12.80-106.156.amzn2023.x86_64` | | 补丁状态 | 修复前内核,缺少 `f4c50a4034e6` | | `esp4` 模块 | 已加载 | | 用户命名空间 | 已启用 (`user.max_user_namespaces=15030`) | | SELinux | 宽容模式 | | Seccomp | 在测试的 Pod 上下文中为 Unconfined | | 目标 DaemonSet | `kube-proxy` | | 目标特权 | `privileged: true`, `hostNetwork: true` | | 代理模式 | iptables | | 标记路径 | `/root/res` | ### GKE 和 ACK — 已测试,在默认配置下不可利用 我在 GKE 和 ACK 集群上进行了测试。均以失败告终。 | 平台 | 结果 | 原因 | | ----------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------ | | 阿里云 ACK | **失败** | 默认节点镜像上的 `user.max_user_namespaces` 设置为 `0`,因此非特权用户无法使用 `CLONE_NEWUSER` unshare。 | | Google GKE | **失败** | `user.max_user_namespaces` 为 `15426`,但 kubelet 启用了 `--seccomp-default`。默认的 seccomp 策略禁用了 `unshare` 系统调用。 | Dirty Frag 原语**需要创建用户命名空间**(`CLONE_NEWUSER`)以便在新网络命名空间内获取 `CAP_NET_ADMIN`。ACK 和 GKE 均通过不同机制在节点级别阻止了此操作: - **ACK**: 内核级别限制(`user.max_user_namespaces=0`)完全阻止了非特权用户命名空间的创建。 - **GKE**: seccomp 默认配置文件(由 kubelet 的 `--seccomp-default` 标志启用)阻止了 `unshare` 系统调用,无论命名空间限制如何。 这是与 [Copy Fail (CVE-2026-31431)](https://github.com/Percivalll/Copy-Fail-CVE-2026-31431-Kubernetes-PoC) 的一个关键区别,后者**不**需要用户命名空间,并且可以成功利用所有三个平台。 ## kube-proxy 作为具体示例 提供的 EKS 变体在存在时会修补以下二进制文件: ``` /usr/sbin/xtables-legacy-multi /usr/sbin/xtables-nft-multi ``` 这些二进制文件由 `kube-proxy` 使用的 iptables 工具链调用。确切的触发时间取决于节点和服务协调活动。在验证的环境中,payload 由正常的 `kube-proxy` 协调触发。 **重要注意事项:** - kube-proxy 仅在配置为 **ipvs** 模式时调用 `ipset`。默认模式(`iptables`)不使用 `ipset`。 - 某些托管 Kubernetes 发行版将 kube-proxy 作为**非特权**容器运行,这限制了逃逸的影响。 - PoC 针对多个二进制文件(`xtables-legacy-multi`、`xtables-nft-multi`)以涵盖不同的代理模式,但它们是否会被调用取决于集群配置。 **如果您的集群中 kube-proxy 不是特权的,攻击原理依然成立** —— 您只需找到另一个与您可构建基础镜像共享镜像层的特权 DaemonSet 即可。 ## 仓库结构 ``` . ├── exploit/ │ └── dirtyfrag.c # xfrm/ESP page-cache writer ├── payload/ │ ├── payload-eks.c # nolibc payload that writes /root/res on the host │ └── nolibc/ # Linux nolibc headers ├── deploy/ │ └── poc-eks.yaml # unprivileged EKS Deployment manifest ├── scripts/ │ ├── setup-eks.sh # copy, build, and import image on an EKS node │ ├── run-poc.sh # deploy and check marker │ └── cleanup.sh # remove pod, marker, cached pages, and local image ├── Dockerfile.eks # EKS image based on eks-distro-minimal-base-iptables ├── Makefile # payload, exploit, Docker, and nerdctl build targets └── .github/workflows/ └── docker-publish.yml # GHCR publishing workflow ``` ## 构建与使用 ``` # 构建 payload + exploit 二进制文件 make build-eks CC=x86_64-linux-gnu-gcc # 构建 Docker 镜像 make docker-build-eks # 部署 (unprivileged pod) kubectl apply -f deploy/poc-eks.yaml # 检查日志 kubectl logs deployment/dirtyfrag-poc-eks # 验证 node 上的逃逸 ssh ec2-user@ "sudo cat /root/res" # 预期: [*] 成功 ``` GitHub Actions 工作流(`.github/workflows/docker-publish.yml`)在推送到 `main` 或创建标签时将镜像发布到 GHCR。请将 `deploy/poc-eks.yaml` 中的 `` 替换为拥有该 fork 的 GitHub 用户或组织。 ### 清理 ``` kubectl delete -f deploy/poc-eks.yaml --ignore-not-found ssh ec2-user@ "sudo rm -f /root/res" kubectl delete pod -n kube-system -l k8s-app=kube-proxy --force ``` ## 受影响版本 - **Linux 内核**:CVE-2026-43284 补丁(提交 `f4c50a4034e6`)之前的所有版本。 - **Kubernetes**:任何使用启用用户命名空间的未修补节点内核的版本。该漏洞存在于内核中,而不是 Kubernetes 本身。Kubernetes 仅提供了执行上下文(共享镜像层 + 特权 DaemonSet),将影响从本地页缓存损坏升级为完整的容器逃逸。 ## 缓解措施 - **修补内核。** 更新至包含 Dirty Frag 修复的内核,包括提交 `f4c50a4034e6` 或供应商反向移植版本。 - **禁用未使用的 ESP 模块。** 如果 worker 节点不需要 IPsec ESP,请阻止 `esp4` 和 `esp6`。 - **限制用户命名空间。** 将 `user.max_user_namespaces` 设置为 `0` 可防止此 PoC 在新网络命名空间中获取 `CAP_NET_ADMIN`(这已经是 ACK 上的默认设置)。 - **使用严格的 seccomp 配置文件。** RuntimeDefault 或自定义配置文件可以阻止关键的命名空间和网络系统调用(这已经是 GKE 上的默认设置)。 - **最小化特权 DaemonSet。** 除非严格需要,否则避免使用 `privileged: true` 和宽泛的宿主机访问。 - **减少与特权工作负载的层共享。** 为特权代理使用独立的基础镜像,并控制不受信任的工作负载可以运行的位置。 模块阻止示例: ``` printf 'install esp4 /bin/false\ninstall esp6 /bin/false\n' | sudo tee /etc/modprobe.d/dirtyfrag.conf sudo rmmod esp4 esp6 2>/dev/null || true ``` ## 致谢 - **Dirty Frag 研究和原始漏洞利用**:[V4bel/dirtyfrag](https://github.com/V4bel/dirtyfrag) ## 参考文献 - [Dirty Frag - V4bel/dirtyfrag](https://github.com/V4bel/dirtyfrag) - [LWN 报道](https://lwn.net/Articles/1071719/) - [CVE-2026-43284 xfrm/ESP 讨论](https://lwn.net/ml/all/afzgS2SCWNcZU3vU%40v4bel/) - [Copy Fail Kubernetes PoC](https://github.com/Percivalll/Copy-Fail-CVE-2026-31431-Kubernetes-PoC) ## 许可证 漏洞利用代码改编自 [V4bel/dirtyfrag](https://github.com/V4bel/dirtyfrag),采用 MIT 许可证。 Payload 代码派生自 [tgies/copy-fail-c](https://github.com/tgies/copy-fail-c),并在 **LGPL-2.1-or-later** 或 **MIT** 下双重许可。 nolibc 头文件来自 Linux 内核自测基础架构。
标签:Amazon EKS, AWS安全, CISA项目, containerd, CRI-O, CVE-2026-43284, DaemonSet, Dirty Frag, Go语言工具, K8s安全, kube-proxy, Linux内核, OverlayFS, PoC, Web报告查看器, 内核漏洞, 子域名突变, 安全渗透, 客户端加密, 容器运行时安全, 容器逃逸, 提权, 数据展示, 暴力破解, 未特权Pod, 概念验证, 红队, 节点级代码执行, 请求拦截, 镜像层共享, 页缓存损坏