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`:

## 背景
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, 概念验证, 红队, 节点级代码执行, 请求拦截, 镜像层共享, 页缓存损坏