Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

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

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

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

工具目录

分类

查看所有分类
Loading categories
Copy-Fail-CVE-2026-31431-Kubernetes-PoC — PoC:通过 CVE-2026-31431 页缓存损坏 + 共享镜像层,实现完全非特权容器逃逸至 Kubernetes 节点级代码执行。已在阿里云 ACK、Amazon EKS 和 Google GKE 上验证。 | Kitploit
工具/GitHubGitHub/percivalll/copy-fail-cve-2026-31431-kubernetes-poc
权限提升漏洞分析漏洞利用云安全论文与研究学习与教育容器逃逸
GitHubpercivalll/copy-fail-cve-2026-31431-kubernetes-poc

Copy-Fail-CVE-2026-31431-Kubernetes-PoC

最受欢迎

查看全部 →

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

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

PoC:通过 CVE-2026-31431 页缓存损坏 + 共享镜像层,实现完全非特权容器逃逸至 Kubernetes 节点级代码执行。已在阿里云 ACK、Amazon EKS 和 Google GKE 上验证。

查看仓库
184283个月前Kitploit 审核通过

Copy Fail (CVE-2026-31431) — Kubernetes 容器逃逸 PoC

一个概念验证(PoC),演示了完全无特权的容器如何通过共享容器镜像层利用 CVE-2026-31431 Linux 内核页缓存损坏漏洞,在 Kubernetes 上实现节点级代码执行。

核心攻击原语是:任何与攻击者控制的容器共享镜像层的特权 DaemonSet 都可被武器化,用于容器逃逸。本 PoC 以 kube-proxy 作为具体示例,但该技术可推广到集群中的任何特权工作负载。

已在阿里云 ACK、Amazon EKS 和 Google GKE 上验证——一个无特权 Pod 通过特权 kube-proxy DaemonSet 向主机文件系统写入 [*] success:

阿里云 ACK (kernel 6.6.88)Amazon EKS (kernel 6.12.79)Google GKE (kernel 6.12.68)
ACKEKSGKE

免责声明: 本仓库仅用于教育和防御目的。请仅在您拥有或已获明确授权测试的系统上使用。

背景

CVE-2026-31431(“Copy Fail”)是 Linux 内核中页缓存写时复制(Copy-on-Write, CoW)路径上的一个漏洞。通过 AF_ALG splice 竞态,无特权进程可以破坏只读文件的页缓存页。这种破坏会持续存在于内核页缓存中,并且对之后读取或执行该文件的每个进程都可见——包括其他容器或主机上的进程。

关于原始漏洞的完整细节,请参阅 copy.fail。

攻击原理

该攻击利用了 Kubernetes 集群中通常同时存在的三个特性:

  1. 内核页缓存损坏(CVE-2026-31431) —— 无特权进程可以覆盖其能够以只读方式打开的任何文件的内存缓存页。
  2. 镜像层共享 —— 容器运行时(containerd、CRI-O)使用 overlay 文件系统,不同容器中相同的镜像层映射到相同的页缓存页。
  3. 特权 DaemonSet —— 许多集群运行具有提升权限的 DaemonSet(privileged: true、hostNetwork: true、广泛的 capabilities 等),这些 DaemonSet 会定期执行其镜像中的二进制文件。

当这些条件同时具备时,无特权 Pod 可以破坏共享镜像层中的二进制文件,而同一节点上的特权 DaemonSet 会在不知情的情况下以其提升的权限执行被破坏的二进制文件——从而实现完整的节点级代码执行。

漏洞目标不仅限于 kube-proxy。 任何容器镜像与攻击者控制的镜像共享层的特权 DaemonSet(监控代理、CNI 插件、日志采集器、安全代理等)都是可行的攻击目标。

工作原理

攻击链包含三个阶段:页缓存损坏、跨容器传播和特权执行。

1. 通过 AF_ALG splice 竞态破坏页缓存

内核的 AF_ALG(加密)子系统为用户空间加密操作提供基于套接字的接口。该漏洞利用的是内核在处理从文件到 AF_ALG 套接字的 splice() 时存在的竞态条件:

  1. 以只读方式打开目标二进制文件。
  2. 创建绑定到 authencesn(hmac(sha256),cbc(aes)) 的 AF_ALG AEAD 套接字。
  3. 使用 MSG_MORE 通过 AF_ALG 套接字发送一小块载荷数据,告知内核还有更多数据。
  4. 通过 splice() 将目标文件内容从 fd → pipe → AF_ALG 套接字传输。
  5. 由于 CoW 缺陷,内核将攻击者的载荷字节写入目标文件的页缓存页,而不是正确隔离它们。

