
Детектор на Rust и локальная лаборатория для CVE-2026-98432 — use-after-free в IPv4 TCP в Linux в inet_opt/ireq_opt: статический анализ ELF, проверки достижимости через kprobe и триггер гонки.
inet_opt / ireq_opt)Исследовательский PoC и локальная лаборатория для use-after-free в ядре Linux, достижимого из обычного IPv4 TCP-листенера. Это детектор/триггер бага, а не эксплойт.
7.0.0-38-generic):
inet_sock_destruct() и tcp_v4_reqsk_destructor() освобождают опции через
kfree() вместо kfree_rcu().kfree достижим во время выполнения (kprobes).free -> use (via=reqsk) в одном старом прогоне и не смогли воспроизвести
их надёжно.tcp2kaslr также останавливается на триггере бага; последующие стадии
не опубликованы.CONFIG_KASAN выключен, а сэмплирование KFENCE отключено.tcp2kaslr)MPTCP не требуется. Доказанный путь — обычный IPv4 TCP:
ireq_opt).accept() для дочернего сокета, устанавливает SO_LINGER(0) и закрывает его.
inet_sock_destruct() освобождает опции через kfree().Наш более ранний триггер был неверен в двух отношениях: жертва так и не приняла/закрыла
дочерний сокет (free_sock=0), и мы отправляли RST вместо того, чтобы полагаться на закрытие сервером.
Текущий код добавляет правильные элементы:
listen --accept-close — accept + SO_LINGER(0) + close.--sync — ACK + дублированный SYN одновременно, без RST, с опциями Record Route.Исправление в upstream выглядит ровно так:
- kfree(rcu_dereference_protected(inet->inet_opt, 1));
+ kfree_rcu(rcu_dereference_protected(inet->inet_opt, 1), rcu);
и то же изменение в tcp_v4_reqsk_destructor().
| Путь | Что |
|---|---|
rust-poc/ | нативный PoC на Rust: статический анализ ELF, kprobes, режимы запуска |
lab/ | жертва на Alpine + PHP через loopback для старых локальных тестов |
scripts/ | локальные вспомогательные скрипты для воспроизведения, вспомогательные скрипты для авторизованного аудита |
docs/FINDINGS.md | что было протестировано, что подтверждено, что нет |
docs/EXPLOITATION-NOTES.md | область охвата: только запуск бага, без RCE |
docs/evidence/ | очищенные образцы доказательств |
cd rust-poc
cargo build --release
# static analysis (no root)
./target/release/cve-2026-98432 static
# runtime reachability (root, tracefs)
sudo ./target/release/cve-2026-98432 runtime
# correct local vector: accept+close server + --sync trigger
cd ..
PASSES=1 ./scripts/repro-sync.sh 8083
repro-sync.sh запускает жертву с --accept-close на 127.0.0.1:8083, запускает
триггер синхронизации через sudo и выводит free_sock, use_build и
вердикт UAF. Чистый прогон не является доказательством безопасности: частота
составляет примерно 1e-7 на попытку, а события кластеризуются.
Если artifacts/ отсутствует, static/runtime переключаются на /boot;
устаревший scripts/cve-2026-98432.sh --static может сгенерировать артефакты ядра.
С KASAN ядро сообщает о slab-use-after-free в
inet_csk_route_req / ip_options_build со стеком освобождения в
inet_sock_destruct / inet_release. Харнесс tcp2kaslr достигает этого примерно
за 134 тыс. попыток с KASAN; на обычном ядре та же гонка наблюдалась лишь
дважды за ~48 млн попыток.
Тестируйте только те ядра и хосты, которыми вы владеете или на тестирование которых у вас есть явное разрешение. Триггер представляет собой гонку в ядре и может привести к краху хоста. Используйте одноразовую ВМ со снимком.
offline-ant/tcp2kaslr — триггер бага, доказательства KASAN, анализ:
https://github.com/offline-ant/tcp2kaslripv4: free inet_opt and ireq_opt after an RCU grace period
(Eric Dumazet), kfree → kfree_rcu в net/ipv4/af_inet.c и
net/ipv4/tcp_ipv4.c.MIT. См. LICENSE.