
Всесторонний анализ CVE-2026-31431, LPE-уязвимости в ядре Linux, включая методологию эксплуатации, скрипты обнаружения, YARA-правила, конфигурации auditd и Falco, а также рекомендации по устранению.
algif_aeadCISA KEV | CVSS 7.8 HIGH | Затрагивает ядра Linux 4.14 – начало 2026 (~9 лет)
CVE-2026-31431, получивший прозвище «Copy Fail», — это уязвимость локального повышения привилегий (LPE) высокой степени серьёзности в криптографической подсистеме ядра Linux. Непривилегированный локальный пользователь может повысить привилегии до root за секунды на любой системе без установленного патча.
| Атрибут | Значение |
|---|---|
| CVE | CVE-2026-31431 |
| Прозвище | Copy Fail |
| CVSS v3.1 | 7.8 HIGH |
| Вектор атаки | Локальный |
| Требуемые привилегии | Низкие |
| Взаимодействие с пользователем | Отсутствует |
| Компонент | crypto/algif_aead.c — шаблон authencesn |
| Введено | 2017 (коммит 72548b093ee3) |
| Раскрыто | 2026 |
| Лет без исправления | ~9 лет |
| CISA KEV | Да |
| Публичный PoC | Да (автономный Python-скрипт на 732 байта) |
detection/check_vulnerable.sh до и после устранения уязвимости.CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
| Метрика | Значение | Обоснование |
|--------|-------|-----------|
| Вектор атаки | **Локальный** | Требуется доступ к оболочке (SSH, container exec, физический) |
| Сложность атаки | **Низкая** | Надёжная, полностью автоматизированная — не требуется состояние гонки |
| Требуемые привилегии | **Низкие** | Любая непривилегированная учётная запись пользователя |
| Взаимодействие с пользователем | **Нет** | Взаимодействие с жертвой не требуется |
| Конфиденциальность | **Высокая** | Полная компрометация системы |
| Целостность | **Высокая** | Полная компрометация системы |
| Доступность | **Высокая** | Полная компрометация системы |
### Ландшафт угроз
| Фактор | Оценка |
|--------|-----------|
| Доступность PoC | Публичный, боевой, автономный Python-скрипт на 732 байта |
| Надёжность эксплойта | Высокая — работает на протестированных дистрибутивах без модификаций |
| Сложность обнаружения | Высокая — нет записи на диск, нет грязных страниц |
| Требуемый уровень навыков атакующего | Низкий — скрипт-кидди с публичным PoC |
| CISA KEV | Добавлен в 2026 году — активно отслеживается |
| Microsoft Defender | Помечен как находящийся под активным расследованием |
### Затронутые среды
| Среда | Риск |
|-------------|------|
| Физические Linux-серверы | Критический |
| Linux-виртуальные машины (облачные или локальные) | Критический |
| Узлы Kubernetes | Критический (также позволяет побег из контейнера) |
| Хосты Docker | Критический |
| Общий хостинг / мультитенантные среды | Критический |
| WSL2 / Linux на Windows | Оценивается по версии ядра |
---
## 3. Техническое глубокое погружение
### 3.1 Предыстория: AF_ALG и AEAD
Ядро Linux предоставляет криптографические операции пользовательскому пространству через **сокеты AF_ALG** (`AF_ALG = 38`). Этот интерфейс (`algif_aead`) позволяет непривилегированным приложениям вызывать аппаратные криптоускорители ядра без необходимости в коде на уровне ядра.
**AEAD** (Authenticated Encryption with Associated Data) — алгоритмы аутентифицированного шифрования с ассоциированными данными, такие как AES-GCM и ChaCha20-Poly1305, широко используются в TLS, шифровании дисков и VPN-протоколах. Уязвимым шаблоном является `authencesn` — AEAD-композиция на основе `hmac(sha256)` + `cbc(aes)` с поддержкой расширенного порядкового номера (ESN), обычно используемая в IPsec.
### 3.2 Корневая причина
В 2017 году коммит `72548b093ee3` ввёл **операцию AEAD на месте** в `algif_aead` как оптимизацию производительности — позволяя криптодвижку читать и записывать один и тот же буфер. Это было ошибочно:```
The bug chain:
1. Caller binds AF_ALG socket to:
authencesn(hmac(sha256),cbc(aes))
2. Caller sends a decryption request via sendmsg() with specific flags
3. Caller uses splice() to feed PAGE CACHE PAGES from an open file
descriptor directly into the socket's scatterlist
4. The authencesn template, during ESN header processing, uses the
OUTPUT BUFFER as scratch space — writing 4 bytes past the
expected output boundary
5. Because the scatterlist contains page cache pages (not private
copies), this scratch write lands DIRECTLY IN THE PAGE CACHE
6. Page cache is shared kernel-wide — all processes reading the
same file now see the modified bytes
Key insight: splice() is zero-copy — it hands page cache references
to the socket. The in-place "optimization" then writes INTO those
pages. No dirty bit is set because the write goes through the crypto
engine, not the normal write path.
Уязвимость обеспечивает контролируемую запись 4 байт в page cache любого файла, который атакующий может открыть для чтения:
| Свойство | Значение |
|---|---|
| Размер записи | 4 байта |
| Контроль смещения | Да — контролируется атакующим через смещение splice |
| Цель | Page cache любого читаемого файла |
| Пометка грязной страницы | Нет |
| Изменение на диске | Нет |
| Обновление временной метки | Нет |
| Запись в журнале ядра | Нет (если не настроен auditd) |
Запись повторяема — эксплойт зацикливает запись по 4 байта для патча более крупных последовательностей кода.
[1] Open /usr/bin/su (or any setuid-root binary) for reading ↓ [2] Map a copy to find target instruction bytes (e.g., UID check, execve path, security gate) ↓ [3] Compute exact page cache offset of target bytes ↓ [4] Set up AF_ALG socket → authencesn(hmac(sha256),cbc(aes)) ↓ [5] splice() the target binary's page cache into the socket ↓ [6] Trigger decryption → authencesn scratch write patches the target bytes in page cache (4 bytes per iteration) ↓ [7] Repeat for each 4-byte patch needed ↓ [8] Execute /usr/bin/su → runs root-owned setuid binary but now with attacker-controlled code in page cache ↓ [9] Root shell
### 3.5 Почему стандартные защиты не срабатывают