漏洞利用程序对每个 4 字节窗口重复此过程,直到目标二进制文件的整个缓存页都被自定义载荷覆盖。

无需对文件具有写权限。磁盘上的文件保持不变——只有内存中的页缓存被破坏。

2. 通过镜像层共享进行跨容器传播

容器运行时使用 overlay 文件系统。当两个容器共享同一镜像层时,内核会从相同的页缓存页为它们的文件读取提供服务。

攻击者构建其 PoC 镜像时,FROM 与目标特权 DaemonSet 相同的基础镜像。由于两个容器共享相同的 overlay lower-dir,共享层中的二进制文件将映射到相同的页缓存页。

当无特权 PoC 容器破坏二进制文件的页缓存时,同一节点上的特权容器立即可见该破坏——并且无需任何跨容器通信。

3. 目标 DaemonSet 的特权执行

当特权 DaemonSet 下次执行任何被破坏的二进制文件时(在其正常运行周期内),内核会加载被破坏的页缓存页。攻击者的载荷将以 DaemonSet 的完整权限运行——可能包括:

  • 节点上的完整 root 权限
  • 所有 capabilities
  • 对主机命名空间(网络、PID、挂载)的访问权限

本 PoC 中的载荷(payload/payload.c)仅挂载主机根文件系统,并向 /root/res 写入标记文件,作为节点级代码执行的证明。

攻击流程图

root@kitploit:~
┌──────────────────────────┐     ┌──────────────────────────┐
│   PoC Container          │     │   Privileged DaemonSet   │
│   (unprivileged)         │     │   (e.g. kube-proxy,      │
│                          │     │    monitoring agent, etc.)│
│  1. Open target binary   │     │                          │
│     (read-only)          │     │                          │
│                          │     │                          │
│  2. AF_ALG splice race   │     │                          │
│     corrupts page cache  │     │                          │
│          │               │     │                          │
└──────────┼───────────────┘     └──────────────────────────┘
           │                                  │
           ▼                                  │
  ┌─────────────────────┐                     │
  │  Kernel Page Cache   │                     │
  │                      │◄────────────────────┘
  │  Shared-layer binary │     3. DaemonSet executes the
  │  (CORRUPTED)         │        corrupted binary
  │  contains attacker's │        → loads corrupted pages
  │  payload bytes       │        → payload runs with
  └─────────────────────┘           DaemonSet's privileges

已验证的云环境

该 PoC 已在以下托管 Kubernetes 平台上成功验证:

阿里云 ACK

ACK PoC 结果

Amazon EKS

EKS PoC 结果

Google GKE

GKE PoC 结果

在以上三种情况中,无特权 PoC Pod 均成功地将 [*] success 标记文件写入主机文件系统——证明通过特权 kube-proxy DaemonSet 实现了节点级代码执行。

有关完整演练(镜像层分析、构建步骤、部署):

  • EKS:docs/eks-poc.md
  • GKE:docs/gke-poc.md

以 kube-proxy 为例

本 PoC 以 kube-proxy 为目标,因为它是 Kubernetes 集群中最常见的特权 DaemonSet 之一。提供了三种变体:

  • 默认(ACK / 上游):构建自 FROM registry.k8s.io/kube-proxy:v1.35.2(参见 Dockerfile)
  • EKS:构建自 FROM public.ecr.aws/eks-distro-build-tooling/eks-distro-minimal-base-iptables:2026-03-11-1773190710.2023(参见 Dockerfile.eks)
  • GKE:构建自 FROM us-central1-artifactregistry.gcr.io/gke-release/gke-release/kube-proxy:v1.35.3-gke.1234000(参见 Dockerfile.gke)

所有变体都会破坏诸如 /usr/sbin/ipset、/usr/sbin/nft、/usr/sbin/xtables-legacy-multi 和 /usr/sbin/xtables-nft-multi 之类的二进制文件。

重要注意事项:

  • 只有当 kube-proxy 以 ipvs 模式配置时,它才会调用 ipset。默认模式(iptables)不使用 ipset。有关 ipvs 弃用计划,请参阅 kubernetes/enhancements#5495。
  • 某些托管 Kubernetes 发行版(例如某些云提供商)会将 kube-proxy 作为非特权容器运行,这会限制逃逸的影响。
  • 本 PoC 针对多个二进制文件(ipset、nft、xtables-legacy-multi、xtables-nft-multi)以覆盖不同的代理模式,但这些二进制文件是否被调用取决于集群配置。

如果你的集群中 kube-proxy 不是特权容器,攻击原理仍然成立 —— 你只需要识别一个不同的特权 DaemonSet,它共享镜像层且基础镜像可供你基于其构建。

推广到其他目标

