
PoC: полностью непривилегированный побег из контейнера до выполнения кода на уровне узла в Kubernetes через повреждение page-cache CVE-2026-31431 + общие слои образов. Проверено на Alibaba Cloud ACK, Amazon EKS и Google GKE.
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) |
|---|---|---|
![]() | ![]() | ![]() |
Отказ от ответственности: Этот репозиторий опубликован только в образовательных и защитных целях. Используйте его исключительно в системах, которыми вы владеете или на тестирование которых имеете явное разрешение.
CVE-2026-31431 («Copy Fail») — уязвимость ядра Linux в пути Copy-on-Write (CoW) page-cache. Гонка splice через AF_ALG позволяет непривилегированному процессу повредить страницы page-cache файла, открытого только для чтения. Повреждение сохраняется в page-cache ядра и видно каждому процессу, который впоследствии читает или исполняет этот файл, — включая процессы в других контейнерах или на узле.
Полные сведения об исходной уязвимости см. на copy.fail.
Атака использует три свойства, которые часто сосуществуют в кластерах Kubernetes:
privileged: true, hostNetwork: true, широкими capabilities и т.д.), которые периодически выполняют бинарные файлы из своего образа.Когда эти условия совпадают, непривилегированный pod может повредить бинарный файл в общем слое образа, а привилегированный DaemonSet на том же узле неосознанно выполнит повреждённый бинарный файл со своими повышенными привилегиями — достигая полного выполнения кода на уровне узла.
Цель уязвимости НЕ ограничивается kube-proxy. Любой привилегированный DaemonSet (агенты мониторинга, CNI-плагины, сборщики логов, агенты безопасности и т.д.), чей образ контейнера разделяет слои с образом, контролируемым атакующим, является подходящей целью.
Цепочка атаки состоит из трёх этапов: повреждение page-cache, распространение между контейнерами и привилегированное выполнение.
Подсистема ядра AF_ALG (crypto) предоставляет интерфейс на основе сокетов для криптографических операций из пользовательского пространства. Эксплойт злоупотребляет состоянием гонки в том, как ядро обрабатывает splice() из файла в сокет AF_ALG:
authesncs(hmac(sha256),cbc(aes)).MSG_MORE, сообщая ядру, что ожидаются ещё данные.splice() передайте содержимое целевого файла из fd → pipe → сокет AF_ALG.Эксплойт повторяет это для каждого 4-байтового окна, пока все кэшированные страницы целевого бинарного файла не будут перезаписаны специальной полезной нагрузкой.
Права на запись в файл не требуются. Файл на диске остаётся неизменным — повреждён только page-cache в памяти.
Контейнерные рантаймы используют overlay-файловые системы. Когда два контейнера используют один и тот же слой образа, ядро обслуживает чтение файлов из одних и тех же страниц page-cache.
Атакующий собирает образ PoC FROM того же базового образа, что и целевой привилегированный DaemonSet. Поскольку оба контейнера используют один и тот же lower-dir в overlay, бинарные файлы в общем слое сопоставляются с идентичными страницами page-cache.
Когда непривилегированный PoC-контейнер повреждает page-cache бинарного файла, повреждение немедленно становится видимым привилегированному контейнеру на том же узле — без какой-либо связи между контейнерами.
Когда привилегированный DaemonSet в следующий раз выполнит любой повреждённый бинарный файл (в рамках своего обычного цикла работы), ядро загрузит повреждённые страницы page-cache. Полезная нагрузка атакующего выполняется с полными привилегиями DaemonSet, потенциально включая:
Полезная нагрузка в этом PoC (payload/payload.c) просто монтирует корневую файловую систему узла и записывает файл-маркер в /root/res как доказательство выполнения кода на уровне узла.
┌──────────────────────────┐ ┌──────────────────────────┐
│ 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 Container Service for Kubernetes (ACK) |
| Kubernetes | v1.35.2 |
| Ядро узла | 6.6.88-4.2.alnx4.x86_64 |
| kube-proxy | registry-cn-*.ack.aliyuncs.com/acs/kube-proxy:v1.35.2-aliyun.1 |
| Базовый образ | registry.k8s.io/kube-proxy:v1.35.2 (апстрим) |
| Корневое устройство | /dev/vda3 (ext4) |
