
CVE-2026-68398 Ubuntu PPPoL2TP use-after-free local privilege escalation

Этот репозиторий содержит эксплойт локального повышения привилегий, привязанный
к конкретной сборке, для CVE-2026-68398 — гонки вида «использование после
освобождения» (use-after-free) между обработкой приёма PPPoL2TP и уничтожением
неприсоединённого PPP-канала. Он был проверен в QEMU на официальном пакете Ubuntu
22.04 linux-image-5.15.0-187-generic (5.15.0-187.197).
Финальный тест запускается от выделенного пользователя с UID 1001, без
дополнительных групп, без capabilities и без доступа к sudo, после чего получает
UID 0 в начальном пространстве имён. KASLR, SMEP, SMAP и AppArmor остаются
включёнными. Гостевая система не загружается с параметрами nokaslr, nopti,
nosmep или nosmap.
Предупреждение
Этот код намеренно повреждает состояние кучи ядра и привязан к одной конкретной сборке ядра Ubuntu. Неудачная гонка может вызвать панику или повредить систему. Запускайте его только в изолированной, одноразовой виртуальной машине, которой вы владеете.
pppol2tp_recv() выполняется на пути приёма UDP-пакетов L2TP внутри критической
секции чтения RCU и в конечном итоге вызывает ppp_input(&po->chan). Сокет PPPoX
и встроенный в него ppp_channel безопасны с точки зрения RCU, однако внутренняя
struct channel, используемая ppp_input(), представляет собой отдельное
выделение памяти.
Для канала, связанного через PPPIOCGCHAN, но не присоединённого к
PPP-устройству и не задействованного в мостовом режиме, путь закрытия немедленно
освобождал этот внутренний объект:
RX: l2tp_udp_encap_recv -> pppol2tp_recv -> ppp_input(channel)
CLOSE: pppol2tp_release -> pppox_unbind_sock
-> ppp_unregister_channel -> ppp_release_channel -> kfree(channel)
Таким образом, путь приёма может работать с очередью skb и очередью ожидания
освобождённого канала. Исправление добавляет колбэк RCU в struct channel и
откладывает очистку очереди и освобождение памяти до истечения периода ожидания
RCU (RCU grace period).
Уязвимость обнаружил и исправил в основной ветке ядра
Норберт Сетеи из Doyensec.
Исправление в основной ветке —
ec4215683e47424c9c4762fd3c60f552a3119142.
Согласно записи Linux CNA, уязвимая линия начинается с Linux 4.15. Вендорные ядра могут содержать это исправление под другим номером версии, поэтому точный исходный код или журнал изменений пакета имеют приоритет над этой таблицей.
Для более старых поддерживаемых вендорных линий требуется бэкпорт. По состоянию
на 2026-08-12
трекер CVE Ubuntu
помечает пакет linux для Jammy как needs-triage; исправленный пакет Ubuntu
Jammy не обнаружен. Исходный код проверенной версии 5.15.0-187.197
по-прежнему напрямую вызывает kfree(pch) и уязвим.
Ядро не перекомпилировалось. В минимальном облачном образе отсутствовал
linux-modules-extra-5.15.0-187-generic, поэтому для предоставления l2tp_ppp
был установлен этот официальный пакет Ubuntu. Обычная установка Jammy
с использованием метапакета linux-generic уже зависит от соответствующего
пакета modules-extra. Модуль протокола автоматически загружается, когда эксплойт
создаёт свой PPPoL2TP-сокет.
Автоматический детектор KASLR использует побочный канал по времени выполнения
инструкции prefetch в x86 и требует RDTSCP при неактивном KPTI. Проверенный
процессор хоста поддерживает rdtscp, smep и smap и не подвержен Meltdown,
поэтому Ubuntu оставляет KPTI неактивным без каких-либо изменений параметров
загрузки. На процессоре, где /proc/cpuinfo сообщает флаг pti, детектор
отказывается запускаться. Это аппаратное условие, специфичное для эксплойта:
базовый CVE остаётся достижимым, но этот выпуск не заявляет об обходе KASLR
в системе с активным KPTI. Сдвиг, задаваемый вручную, существует только для
контролируемой диагностики.
struct channel. Всё ещё выполняющийся путь RX трактует
управляемые байты ключа как свою очередь skb и очередь ожидания.core_pattern в качестве рабочей области для раскрытия и выявляет
указатель на выделение ключа.override_creds()
с поддельными учётными данными. Поля UID/GID, capabilities, а также
необходимые указатели user, namespace, ucount и group соответствуют точной
сборке Ubuntu./proc/self/exe
в уникальный файл в /tmp, меняет его владельца на root и режим 4755
и проверяет эти атрибуты./usr/bin/id.Последний мост необходим, поскольку override_creds() изменяет субъективные
учётные данные активной задачи ядра; установка и выполнение проверенной
SUID-копии превращает этот недолговечный примитив в обычные учётные данные
процесса.
Makefile компонует эксплойт статически. Чувствительный к таймингам объект
prefetch намеренно компилируется с -O0; сам эксплойт использует -O2.
make
Эквивалентные команды:
gcc -O0 -Wall -Wextra -Werror -c -o build/kaslr_prefetch.o kaslr_prefetch.c
gcc -O2 -static -pthread -Wall -Wextra -Werror \
-o build/CVE-2026-68398 exploit.c build/kaslr_prefetch.o
Из обычной учётной записи пользователя на точно проверенном ядре:
id
grep '^Cap' /proc/self/status
./CVE-2026-68398 auto 60
Исходный код проверяет uname() и отказывается работать с любым релизом, кроме
5.15.0-187-generic. Гонка носит вероятностный характер; после промаха или
краха перезагрузите одноразовый снимок ВМ перед повторной попыткой.
Успешный запуск завершается следующим образом:
[KASLR] image_base=0xffffffffb9200000 slide=0x38200000
CVE-2026-68398 Ubuntu local privilege-escalation exploit
uid=1001 euid=1001 slide=0x38200000
...
[9/9] invoking override_creds and installing the SUID transition...
override callback: uid=0 euid=0 gid=0 egid=0
installed root-owned mode 4755 helper: /tmp/.cve-2026-68398-root-948
SUID helper ready; executing it from the original unprivileged task...
SUID transition: uid=0 euid=0 gid=0 egid=0
uid=0(root) gid=0(root) groups=0(root),1001(poc)
Полный краткий протокол вывода этого реального запуска в QEMU приведён в
docs/example-output.txt.
Цепочка была полностью пройдена на трёх свежих загрузках Ubuntu со штатной
рандомизацией адресного пространства. Автоматически восстановленные базовые
адреса образа ядра: 0xffffffff90800000, 0xffffffffa5a00000 и
0xffffffffb9200000. В финальном запуске использовалась выделенная
неадминистративная учётная запись UID 1001, описанная выше, и было проверено,
что временный SUID-файл впоследствии удалён.
Та же финальная гонка также запускалась на 60 секунд на том самом коммите
исправления из основной ветки с включённым KASAN и той же топологией из четырёх
vCPU. Было завершено 5 969 циклов «канал/ключ», зафиксирован результат
stage 1: no controlled reclaim, и не было ни одного отчёта KASAN или перехода
стадий эксплойта.
Проверено 2026-08-12 до создания этого приватного репозитория. SearchSploit/Exploit-DB не вернули ни одного эксплойта; Packet Storm не вернул подходящих файлов; точный поиск по коду в GitHub вернул 22 зеркала CVE/бюллетеней и ни одного PoC; точный веб-поиск нашёл только исправление из основной ветки и метаданные. Это результат на конкретный момент времени, а не гарантия того, что другой PoC не появится позже.
kaslr_prefetch.cЭксплойт написан А. Рамосом <[email protected]> (Twitter:
@aramosf). Обнаружение уязвимости и исправление
в основной ветке приписываются Норберту Сетеи (Doyensec).
exploit.c распространяется только под лицензией GPL-2.0. kaslr_prefetch.c
и kaslr_prefetch.h лицензированы под MIT и сохраняют указание авторства KASLD
и полное уведомление о разрешении в исходных файлах.
| Линия ядра | Первый исправленный выпуск | Коммит исправления |
|---|
| 6.6.y | 6.6.148 | 4bb84e964ff0 |
| 6.12.y | 6.12.101 | 3ab32218d718 |
| 6.18.y | 6.18.42 | c9574b8a8ede |
| 7.1.y | 7.1.6 | 06213c85d8c0 |
| Mainline | 7.2-rc4 | ec4215683e47 |
| Свойство | Значение |
|---|
| Дистрибутив | Ubuntu 22.04.5 LTS (Jammy) |
| Пакет ядра | linux-image-5.15.0-187-generic / 5.15.0-187.197 |
| Релиз ядра | 5.15.0-187-generic #197-Ubuntu |
| Архитектура | x86-64 |
| ВМ | QEMU/KVM, -cpu host, четыре vCPU, 5 ГиБ ОЗУ |
| Исходная идентичность | uid=1001(poc) gid=1001(poc) groups=1001(poc) |
| Исходные capabilities | inheritable, permitted, effective и ambient — все нулевые |
| Финальная идентичность | uid=0(root) gid=0(root) в начальных пространствах имён |
| Изменения загрузки | Нет; стандартная командная строка, KASLR включён |
| Требование | Состояние в Ubuntu 5.15.0-187 | Использование эксплойтом |
|---|
| PPP | CONFIG_PPP=y | Встроен |
| L2TP / PPPoL2TP | CONFIG_L2TP=m, CONFIG_PPPOL2TP=m | Официальный модуль linux-modules-extra |
| Ключи пользователя | CONFIG_KEYS=y | Повторно занимает освобождённый канал kmalloc-256 |
| AppArmor | CONFIG_SECURITY_APPARMOR=y | Остаётся активным; поддельные учётные данные включают допустимую метку unconfined |
| KASLR | CONFIG_RANDOMIZE_BASE=y | Остаётся активным; сдвиг восстанавливается во время выполнения |
| SMAP | CONFIG_X86_SMAP=y | Остаётся активным |
| Пространства имён пользователя/сетей | Включены Ubuntu, но не используются | Не требуется настройка пространств имён или получение capabilities |
/dev/ppp | Не требуется | Канал связан, но никогда не подключается к PPP-устройству |