🛡️ CVE-2026-98432: удалённый root на Linux через MPTCP, Go 1.24+ и экстренный Xray v26.10.31

О чём заметка
Разбор уязвимости ядра Linux CVE-2026-98432 (октябрь 2026) для тех, кто держит свой прокси-сервер на Xray или другой программе на Go: что сломано в ядре, почему опасность резко выросла именно у Go-серверов, что изменил выпуск Xray v26.10.31 и как проверить и закрыть свой сервер.
TL;DR
- В ядре Linux нашли ошибку при приёме входящих IPv4 TCP-подключений: память освобождается, пока другое ядро процессора ещё её читает. CVE-2026-98432 получила оценку 9,8 из 10, ошибка есть в ядрах начиная с 4.4.
- Anthropic показала, как через эту ошибку получить root на сервере с MPTCP-слушателем без пароля и без действий администратора: в их тесте ушло 48 + 5 минут, а неудачная попытка систему не роняет.
- Программы на Go 1.24 и новее открывают MPTCP-слушатели сами, даже если администратор об этом не знает. На типичном VPS с Xray именно Xray оказывается таким слушателем.
- Xray v26.10.31 вышел 31 октября 2026 года как экстренное обновление: MPTCP теперь выключен по умолчанию. Команда Go менять своё поведение пока не стала.
- Полностью закрывает дыру только исправленное ядро и перезагрузка. Обновление Xray,
GODEBUG=multipathtcp=0иnet.mptcp.enabled=0убирают самый лёгкий путь атаки, но не саму ошибку.
Что произошло
31 октября 2026 года разработчики Xray выпустили экстренное обновление v26.10.31. В описании выпуска сказано прямо: в ядре Linux нашли способ удалённо получить root через слушатель IPv4 MPTCP, а Go 1.24+ включает MPTCP по умолчанию, поэтому новая версия его выключает. Предыдущая версия v26.10.29 отозвана, пользователям советуют обновиться как можно скорее и заодно обновить ядро Linux, потому что исправить ошибку в корне может только оно.
За выпуском стоит цепочка событий короче месяца. Исправление в ядро Linux приняли 5 октября, по данным The Hacker News, 15 октября опубликовали CVE. Положение изменилось 27 октября: Anthropic опубликовала разбор, где её модель написала рабочий эксплойт с удалённым root, и целью в нём был сервер с MPTCP-слушателем. Через два дня связь с Go заметили в трекере Go и в Xray, и обсуждение пошло уже о том, у кого такие слушатели есть.

Ошибка в ядре: гонка при приёме TCP-подключения
Чтобы понять ошибку, нужно вспомнить, как сервер принимает подключение. Клиент присылает пакет SYN («хочу подключиться»), сервер отвечает SYN-ACK, клиент подтверждает. Пока рукопожатие не закончено, ядро держит для будущего подключения временную запись — запрос на соединение (request socket). Когда рукопожатие завершается, ядро создаёт из неё настоящий сокет подключения. Подробнее о самом рукопожатии рассказано в заметке о том, как DPI «замораживает» VLESS.
В IPv4-пакете бывают IP-опции — редкие служебные поля в заголовке. Если они пришли в SYN, ядро хранит их в записи о запросе. По описанию CVE-2026-98432 в NVD, при создании сокета подключения функция tcp_v4_syn_recv_sock() передаёт ему эти опции, не копируя их. Тем временем другое ядро процессора может обрабатывать повторный SYN для того же запроса и строить по тем же опциям ответный SYN-ACK. Если сокет подключения в этот момент закрывается, опции освобождаются обычным kfree(), а второе ядро продолжает их читать. Такая ошибка называется использованием после освобождения (use-after-free, UAF).
Проще говоря: два обработчика одновременно работают с одним куском памяти, один его выбрасывает, второй продолжает им пользоваться. Атакующий подбирает момент так, чтобы на месте выброшенных данных оказалось то, что нужно ему.
Ошибку внёс коммит, после которого записи о запросах обрабатываются без блокировки слушающего сокета. Затронуты ядра начиная с Linux 4.4; исправление переводит освобождение опций на kfree_rcu(), то есть память отдаётся только после того, как все читатели закончили. Исправленные версии, по записи CVE: 5.10.272, 5.15.223, 6.1.190, 6.6.159, 6.12.113, 6.18.56, 7.2.10 и 7.3. IPv6 первым вариантом ошибки не затронут, потому что для IPv6 ядро опции копирует. Однако сервер, который слушает на [::] и принимает IPv4-подключения через тот же сокет, обрабатывает их IPv4-кодом ядра, так что слушать на [::] вместо 0.0.0.0 не помогает.
У ошибки есть второй вариант — при переносе запросов между сокетами (net.ipv4.tcp_migrate_req=1 или BPF-программа BPF_SK_REUSEPORT_SELECT_OR_MIGRATE). Эта настройка по умолчанию выключена, и, как отметил автор Xray RPRX в обсуждении исправления, ею пользуются немногие.
Как Anthropic дошла до root
27 октября 2026 года команда Frontier Red Team компании Anthropic опубликовала разбор пяти цепочек атак, которые нашла и превратила в эксплойты её внутренняя, ещё не выпущенная исследовательская модель. Одна из них — удалённое выполнение кода в ядре Linux. По словам компании, после начальной постановки задачи Claude написал эксплойт, который позволяет удалённому атакующему отправлять пакеты на сервер Linux с MPTCP-слушателем и выполнять любые команды от root, без учётных данных и без действий пользователя. На русском новость пересказал канал Black Triangle.
Атака идёт в два этапа. На первом атакующий обходит KASLR — случайное размещение ядра в памяти, из-за которого заранее неизвестно, где лежат нужные функции. Гонка заставляет ядро прочитать поле длины, которое контролирует атакующий, и отправить ему лишние байты памяти. Как только в одном из ответов оказывается адрес внутри ядра, расположение ядра раскрыто. На втором этапе та же ошибка переполняет буфер и перезаписывает указатель на функцию (callback) адресом заранее подложенной в память ядра нагрузки. Когда ядро вызывает этот указатель, нагрузка цепочкой обычных функций ядра запускает команду атакующего от root.
Главное свойство этой гонки, по словам Anthropic, в том, что проигрыш ничего не ломает: срывается одно рукопожатие, система работает дальше, поэтому настойчивый атакующий пробует, пока не получится. В демонстрации утечка адреса ядра заняла 48 минут, а ещё пять минут ушло на выполнение команды. Код эксплойта, версию ядра и настройки стенда компания не опубликовала, как отмечает The Hacker News.

