
Реализация dirtyfrag на Go (CVE-2026-43284 / CVE-2026-43500)
Два бага. Один шелл. Никаких записей на диск.
Go-порт dirtyfrag (CVE-2026-43284 / CVE-2026-43500).
Класс уязвимости находится в подсистеме XFRM ядра Linux. Когда страница файла передаётся через splice() в pipe, а затем в сокет с ESP-шифрованием, ядро расшифровывает ESP-нагрузку на месте — прямо в страницу page-cache исходного файла. Файл доступен только для чтения. Page cache — нет.
dirtyfrag объединяет две независимые уязвимости, эксплуатирующие этот примитив:
CVE-2026-43284 — путь ESP/XFRM
Устанавливает 48 SA в транспортном режиме XFRM через NETLINK_XFRM. Каждая SA кодирует 4 байта шеллкода в поле seq_hi своего ESN replay state. Цепочка vmsplice + splice запускает расшифровку ESP на месте для каждой SA, записывая эти 4 байта в запись page-cache файла /usr/bin/su. 48 триггеров, 192 байта записано, без состояния гонки.
CVE-2026-43500 — путь RxRPC/rxkad
Перебирает офлайн 3 сессионных ключа PCBC(fcrypt), которые при расшифровке дают целевые байтовые последовательности. Запускает триггер сокета AF_RXRPC для каждого ключа, чтобы пропатчить корневую запись в /etc/passwd до root::0:0 (nullok). После этого su - принимает пустой пароль.
Оба пути выполняются в пользовательском и сетевом неймспейсах (CLONE_NEWUSER | CLONE_NEWNET), чтобы не требовать CAP_NET_ADMIN на хосте.
go build -o dirtyfrag-go .
./dirtyfrag-go
# Force a specific path
./dirtyfrag-go --force-esp
./dirtyfrag-go --force-rxrpc
# Verbose output
./dirtyfrag-go -v
Бинарник сначала пробует путь ESP. Если /usr/bin/su после этого не пропатчен, он переключается на путь RxRPC (до 3 повторных попыток). При успехе открывает root-шелл через новый PTY.
Эксплойт затрагивает только page cache. Бинарники на диске и /etc/passwd не изменяются. Перезагрузка восстанавливает всё. Чтобы немедленно сбросить кэш без перезагрузки:
echo 1 | tee /proc/sys/vm/drop_caches
esp4, esp6 (путь ESP) и/или rxrpc (путь RxRPC)Все ядра до выхода патчей:
rmmod esp4 esp6 rxrpc
printf 'install esp4 /bin/false\ninstall esp6 /bin/false\ninstall rxrpc /bin/false\n' \
> /etc/modprobe.d/dirtyfrag.conf
Среда выполнения Go с самого начала многопоточная, поэтому unshare(CLONE_NEWUSER) недопустим. Go-порт перезапускает себя как дочерний процесс с установленным SysProcAttr.Cloneflags, который вызывает clone() до инициализации Go runtime.
| C (оригинал) | Go |
|---|
| Внешние зависимости | нет | нет |
| Один файл | нет | нет |
| Статический бинарник | да | да |
| Путь RxRPC | да | да |
| Путь ESP | да | да |
| Изоляция неймспейсов | unshare() | повторный exec с Cloneflags |