要将此 PoC 适配到另一个特权 DaemonSet:

  1. 识别集群上运行的特权 DaemonSet(监控代理、CNI 插件、日志采集器等)。
  2. 使用该 DaemonSet 使用的基础镜像来构建你的 PoC 镜像(FROM)。
  3. 识别共享层中该 DaemonSet 在正常运行期间会执行的二进制文件。
  4. 利用该漏洞破坏这些二进制文件的页缓存。

仓库结构

root@kitploit:~
.
├── cmd/copyfail/main.go          # Entry point; embeds compiled payload
├── internal/
│   ├── exploit/
│   │   ├── exploit.go            # Core exploit: AF_ALG splice race loop
│   │   └── patch.go              # Splits payload into 4-byte patch windows
│   └── alg/
│       └── alg.go                # AF_ALG AEAD socket abstraction
├── payload/
│   ├── payload.c                 # ACK/upstream payload (mount /dev/vda3 ext4)
│   ├── payload-eks.c             # EKS payload (NVMe/Xen device auto-detection)
│   ├── payload-gke.c             # GKE payload (COS/Ubuntu device auto-detection)
│   └── nolibc/                   # Kernel's tiny libc for static, no-dependency payloads
├── deploy/
│   ├── poc.yaml                  # Kubernetes Deployment manifest (ACK/upstream)
│   ├── poc-eks.yaml              # EKS Deployment manifest
│   └── poc-gke.yaml              # GKE Deployment manifest
├── Dockerfile                    # ACK/upstream: FROM registry.k8s.io/kube-proxy
├── Dockerfile.eks                # EKS: FROM eks-distro-minimal-base-iptables
├── Dockerfile.gke                # GKE: FROM gke-release/kube-proxy
├── Makefile                      # Build orchestration (includes *-eks and *-gke targets)
└── docs/
    ├── eks-poc.md                # EKS PoC full walkthrough
    ├── gke-poc.md                # GKE PoC full walkthrough
    ├── ack-poc-res.png           # ACK validation screenshot
    ├── eks-poc-res.png           # EKS validation screenshot
    └── gke-poc-res.png           # GKE validation screenshot

前提条件

  • Go 1.25+
  • 用于 nolibc 载荷的交叉编译器(默认:x86_64-linux-gnu-gcc)
  • Docker / Buildx
  • 一个 Kubernetes 集群,其中包含一个与 PoC 镜像共享镜像层的特权 DaemonSet(默认示例以 kube-proxy 为目标)
  • 目标 DaemonSet 的 imagePullPolicy: IfNotPresent(Kubernetes 默认值)
  • 尚未应用 CVE-2026-31431 修复的 Linux 内核

构建

ACK / 上游 Kubernetes

root@kitploit:~
# Build payload + Go binary
make build

# Build Docker image
make docker-build

# Build and push to GHCR
make docker-push IMAGE=ghcr.io/<you>/copy-fail-poc TAG=latest

Amazon EKS

root@kitploit:~
# Build EKS payload + Go binary + Docker image
make docker-build-eks

# Build and push to GHCR
make docker-push-eks IMAGE=ghcr.io/<you>/copy-fail-poc

对于 arm64 目标(Graviton):

root@kitploit:~
make build-eks CC=aarch64-linux-gnu-gcc GOARCH=arm64

Google GKE

root@kitploit:~
# Build GKE payload + Go binary + Docker image
make docker-build-gke

# Build and push to GHCR
make docker-push-gke IMAGE=ghcr.io/<you>/copy-fail-poc

对于 arm64 节点:

root@kitploit:~
make docker-build-gke CC=aarch64-linux-gnu-gcc GOARCH=arm64 PLATFORM=linux/arm64

使用方法

部署 PoC

root@kitploit:~
# ACK / upstream Kubernetes
kubectl apply -f deploy/poc.yaml

# Amazon EKS
kubectl apply -f deploy/poc-eks.yaml

# Google GKE
kubectl apply -f deploy/poc-gke.yaml

该 Deployment 会创建一个无特权 Pod。它会:

  1. 运行 /bin/copyfail 来破坏共享镜像层中目标二进制文件的页缓存。
  2. 无限期休眠,使 Pod 保持运行以供观察。

验证逃逸

当目标特权 DaemonSet 下次执行被破坏的二进制文件后(对于 kube-proxy,由于其协调循环,这通常会在数秒内发生),请检查节点:

root@kitploit:~
# SSH into the node, or use a privileged debug pod

# ACK / EKS (writable root filesystem)
cat /root/res
# Expected output: [*] success

# GKE COS nodes (read-only root, writable stateful partition)
cat /mnt/stateful_partition/copyfail-res
# Expected output: [*] success

