Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
Инструменты/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: полностью непривилегированный побег из контейнера до выполнения кода на уровне узла в Kubernetes через повреждение page-cache CVE-2026-31431 + общие слои образов. Проверено на Alibaba Cloud ACK, Amazon EKS и Google GKE.

Репозиторий
18428114 месяцев назадПроверено Kitploit

Copy Fail (CVE-2026-31431) — PoC побега из контейнера Kubernetes

Proof-of-concept, демонстрирующий, как полностью непривилегированный контейнер может добиться выполнения кода на уровне узла в Kubernetes, эксплуатируя ошибку повреждения page-cache ядра Linux CVE-2026-31431 через общие слои образов контейнеров.

Основной примитив атаки: любой привилегированный DaemonSet, разделяющий слои образа с контейнером, контролируемым атакующим, может быть использован для побега из контейнера. В этом PoC в качестве конкретного примера используется kube-proxy, но метод применим к любой привилегированной рабочей нагрузке в кластере.

Проверено на Alibaba Cloud ACK, Amazon EKS и Google GKE — непривилегированный pod записывает [*] success в файловую систему узла через привилегированный DaemonSet kube-proxy:

Alibaba Cloud 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) page-cache. Гонка splice через AF_ALG позволяет непривилегированному процессу повредить страницы page-cache файла, открытого только для чтения. Повреждение сохраняется в page-cache ядра и видно каждому процессу, который впоследствии читает или исполняет этот файл, — включая процессы в других контейнерах или на узле.

Полные сведения об исходной уязвимости см. на copy.fail.

Принцип атаки

Атака использует три свойства, которые часто сосуществуют в кластерах Kubernetes:

  1. Повреждение page-cache ядра (CVE-2026-31431) — непривилегированный процесс может перезаписать кэшированные в памяти страницы любого файла, который он может открыть только на чтение.
  2. Совместное использование слоёв образов — контейнерные рантаймы (containerd, CRI-O) используют overlay-файловые системы, где одинаковые слои образов сопоставляются с одними и теми же страницами page-cache в разных контейнерах.
  3. Привилегированные DaemonSet — во многих кластерах работают DaemonSet с повышенными привилегиями (privileged: true, hostNetwork: true, широкими capabilities и т.д.), которые периодически выполняют бинарные файлы из своего образа.

Когда эти условия совпадают, непривилегированный pod может повредить бинарный файл в общем слое образа, а привилегированный DaemonSet на том же узле неосознанно выполнит повреждённый бинарный файл со своими повышенными привилегиями — достигая полного выполнения кода на уровне узла.

Цель уязвимости НЕ ограничивается kube-proxy. Любой привилегированный DaemonSet (агенты мониторинга, CNI-плагины, сборщики логов, агенты безопасности и т.д.), чей образ контейнера разделяет слои с образом, контролируемым атакующим, является подходящей целью.

Как это работает

Цепочка атаки состоит из трёх этапов: повреждение page-cache, распространение между контейнерами и привилегированное выполнение.

1. Повреждение page-cache через гонку splice в AF_ALG

Подсистема ядра AF_ALG (crypto) предоставляет интерфейс на основе сокетов для криптографических операций из пользовательского пространства. Эксплойт злоупотребляет состоянием гонки в том, как ядро обрабатывает splice() из файла в сокет AF_ALG:

  1. Откройте целевой бинарный файл только на чтение.
  2. Создайте AEAD-сокет AF_ALG, привязанный к authesncs(hmac(sha256),cbc(aes)).
  3. Отправьте небольшой фрагмент полезной нагрузки через сокет AF_ALG с флагом MSG_MORE, сообщая ядру, что ожидаются ещё данные.
  4. С помощью splice() передайте содержимое целевого файла из fd → pipe → сокет AF_ALG.
  5. Из-за ошибки CoW ядро записывает байты полезной нагрузки атакующего в страницы page-cache целевого файла вместо их корректной изоляции.

Эксплойт повторяет это для каждого 4-байтового окна, пока все кэшированные страницы целевого бинарного файла не будут перезаписаны специальной полезной нагрузкой.

Права на запись в файл не требуются. Файл на диске остаётся неизменным — повреждён только page-cache в памяти.

2. Распространение между контейнерами через совместное использование слоёв образов

Контейнерные рантаймы используют overlay-файловые системы. Когда два контейнера используют один и тот же слой образа, ядро обслуживает чтение файлов из одних и тех же страниц page-cache.

Атакующий собирает образ PoC FROM того же базового образа, что и целевой привилегированный DaemonSet. Поскольку оба контейнера используют один и тот же lower-dir в overlay, бинарные файлы в общем слое сопоставляются с идентичными страницами page-cache.