Проще говоря: сервер не падает от неудачных попыток, поэтому администратор и мониторинг могут не заметить, что его час подряд атакуют, а в конце атакующий получает полный контроль.
При чём тут MPTCP и Go
MPTCP (Multipath TCP) — расширение TCP, которое позволяет одному подключению идти сразу по нескольким сетевым путям, например одновременно через Wi-Fi и мобильную сеть. В Linux программа должна сама попросить MPTCP при создании сокета, а ядро при этом по умолчанию его разрешает (net.mptcp.enabled=1). Если клиент MPTCP не предлагает, подключение работает как обычный TCP, поэтому снаружи включённый MPTCP никак не заметен.
С версии 1.24 язык Go включает MPTCP по умолчанию для всех слушающих сокетов на Linux. Администратору ничего делать не нужно: любой сервер на Go 1.24+, который сам не выключил эту настройку, принимает подключения через MPTCP. Xray собирается свежим Go (в go.mod версии v26.10.31 указан Go 1.27), а на типичном VPS для обхода блокировок Xray — единственная программа, которая слушает внешние порты. Отсюда вывод RPRX: для большинства пользователей Xray единственный IPv4 MPTCP-слушатель на сервере — это сам Xray или другой прокси на Go.
В самой записи CVE и в исправлении ядра MPTCP не упоминается, связь с ним пришла из разбора Anthropic. Ошибка находится в общем коде IPv4 TCP, и Red Hat пишет, что вызвать гонку может удалённый атакующий, которому доступен любой открытый TCP-сервис. Но вызвать гонку и довести её до root — разные вещи. RPRX рассуждает так: все IPv4 TCP-слушатели затронуты, однако через MPTCP получить root особенно легко, иначе Anthropic атаковала бы обычный TCP. Это вывод по косвенным признакам, а не доказанный факт: на 31 октября 2026 года публично root без MPTCP никто не показал, и команда безопасности Go прямо предупреждает, что системы без MPTCP-слушателей тоже могут оказаться уязвимы к похожим атакам.
MPTCP-слушатели есть не только у Xray
На проверочном хосте 31 октября 2026 года команда
ss -Mlnp(её разбор ниже) показала MPTCP-слушатели уxray, уtailscaledи у собственного сервиса на Go. Это наблюдение одной машины, но оно показывает общую картину: MPTCP открывает любая программа на Go 1.24+, а не только прокси.
Позиция Go и решение Xray
29 октября в трекере Go открыли предложение выключить MPTCP по умолчанию. В ночь на 30 октября по московскому времени команда безопасности Go ответила заявлением в рассылке golang-announce, которое переслали и в oss-security. Лучшее исправление, по словам команды, — обновить ядро. MPTCP можно выключить переменной окружения GODEBUG=multipathtcp=0, строкой godebug multipathtcp=0 в go.mod при сборке или для отдельного сокета через net.ListenConfig.SetMultipathTCP. При этом команда называет выключение MPTCP в каждой программе по отдельности ненадёжной защитой: стоит забыть одну программу, и система уязвима, к тому же неизвестно, все ли рабочие эксплойты требуют MPTCP. Менять поведение самого Go в ответ на эту ошибку команда считает преждевременным.
Xray решил иначе. В запросе на изменение #7291, открытом 29 октября и принятом 31 октября, MPTCP в слушателях Xray выключается явно. Попутно исправлена старая неувязка: опция tcpMptcp в sockopt раньше умела только включать MPTCP, а значение false ничего не меняло, потому что Go и так включал его сам. Теперь опция снова работает в обе стороны, и кому MPTCP действительно нужен, может включить его вручную. RPRX объяснил выбор так: позиция Go обоснована, но для пользователей Xray выключение MPTCP по умолчанию заметно сокращает поверхность атаки, а выпуск в виде срочного обновления заодно напомнит обновить ядро.
Кого это касается
Владельцы серверов. В первую очередь — все, у кого на Linux-сервере с непропатченным ядром работает прокси на Go 1.24+ и слушает внешний IPv4-порт: Xray до v26.10.31 и другие программы на Go, которые MPTCP сами не выключают. В панелях управления версия ядра Xray обычно выбирается отдельно от версии самой панели, поэтому проверять стоит именно ядро.
Android-клиенты с доступом из локальной сети. В описании выпуска Xray отдельно отмечено, что ошибка касается не только серверов: Android-клиенту тоже грозит некоторая опасность, если в нём включены входящие SOCKS/HTTP-подключения с опцией «Разрешить подключения из локальной сети». Тогда клиент слушает порт для всей Wi-Fi-сети, и до него может дотянуться любой участник этой сети. Ядро на телефоне обновляет производитель, и часто с большой задержкой, а клиенты с устаревшим ядром Xray встречаются нередко — например, у Happ ядро Xray обновляется медленно. О том, чем ещё опасен открытый SOCKS-порт клиента, рассказано в заметке про неаутентифицированный SOCKS5 на localhost.
Обычные устройства, которые ничего не слушают. Ошибка находится в коде, который принимает входящие подключения. Устройство, у которого нет открытых для сети TCP-портов, этим путём не атакуется, а Go по умолчанию включает MPTCP только для слушающих сокетов, не для исходящих. Это вывод из описания исправления, а не отдельное заявление разработчиков.
Версия: MPTCP как примета Go-серверов
В том же комментарии RPRX мимоходом заметил, что неизвестно, не получил ли Великий китайский файрвол «бонус», и что REALITY, у которого MPTCP включён пассивно, по умолчанию выглядит ещё более странно. Возможное прочтение: REALITY выдаёт себя за чужой сайт, а настоящий сайт на nginx на предложение MPTCP отвечает обычным TCP. Сервер на Go 1.24+ отвечает согласием, и по этой разнице его можно отличить от маскировки. Это гипотеза из реплики разработчика, а не подтверждённый способ обнаружения; выключение MPTCP в v26.10.31 её снимает.
Как проверить свой сервер
Сначала узнайте версию ядра командой uname -r и сравните её с исправленными версиями выше. Для ядер из дистрибутива надёжнее смотреть трекер безопасности самого дистрибутива, потому что исправление переносят в старые ветки под их собственными номерами. В Debian исправление уже вышло: 6.1.190-1 для bookworm и 6.12.113-1 для trixie. В Ubuntu на 31 октября 2026 года все поддерживаемые выпуски значатся уязвимыми, исправление «в работе». Red Hat, по данным The Hacker News на 30 октября, относит RHEL 8, 9 и 10 к затронутым, а исправленных ядер ещё не выпустил.
Дальше проверьте, включён ли MPTCP в системе и кто его слушает:
uname -r # версия ядра
cat /proc/sys/net/mptcp/enabled # 1 — MPTCP в системе разрешён
cat /proc/sys/net/ipv4/tcp_migrate_req # 1 — включён перенос запросов (второй вариант ошибки)
sudo ss -Mlnp # только MPTCP-слушатели и их процессы
xray version # версия ядра Xray; нужна v26.10.31 или новееФлаг -M у ss показывает только MPTCP-сокеты. Не добавляйте к нему -t: вместе они выводят и обычные TCP-слушатели, и список выглядит хуже, чем есть. Если ss -Mlnp показывает процесс на внешнем IPv4-адресе или на 0.0.0.0 и [::], а ядро не исправлено, сервер подходит под сценарий из разбора Anthropic.
Что делать

