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

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

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

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

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

Категории

Все категории
Loading categories
Copy-Fail-CVE-2026-31431-Kubernetes-PoC — Доказательство концепции, демонстрирующее побег из контейнера в Kubernetes через повреждение page-cache ядра CVE-2026-31431, позволяющее достичь выполнения кода на уровне узла из непривилегированного контейнера. | Kitploit
Инструменты/GitHubGitHub/starscow/copy-fail-cve-2026-31431-kubernetes-poc
Повышение привилегийАнализ уязвимостейЭксплуатацияОбучение и ОбразованиеПобег из Контейнера
GitHubstarscow/copy-fail-cve-2026-31431-kubernetes-poc

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

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

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться
Репозиторий
4 месяцев назадЕщё не проверено

Copy Fail (CVE-2026-31431) — Kubernetes Container Escape PoC

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

Дисклеймер: Этот репозиторий опубликован исключительно в образовательных и защитных целях. Используйте его только на системах, которыми вы владеете или на тестирование которых у вас есть явное разрешение.

Предыстория

CVE-2026-31431 («Copy Fail») — это уязвимость ядра Linux в пути Copy-on-Write (CoW) page-cache. Гонка AF_ALG splice позволяет непривилегированному процессу повредить страницы page-cache доступного только для чтения файла. Повреждение сохраняется в page-cache ядра и видно каждому процессу, который впоследствии читает или исполняет этот файл — включая процессы в других контейнерах или на хосте.

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

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

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

1. Повреждение Page-Cache через гонку AF_ALG Splice

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

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

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

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

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

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

Этот образ PoC собран FROM registry.k8s.io/kube-proxy:v1.35.2. DaemonSet kube-proxy на каждом узле Kubernetes использует точно такой же базовый слой. В результате /usr/sbin/ipset в обоих контейнерах сопоставляется с идентичным набором страниц page-cache.

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

3. Привилегированное выполнение kube-proxy

kube-proxy работает как привилегированный DaemonSet с hostNetwork: true. Он периодически вызывает /usr/sbin/ipset для управления правилами iptables/ipset. При следующем выполнении ipset ядро загружает повреждённые страницы page-cache, выполняя полезную нагрузку атакующего с полными привилегиями kube-proxy:

  • Полный root на узле
  • Все capabilities
  • Доступ к пространствам имён хоста

Полезная нагрузка в этом PoC (payload/payload.c) просто монтирует корневую файловую систему хоста и записывает файл-маркер в /root/res как доказательство выполнения кода на уровне узла.

Схема потока атаки

root@kitploit:~
┌──────────────────────────┐     ┌──────────────────────────┐
│   PoC Container          │     │   kube-proxy Container   │
│   (unprivileged)         │     │   (privileged)           │
│                          │     │                          │
│  1. Open /usr/sbin/ipset │     │                          │
│     (read-only)          │     │                          │
│                          │     │                          │
│  2. AF_ALG splice race   │     │                          │
│     corrupts page cache  │     │                          │
│          │               │     │                          │
└──────────┼───────────────┘     └──────────────────────────┘
           │                                  │
           ▼                                  │
  ┌─────────────────────┐                     │
  │  Kernel Page Cache   │                     │
  │  /usr/sbin/ipset     │◄────────────────────┘
  │  (CORRUPTED)         │     3. kube-proxy executes ipset
  │  contains attacker's │        → loads corrupted pages
  │  payload bytes       │        → payload runs as root
  └─────────────────────┘           on the host

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

root@kitploit:~
.
├── cmd/copyfail/main.go          # Точка входа; встраивает скомпилированную полезную нагрузку
├── internal/
│   ├── exploit/
│   │   ├── exploit.go            # Основной эксплойт: цикл гонки AF_ALG splice
│   │   └── patch.go              # Разбивает полезную нагрузку на 4-байтовые окна патчей
│   └── alg/
│       └── alg.go                # Абстракция сокета AF_ALG AEAD
├── payload/
│   ├── payload.c                 # Валидационная полезная нагрузка (монтирование ФС хоста, запись маркера)
│   └── nolibc/                   # Минимальная libc ядра для статических полезных нагрузок без зависимостей
├── deploy/
│   └── poc.yaml                  # Манифест Deployment Kubernetes
├── Dockerfile                    # Собран FROM kube-proxy для совместного использования слоёв образа
├── Makefile                      # Оркестрация сборки
└── docs/                         # Доказательства валидации из ACK (Alibaba Cloud)

Предварительные требования

  • Go 1.25+
  • Кросс-компилятор для полезной нагрузки nolibc (по умолчанию: x86_64-linux-gnu-gcc)
  • Docker / Buildx
  • Кластер Kubernetes, работающий с kube-proxy как DaemonSet с imagePullPolicy: IfNotPresent (по умолчанию)
  • Ядро Linux до исправления CVE-2026-31431

Сборка

root@kitploit:~
# Сборка полезной нагрузки + Go-бинарника
make build

# Сборка Docker-образа
make docker-build

# Сборка и публикация в GHCR
make docker-push IMAGE=ghcr.io/<you>/copy-fail-poc TAG=latest

Для целей arm64:

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

Использование

Развёртывание PoC

root@kitploit:~
kubectl apply -f deploy/poc.yaml

Deployment создаёт один непривилегированный под. Он:

  1. Запускает /bin/copyfail -target /usr/sbin/ipset для повреждения page-cache.
  2. Бесконечно спит, чтобы под оставался запущенным для наблюдения.

Проверка эскалации

После того как kube-proxy в следующий раз выполнит ipset (обычно это происходит в течение секунд из-за его цикла согласования или при следующем перезапуске), проверьте узел:

root@kitploit:~
# SSH на узел или используйте привилегированный debug-под
cat /root/res
# Ожидаемый вывод: [*] success

Наличие /root/res в файловой системе хоста доказывает, что код, предоставленный атакующим, выполнился с привилегиями уровня узла — записанный из контекста привилегированного контейнера kube-proxy.

Очистка

root@kitploit:~
kubectl delete -f deploy/poc.yaml

# На затронутых узлах удалите маркер и перезапустите kube-proxy:
rm -f /root/res
systemctl restart kubelet   # или удалите под kube-proxy, чтобы принудительно перезагрузить образ

Почему kube-proxy + ipset?

kube-proxy — идеальная цель, потому что он:

  1. Присутствует на каждом узле — работает как DaemonSet.
  2. Высокопривилегированный — privileged: true, hostNetwork: true.
  3. Содержит ipset в своём образе — ipset — это setuid-бинарник, используемый для управления iptables.
  4. Использует imagePullPolicy: IfNotPresent — как только образ атакующего загружен и использует тот же базовый слой, страницы нижнего каталога overlay являются общими.

Любой привилегированный DaemonSet, чей образ содержит предсказуемый бинарник, может быть атакован аналогичным образом.

Настройка полезной нагрузки

Полезная нагрузка по умолчанию (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.
  • Используйте read-only корневые файловые системы для kube-proxy (не полностью смягчает, но ограничивает возможности полезной нагрузки).
  • Ограничьте планирование подов, чтобы недоверенные рабочие нагрузки не попадали на узлы, работающие с привилегированными DaemonSet и общими базовыми образами.

Авторы

  • Обнаружение и раскрытие 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.

Скачать инструмент