主机文件系统上存在标记文件,证明攻击者提供的代码在特权 DaemonSet 的容器上下文内以节点级权限执行。

清理

root@kitploit:~
kubectl delete -f deploy/poc.yaml      # or poc-eks.yaml / poc-gke.yaml

# On the affected node(s), remove the marker and restart the target DaemonSet:
rm -f /root/res                                     # ACK / EKS
rm -f /copyfail-res /mnt/stateful_partition/copyfail-res  # GKE COS nodes
# For kube-proxy: delete the pod to force image layer re-read
kubectl delete pod -n kube-system -l k8s-app=kube-proxy --field-selector spec.nodeName=<node>

自定义载荷

默认载荷(payload/payload.c)是一个仅用于验证的程序,它会写入一个标记文件。要构建自定义载荷:

  1. 编辑 payload/payload.c。该程序基于 nolibc(内核的最小 C 库)构建,以生成静态、无依赖的二进制文件。
  2. 运行 make payload 进行交叉编译。
  3. 编译后的载荷通过 //go:embed 嵌入到 Go 二进制文件中。

受影响版本

  • Linux 内核:CVE-2026-31431 补丁之前的所有版本。
  • Kubernetes:任何使用未修补节点内核的版本。该漏洞存在于内核中,而非 Kubernetes 本身。Kubernetes 仅提供了执行上下文(共享镜像层 + 特权 DaemonSet),使影响从本地页缓存损坏升级为完整的容器逃逸。

缓解措施

  • 修补内核。 这是最终的修复方法。
  • 启用镜像层隔离。 某些运行时支持每容器文件系统快照,可防止页缓存共享。
  • 最小化特权 DaemonSet。 减少以提升权限运行的工作负载数量;遵循最小权限原则。
  • 从不需要严格 privileged: true 的 DaemonSet 中删除不必要的 capabilities。
  • 限制 Pod 调度,防止不受信任的工作负载调度到运行具有共享基础镜像的特权 DaemonSet 的节点上。
  • 为特权工作负载使用不同的基础镜像,以减少与不受信任容器共享镜像层的可能性。

缓解措施示例

  • vArmor 内置缓解规则:copy-fail-mitigation 通过阻止容器创建 AF_ALG 套接字来阻断该利用向量。该规则可通过 AppArmor 和 BPF 执行器使用。
  • Kubernetes eBPF 缓解方案:iwanhae/copyfail-ebpf-k8s 为 CVE-2026-31431 提供了基于 eBPF 的 Kubernetes 缓解示例。

致谢

  • CVE-2026-31431 的发现与披露:Theori / Xint
  • 跨平台 C 载荷:Tony Gies(LGPL-2.1-or-later OR MIT)
  • nolibc:Linux 内核 selftests(tools/include/nolibc/)

许可证

本仓库中的 Go 漏洞利用代码按原样提供,仅供研究目的。

载荷(payload/payload.c)衍生自 copy-fail-c,并根据 LGPL-2.1-or-later 或 MIT 双重许可。请参阅 LICENSE-LGPL 和 LICENSE-MIT。

下载工具
属性值
平台阿里云容器服务 Kubernetes 版(ACK)
Kubernetesv1.35.2
节点内核6.6.88-4.2.alnx4.x86_64
kube-proxyregistry-cn-*.ack.aliyuncs.com/acs/kube-proxy:v1.35.2-aliyun.1
基础镜像registry.k8s.io/kube-proxy:v1.35.2(上游)
根设备/dev/vda3 (ext4)
属性值
平台Amazon Elastic Kubernetes Service(EKS)
Kubernetesv1.35.4
节点内核6.12.79-101.147.amzn2023.x86_64
kube-proxy***.dkr.ecr.***.amazonaws.com.cn/eks/kube-proxy:v1.35.3-eksbuild.2
基础镜像public.ecr.aws/eks-distro-build-tooling/eks-distro-minimal-base-iptables:2026-03-11-1773190710.2023
根设备/dev/nvme0n1p1 (xfs)
属性值
平台Google Kubernetes Engine(GKE)
Kubernetesv1.35.3-gke.1234000
节点操作系统Container-Optimized OS (COS) 125,BUILD_ID 19216.220.72
节点内核6.12.68+ x86_64
kube-proxyus-central1-artifactregistry.gcr.io/gke-release/gke-release/kube-proxy:v1.35.3-gke.1234000
基础镜像与 kube-proxy 相同(GKE 供应商管理的 Artifact Registry 镜像)
根设备/dev/dm-0(ext2,只读);/dev/sda1(ext4,可写的有状态分区)
标记路径/mnt/stateful_partition/copyfail-res