- Обновите ядро и перезагрузите сервер. Это единственная мера, которая закрывает ошибку целиком, в том числе для обычного TCP. Установленный пакет без перезагрузки ничего не меняет: работает старое ядро.
- Обновите Xray до v26.10.31. Если сервер управляется панелью, обновите ядро Xray через неё и проверьте версию командой выше.
- Выключите MPTCP в остальных программах на Go. Для службы systemd добавьте в её override строку
Environment=GODEBUG=multipathtcp=0(systemctl edit <служба>), затем перезапустите службу. - Или выключите MPTCP во всей системе:
sysctl -w net.mptcp.enabled=0и та же строкаnet.mptcp.enabled=0в файле/etc/sysctl.d/, чтобы настройка пережила перезагрузку. Так защищены сразу все программы, но уже запущенные службы надо перезапустить: в рассылке oss-security предупредили, что программы на Go, запущенные после изменения, переходят на обычный TCP без проблем, а уже работающие могут выдавать ошибки на новых подключениях. - Проверьте, что
net.ipv4.tcp_migrate_reqравен 0, если не включали его сознательно. - Если исправленного ядра для вашего дистрибутива ещё нет, Red Hat предлагает правило nftables, которое отбрасывает входящие IPv4 TCP-пакеты с IP-опциями. Обычный трафик его не задевает, потому что TCP-опции живут в заголовке TCP, а не IP. По словам Red Hat, правило снижает риск, но полностью атаку не предотвращает, и его стоит проверить на своём трафике перед включением:
table inet cve_2026_98432 {
chain input {
type filter hook input priority -310; policy accept;
ip protocol tcp ip hdrlength > 5 counter drop
}
}
Сохраните правило в файл cve-2026-98432.nft, проверьте командой sudo nft --check --file cve-2026-98432.nft и примените sudo nft --file cve-2026-98432.nft. После обновления ядра таблицу удаляют: sudo nft delete table inet cve_2026_98432.
Вывод
Выключенный MPTCP убирает путь, по которому root уже показан, и поэтому выпуск Xray v26.10.31 стоит поставить сразу. Но ошибка остаётся в общем коде IPv4 TCP, и, как подчёркивают и Go, и Red Hat, окончательно сервер защищает только исправленное ядро.
Источники
- XTLS/Xray-core, 31 октября 2026 — выпуск v26.10.31
- XTLS/Xray-core — PR #7291 «DefaultListener: Disable MPTCP by default»
- XTLS/Xray-core — комментарий RPRX в PR #7291, 31 октября 2026
- NVD — CVE-2026-98432
- Anthropic, 27 октября 2026 — Discovering vulnerabilities with Claude
- Black Triangle, Telegram — пересказ разбора Anthropic на русском
- The Hacker News — Linux Kernel TCP Flaw With 9.8 CVSS Score Affects Ubuntu, Red Hat and Other Distributions
- golang-announce, 30 октября 2026 — Protecting against CVE-2026-98432
- oss-security, 30 октября 2026 — пересылка заявления Go
- oss-security, 30 октября 2026 — системное отключение MPTCP через sysctl
- golang/go #82717 — proposal: net: Disable MPTCP by default
- golang/go — коммит «net: enable multipath TCP by default for listeners»
- Red Hat — страница CVE-2026-98432
- Red Hat — бюллетень RHSB-2026-016 с правилом nftables
- Debian Security Tracker — CVE-2026-98432
- Ubuntu Security — CVE-2026-98432
📚 См. также
- Раздел Xray, VLESS и REALITY — обзор ядра Xray-core и его протоколов
- REALITY — как прокси выдаёт себя за чужой сайт и почему любая разница в поведении сервера важна
- Чем плох Happ — в том числе почему клиенты с устаревшим ядром Xray опасны
- Уязвимость VLESS-клиентов: SOCKS5 на localhost — другой риск открытого порта на клиенте
- Защита VPN-клиента от localhost-атаки — как закрыть входящие порты клиента
🤖 Эти статьи открыты — можно обучать на них ИИ
При желании вы можете натренировать ИИ на наших статьях. Исходное форматирование доступно в Forgejo: исходник этой заметки · скачать весь репозиторий одним zip-архивом.