
Набор инструментов для исследования и обнаружения LPE-уязвимости CVE-2026-31431 в ядре Linux, включающий анализ эксплойтов, правила YARA, обнаружение через auditd/Falco, руководство по патчингу и лабораторную среду.
algif_aeadCISA KEV | CVSS 7.8 HIGH | Затрагивает ядра Linux 4.14 — начало 2026 года (~9 лет)
CVE-2026-31431, получивший прозвище «Copy Fail», — это уязвимость локального повышения привилегий (LPE) высокой степени серьёзности в криптографической подсистеме ядра Linux. Непривилегированный локальный пользователь может повысить привилегии до root за секунды на любой системе без установленного патча.
detection/check_vulnerable.sh до и после устранения уязвимости.CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
| Metric | Value | Rationale |
|--------|-------|-----------|
| Attack Vector | **Local** | Requires shell access (SSH, container exec, physical) |
| Attack Complexity | **Low** | Reliable, fully automated — no race condition required |
| Privileges Required | **Low** | Any unprivileged user account |
| User Interaction | **None** | No victim interaction needed |
| Confidentiality | **High** | Full system compromise |
| Integrity | **High** | Full system compromise |
| Availability | **High** | Full system compromise |
### Threat Landscape
| Factor | Assessment |
|--------|-----------|
| PoC Availability | Public, weaponized, 732-byte standalone Python |
| Exploit Reliability | High — works across tested distros without modification |
| Detection Difficulty | High — no disk writes, no dirty pages |
| Attacker Skill Required | Low — script kiddie with public PoC |
| CISA KEV | Added 2026 — actively monitored |
| Microsoft Defender | Flagged as under active investigation |
### Affected Environments
| Environment | Risk |
|-------------|------|
| Bare-metal Linux servers | Critical |
| Linux VMs (cloud or on-prem) | Critical |
| Kubernetes nodes | Critical (also enables container escape) |
| Docker hosts | Critical |
| Shared hosting / multi-tenant | Critical |
| WSL2 / Linux on Windows | Assess per kernel version |
---
## 3. Technical Deep Dive
### 3.1 Background: AF_ALG and AEAD
The Linux kernel exposes cryptographic operations to userspace via **AF_ALG sockets** (`AF_ALG = 38`). This interface (`algif_aead`) allows unprivileged applications to invoke kernel crypto hardware accelerators without needing kernel-mode code.
**AEAD** (Authenticated Encryption with Associated Data) algorithms like AES-GCM and ChaCha20-Poly1305 are widely used for TLS, disk encryption, and VPN protocols. The vulnerable template is `authencesn` — an AEAD composition using `hmac(sha256)` + `cbc(aes)` with Extended Sequence Number (ESN) support, commonly used in IPsec.
### 3.2 Root Cause
In 2017, commit `72548b093ee3` introduced **in-place AEAD operation** to `algif_aead` as a performance optimization — allowing the crypto engine to read and write the same buffer. This was flawed:```
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 байта для пропатчивания более крупных последовательностей кода.
[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 Почему стандартные защиты не срабатывают
| Защита | Обойдена? | Причина |
|---------|-----------|--------|
| Мониторинг целостности файлов (Tripwire/AIDE) | **Да** | Нет изменений на диске |
| Проверка хешей файлов в IDS | **Да** | Байты на диске не изменены |
| `inotify` отслеживание файлов | **Да** | Нет события записи в VFS |
| SELinux / AppArmor | **Частично** | Контролирует процесс, а не запись в page cache через криптодвижок |
| Read-only монтирования | **Да** | Page cache изменяется в памяти, а не через монтирование |
| auditd `watch` на бинарник | **Да** | Audit отслеживает записи VFS — здесь VFS обходится |
### 3.6 Затронутые версии ядра
| Ветка | Уязвима до | Исправлена с |
|--------|-------------------|------------|
| 4.14.x | Все (источник уязвимости) | Нет исправления в апстриме (EOL) |
| 5.4.x (LTS) | Все | Требуется бэкпорт от дистрибутива |
| 5.10.x (LTS) | Все | Требуется бэкпорт от дистрибутива |
| 5.15.x (LTS) | Все | Требуется бэкпорт от дистрибутива |
| 6.1.x (LTS) | ≤ 6.1.129 | **6.1.130+** |
| 6.6.x (LTS) | ≤ 6.6.86 | **6.6.87+** |
| 6.12.x (LTS) | ≤ 6.12.22 | **6.12.23+** |
| 6.15-rc | Исправлено в rc | **6.15-rc+** |
> Ядра дистрибутивов могут иметь бэкпорт исправления с другими номерами версий. Всегда проверяйте бюллетень безопасности вашего дистрибутива.
---
## 4. Методология атаки — Red Team
> **Требуется авторизация.** Этот раздел существует, чтобы помочь защитникам понять точку зрения атакующего. Выполняйте действия только на системах, которыми владеете, или на которые имеете явное письменное разрешение на тестирование.
### 4.1 Предварительные требования
- Оболочка с низкими привилегиями на цели (SSH, container exec, цепочка RCE)
- Python 3.10+ **или** скомпилированный C-бинарник
- Непропатченное ядро с доступным `algif_aead`
### 4.2 Разведка```bash
# Check if vulnerable
uname -r
cat /proc/crypto | grep -A10 "authencesn"
lsmod | grep algif_aead
# Verify setuid target exists
ls -la /usr/bin/su /usr/bin/sudo /usr/bin/passwd
Исследователи (Theori) выпустили полностью рабочий автономный PoC на Python размером 732 байта:
python3 copy_fail_exp.py
python3 copy_fail_exp.py /usr/bin/passwd
Локальная копия доступна по адресу `exploit/poc.py`. Технический разбор см. в `exploit/README.md`.
### 4.4 Сценарий выхода из контейнера
Поскольку кэш страниц Linux является общим для всех процессов на одном хосте (включая хост и контейнеры):```
Attacker in container → patches /usr/bin/su in HOST page cache
Host user runs su → executes attacker code as root on host
Это работает даже из непривилегированных контейнеров, если ядро хоста уязвимо.
Это основная направленность данного репозитория.
Запустите скрипт обнаружения на любой Linux-системе:```bash chmod +x detection/check_vulnerable.sh sudo ./detection/check_vulnerable.sh
**Что проверяет:**
- Версию ядра на соответствие известным уязвимым диапазонам
- Статус загрузки модуля `algif_aead` и статус его блокировки
- Наличие `authencesn` в `/proc/crypto`
- Целостность page cache для setuid-бинарников (требуются права root)
- Статус патчей для конкретного дистрибутива
- Запущенные процессы на предмет индикаторов активной эксплуатации
Отчёт с отметкой времени сохраняется в `/tmp/cve-2026-31431-report-*.txt`.
### 5.2 Обнаружение с помощью YARA
В `detection/yara/` предоставлены два YARA-правила:
| Файл правила | Назначение |
|-----------|---------|
| `cve_2026_31431_base.yar` | Точно сопоставляет известный публичный PoC |
| `cve_2026_31431_enhanced.yar` | Обнаруживает обфусцированные, скомпилированные и модифицированные эксплойты |```bash
# Install YARA
apt-get install yara # Debian/Ubuntu
dnf install yara # RHEL/Fedora
apk add yara # Alpine
# Scan running process executables
sudo yara -r detection/yara/cve_2026_31431_enhanced.yar /proc/*/exe 2>/dev/null
# Scan common dropper locations
sudo yara -r detection/yara/cve_2026_31431_enhanced.yar /home /tmp /var/tmp /dev/shm
# Scan uploaded files / quarantine
yara detection/yara/cve_2026_31431_base.yar <suspect_file>
Почему расширенные правила важны: Атакующие могут обфусцировать публичный Python PoC (закодировать строки в base64, XOR-закодировать имя алгоритма, скомпилировать в C-бинарник, удалить символы). Расширенное правило обнаруживает эти варианты, нацеливаясь на инварианты, которые нельзя удалить без нарушения работы эксплойта:
authesn в качестве имени алгоритмаsplice() для обеспечения доступа к page cache с нулевым копированием38)Разверните в /etc/audit/rules.d/cve-2026-31431.rules:```bash
-a always,exit -F arch=b64 -S socket -F a0=38 -k cve_2026_31431_afalg
-a always,exit -F arch=b64 -S splice -k cve_2026_31431_splice
-a always,exit -F arch=b64 -S init_module -S finit_module -k cve_2026_31431_modload
-a always,exit -F arch=b64 -S execve -F euid=0 -F auid>=1000 -k cve_2026_31431_suid_exec
Перезагрузить:```bash
augenrules --load && service auditd restart
Запрос на попытки эксплуатации:```bash
ausearch -k cve_2026_31431_afalg --start today
ausearch -k cve_2026_31431_afalg -k cve_2026_31431_splice --start today
### 5.4 Обнаружение Falco / eBPF
Добавьте в `/etc/falco/rules.d/cve-2026-31431.yaml`:```yaml
- rule: CVE-2026-31431 AF_ALG Socket Creation
desc: Detects unprivileged process creating AF_ALG socket (family 38) — required step for Copy Fail exploit
condition: >
syscall.type = socket and
evt.arg.domain = 38 and
not user.uid = 0 and
not proc.name in (known_crypto_daemons)
output: >
CVE-2026-31431 exploitation attempt - AF_ALG socket (user=%user.name
uid=%user.uid pid=%proc.pid cmd=%proc.cmdline)
priority: CRITICAL
tags: [cve-2026-31431, lpe, kernel, crypto]
- list: known_crypto_daemons
items: [strongswan, charon, pluto, openssl]
- rule: CVE-2026-31431 Splice After AF_ALG
desc: Detects splice() syscall shortly after AF_ALG socket creation — exploitation sequence
condition: >
syscall.type = splice and
not user.uid = 0 and
evt.elapsed < 5000000000
output: >
CVE-2026-31431 splice after AF_ALG socket (user=%user.name pid=%proc.pid)
priority: CRITICAL
tags: [cve-2026-31431, lpe]
Поскольку эксплойт изменяет кэш страниц без записи на диск, стандартные инструменты FIM этого не видят. Эта проверка обнаруживает активную эксплуатацию:```bash #!/bin/bash
SETUID_BINS=("/usr/bin/su" "/usr/bin/sudo" "/usr/bin/passwd")
for binary in "${SETUID_BINS[@]}"; do [[ -f "$binary" ]] || continue LIVE_HASH=$(sha256sum "$binary" | awk '{print $1}') echo 3 | sudo tee /proc/sys/vm/drop_caches > /dev/null # flush page cache DISK_HASH=$(sha256sum "$binary" | awk '{print $1}') if [[ "$LIVE_HASH" != "$DISK_HASH" ]]; then echo "CRITICAL: Page cache tampering detected on $binary" echo " Pre-flush: $LIVE_HASH" echo " Post-flush: $DISK_HASH" else echo "OK: $binary page cache matches disk" fi done
> **Примечание к продакшену:** `drop_caches` вызывает снижение производительности. Запускайте во время окон технического обслуживания или сначала на некритичных системах.
### 5.6 Индикаторы компрометации (IoCs)
| Тип IoC | Индикатор | Уверенность |
|----------|-----------|-----------|
| Строка (бинарный файл/скрипт) | `authencesn(hmac(sha256),cbc(aes))` | Высокая |
| Шестнадцатеричные байты | `78 DA AB 77 F5 71 63 62 64 64` (заголовок полезной нагрузки zlib) | Высокая |
| Последовательность системных вызовов | `socket(38,5,0)` → `bind()` → `splice()` | Высокая |
| Сеть | Нет — только локально | Н/Д |
| Файл | Нет записи на диск (скрытность) | — |
| Процесс | Недолговечный процесс Python/C с сокетом AF_ALG | Средняя |
| Кэш страниц | Кэш страниц setuid-бинарника ≠ хэш на диске | Критическая |
### 5.7 Запросы обнаружения для SIEM
**Splunk (источник auditd):**```spl
index=linux_audit sourcetype=auditd action=SYSCALL syscall=socket a0="0x26"
| join pid [
search index=linux_audit sourcetype=auditd action=SYSCALL syscall=splice
]
| where (_time - join_time) < 30
| table _time host user pid cmd a0
| eval severity="CRITICAL"
Elastic KQL:```kql event.action: "SYSCALL" AND process.args: "socket" AND auditd.data.a0: "0x26" AND NOT user.id: "0"
**Microsoft Sentinel (KQL):**```kql
Syslog
| where Facility == "kern" or ProcessName == "audit"
| where SyslogMessage contains "socket" and SyslogMessage contains "a0=0x26"
| extend UserName = extract("uid=([0-9]+)", 1, SyslogMessage)
| where UserName != "0"
| project TimeGenerated, Computer, UserName, SyslogMessage
| order by TimeGenerated desc
Запустите автоматический скрипт патчинга:```bash chmod +x patch/patch.sh sudo ./patch/patch.sh
### 6.1 Немедленное смягчение последствий (без перезагрузки*)```bash
# Blacklist the module permanently
echo "install algif_aead /bin/false" | sudo tee /etc/modprobe.d/disable-algif-aead.conf
echo "install authencesn /bin/false" | sudo tee -a /etc/modprobe.d/disable-algif-aead.conf
# Unload if currently loaded
sudo rmmod algif_aead 2>/dev/null || echo "Not loaded — mitigation active after config"
# Verify
lsmod | grep algif_aead && echo "WARNING: still loaded — reboot needed" || echo "OK: not loaded"
*Если algif_aead уже загружен, для полного применения чёрного списка потребуется перезагрузка.
Побочные эффекты: Приложения, использующие интерфейс ядра AEAD через AF_ALG (редко — большинство используют OpenSSL в пользовательском пространстве), могут выйти из строя. Стандартные TLS, шифрование дисков и VPN-инструменты, как правило, не затрагиваются.
kubectl get nodes -o wide
kubectl drain --ignore-daemonsets --delete-emptydir-data
kubectl uncordon
Используйте автообновление узлов (Karpenter, Managed Node Groups) или ротацию пула узлов кластера, где это доступно.
### 6.4 Проверка после применения исправлений```bash
# Re-run detection script
sudo ./detection/check_vulnerable.sh
# Quick manual verification
uname -r # confirm new kernel version
lsmod | grep algif_aead # should be empty
cat /proc/crypto | grep authencesn # should return nothing (or still listed but module blacklisted)
Минимальная лаборатория на базе Alpine Docker предоставляется для безопасного тестирования средств обнаружения.```bash cd lab/ docker compose up -d docker exec -it cve-2026-31431-lab /bin/sh
/cve-2026-31431/detection/check_vulnerable.sh
> **Важно:** Контейнеры Docker используют ядро хоста. Лабораторная работа проверяет уязвимость **ядра вашего хоста**. Результаты оценки уязвимости отражают фактическую хост-систему — это сделано намеренно для реалистичной оценки.
Для изолированного тестирования с конкретной уязвимой версией ядра используйте выделенную виртуальную машину с зафиксированным ядром. Инструкции по настройке ВМ см. в `lab/README.md`.
---
## 8. Ссылки
| Ресурс | Ссылка |
|----------|------|
| Консультация NVD | https://nvd.nist.gov/vuln/detail/CVE-2026-31431 |
| Оригинальное исследование | https://copy.fail |
| Технический разбор | https://xint.io/blog/copy-fail-linux-distributions |
| Публичный PoC | https://github.com/theori-io/copy-fail-CVE-2026-31431 |
| Каталог CISA KEV | https://www.cisa.gov/known-exploited-vulnerabilities-catalog |
| Исправление ядра — откат коммита | `a664bf3d603d` / `fafe0fa2995a` |
| Уязвимый коммит | `72548b093ee3` |
| Консультация Microsoft Defender | Блог Microsoft Defender Threat Intelligence |
---
## Структура репозитория```
cve-2026-31431/
├── README.md ← This document
├── exploit/
│ ├── README.md ← Technical exploit breakdown
│ └── poc.py ← Public PoC (theori-io, for reference)
├── detection/
│ ├── README.md ← Detection guide
│ ├── check_vulnerable.sh ← Vulnerability & IoC detection script
│ └── yara/
│ ├── cve_2026_31431_base.yar ← Detects known public PoC
│ └── cve_2026_31431_enhanced.yar ← Detects obfuscated/compiled variants
├── patch/
│ ├── README.md ← Remediation guide
│ └── patch.sh ← Automated patch/mitigation script
└── lab/
├── README.md ← Lab setup guide
├── Dockerfile ← Alpine-based lab container
└── docker-compose.yml ← Lab orchestration
Данное исследование предоставлено исключительно в образовательных целях и для защиты систем. Все инструменты предназначены для помощи специалистам по безопасности в обнаружении и устранении CVE-2026-31431 на системах, которые им разрешено защищать.
Репозиторий поддерживается rippsec
| Атрибут | Значение |
|---|
| 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 байта) |
| Свойство | Значение |
|---|
| Размер записи | 4 байта |
| Контроль смещения | Да — контролируется атакующим через смещение splice |
| Цель | Page cache любого читаемого файла |
| Пометка грязной страницы | Нет |
| Изменение на диске | Нет |
| Обновление временной метки | Нет |
| Запись в журнале ядра | Нет (если не настроен auditd) |
| Техника | ID | Примечания |
|---|
| Эксплуатация для повышения привилегий | T1068 | Основная техника |
| Злоупотребление механизмом контроля повышения привилегий: Setuid/Setgid | T1548.001 | Перехват setuid-бинарника |
| Перехват потока выполнения | T1574 | Патчинг бинарника в памяти |
| Удаление индикаторов: Timestomp | T1070.006 | Метки времени не обновляются |
| Косвенное выполнение команд | T1202 | Запатченный бинарник выполняет оболочку |
| Дистрибутив | Команда обновления |
|---|
| Ubuntu / Debian | apt-get update && apt-get upgrade linux-image-generic && reboot |
| RHEL / CentOS / Rocky | dnf update kernel && reboot |
| Amazon Linux 2 | yum update kernel && reboot |
| Amazon Linux 2023 | dnf update kernel && reboot |
| SUSE / SLES | zypper update kernel-default && reboot |
| Arch Linux | pacman -Syu linux && reboot |
| Alpine Linux | apk update && apk upgrade linux-lts && reboot |
| Debian | apt-get update && apt-get upgrade linux-image-amd64 && reboot |