Когда непривилегированный PoC-контейнер повреждает page-cache бинарного файла, повреждение немедленно становится видимым привилегированному контейнеру на том же узле — без какой-либо связи между контейнерами.

3. Привилегированное выполнение целевым DaemonSet

Когда привилегированный DaemonSet в следующий раз выполнит любой повреждённый бинарный файл (в рамках своего обычного цикла работы), ядро загрузит повреждённые страницы page-cache. Полезная нагрузка атакующего выполняется с полными привилегиями DaemonSet, потенциально включая:

  • Полный root на узле
  • Все capabilities
  • Доступ к namespace узла (network, PID, mount)

Полезная нагрузка в этом 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:

Alibaba Cloud ACK

Результат PoC на ACK

Amazon EKS

Результат PoC на EKS

Google GKE

Результат PoC на GKE

Во всех трёх случаях непривилегированный PoC-pod успешно записал файл-маркер [*] success в файловую систему узла, что доказывает выполнение кода на уровне узла через привилегированный DaemonSet kube-proxy.

Полные руководства (анализ слоёв образа, шаги сборки, развёртывание):

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

kube-proxy как конкретный пример

В этом PoC в качестве цели используется kube-proxy, поскольку это один из самых распространённых привилегированных DaemonSet в кластерах Kubernetes. Предоставлены три варианта:

  • По умолчанию (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 вызывает ipset только при настройке в режиме ipvs. Режим по умолчанию (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. Соберите образ PoC FROM того же базового образа, который использует этот DaemonSet.
  3. Определите бинарные файлы в общем слое, которые DaemonSet будет выполнять во время своей обычной работы.
  4. Повредите page-cache этих бинарных файлов с помощью эксплойта.

Структура репозитория

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 с привилегированным DaemonSet, который разделяет слои образа с PoC-образом (пример по умолчанию нацелен на kube-proxy)
  • imagePullPolicy: IfNotPresent у целевого DaemonSet (значение по умолчанию в Kubernetes)
  • Ядро Linux до исправления CVE-2026-31431

Сборка

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, чтобы повредить page-cache целевых бинарных файлов в общем слое образа.
  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-бинарный файл через //go:embed.

Затронутые версии

  • Ядро Linux: все версии до патча CVE-2026-31431.
  • Kubernetes: любая версия, использующая неисправленное ядро узла. Уязвимость находится в ядре, а не в самом Kubernetes. Kubernetes лишь предоставляет контекст выполнения (общие слои образов + привилегированные DaemonSet), который повышает воздействие с локального повреждения page-cache до полного побега из контейнера.

Меры по смягчению

  • Обновите ядро. Это окончательное исправление.
  • Включите изоляцию слоёв образов. Некоторые рантаймы поддерживают снапшоты файловой системы для каждого контейнера, которые предотвращают совместное использование page-cache.
  • Минимизируйте привилегированные DaemonSet. Сократите количество рабочих нагрузок с повышенными привилегиями; используйте принцип наименьших привилегий.
  • Удалите ненужные capabilities у DaemonSet, которым не требуется строго privileged: true.
  • Ограничьте планирование pod, чтобы не допускать попадания недоверенных рабочих нагрузок на узлы, где работают привилегированные DaemonSet с общими базовыми образами.
  • Используйте отдельные базовые образы для привилегированных рабочих нагрузок, чтобы снизить вероятность совместного использования слоёв с недоверенными контейнерами.

Примеры мер по смягчению

  • Встроенное правило смягчения vArmor: copy-fail-mitigation блокирует вектор эксплойта, запрещая контейнерам создавать сокеты AF_ALG. Правило доступно через механизмы AppArmor и BPF.
  • eBPF-смягчение для Kubernetes: iwanhae/copyfail-ebpf-k8s предоставляет пример смягчения на основе eBPF для Kubernetes для CVE-2026-31431.

Благодарности

  • Обнаружение и раскрытие CVE-2026-31431: Theori / Xint
  • Кроссплатформенная C-полезная нагрузка: Tony Gies (LGPL-2.1-or-later OR MIT)
  • nolibc: selftests ядра Linux (tools/include/nolibc/)

Лицензия

Go-код эксплойта в этом репозитории предоставляется как есть, в исследовательских целях.

Полезная нагрузка (payload/payload.c) является производной от copy-fail-c и распространяется по двойной лицензии LGPL-2.1-or-later OR MIT. См. LICENSE-LGPL и LICENSE-MIT.

Скачать инструмент
СвойствоЗначение
ПлатформаAlibaba Cloud Container Service for 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 (образ Artifact Registry, управляемый провайдером GKE)
Корневое устройство/dev/dm-0 (ext2, только чтение); /dev/sda1 (ext4, монтируемый stateful-раздел)
Путь маркера/mnt/stateful_partition/copyfail-res