todo/xray/mptcp-linux-kernel-rce-cve-2026-98432.md
loop-uh 804dea4fc3
Some checks failed
Published content check / validate (push) Failing after 8s
xray: обложка статьи о CVE-2026-98432
Шапка статьи про удалённый root через MPTCP и Xray v26.10.31:
РКН-тян «взламывает» сервер, Запрет-тян держит обновление ядра.
Добавлены embed после заголовка и поле image во frontmatter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 10:49:33 -04:00

174 lines
31 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
date: 2026-10-31
tags:
- xray
- linux
- уязвимость
- mptcp
- golang
- сервер
- безопасность
aliases:
- CVE-2026-98432
- Уязвимость ядра Linux MPTCP удалённый root
- Xray v26.10.31 экстренное обновление
- Почему Xray отключил MPTCP
- GODEBUG multipathtcp=0
- Как проверить сервер на CVE-2026-98432
- net.mptcp.enabled=0 как отключить MPTCP
- Anthropic Claude эксплойт ядра Linux
description: "CVE-2026-98432: гонка в IPv4 TCP ядра Linux даёт удалённый root через MPTCP, который Go 1.24+ включает сам. Почему вышел Xray v26.10.31 и как закрыть сервер."
image: xray/attachments/mptcp-rce-header.jpg
link: https://github.com/XTLS/Xray-core/releases/tag/v26.10.31
---
> [!mirror] Резервное зеркало
> Актуальная версия этой страницы — на основной вики: [jzesawgjsz.zapret.moe/xray/mptcp-linux-kernel-rce-cve-2026-98432](https://jzesawgjsz.zapret.moe/xray/mptcp-linux-kernel-rce-cve-2026-98432)
# 🛡️ CVE-2026-98432: удалённый root на Linux через MPTCP, Go 1.24+ и экстренный Xray v26.10.31
![[mptcp-rce-header.jpg]]
> [!info] О чём заметка
> Разбор уязвимости ядра Linux CVE-2026-98432 (октябрь 2026) для тех, кто держит свой прокси-сервер на Xray или другой программе на Go: что сломано в ядре, почему опасность резко выросла именно у Go-серверов, что изменил выпуск Xray v26.10.31 и как проверить и закрыть свой сервер.
## TL;DR
- В ядре Linux нашли ошибку при приёме входящих IPv4 TCP-подключений: память освобождается, пока другое ядро процессора ещё её читает. [CVE-2026-98432 получила оценку 9,8 из 10](https://nvd.nist.gov/vuln/detail/CVE-2026-98432), ошибка есть в ядрах начиная с 4.4.
- [Anthropic показала](https://www.anthropic.com/research/discovering-vulnerabilities-with-claude), как через эту ошибку получить root на сервере с MPTCP-слушателем без пароля и без действий администратора: в их тесте ушло 48 + 5 минут, а неудачная попытка систему не роняет.
- Программы на Go 1.24 и новее открывают MPTCP-слушатели сами, даже если администратор об этом не знает. На типичном VPS с Xray именно Xray оказывается таким слушателем.
- [Xray v26.10.31](https://github.com/XTLS/Xray-core/releases/tag/v26.10.31) вышел 31 октября 2026 года как экстренное обновление: MPTCP теперь выключен по умолчанию. Команда Go менять своё поведение [пока не стала](https://groups.google.com/g/golang-announce/c/PCoQcdxoScw/m/aD-MgXEvAAAJ).
- Полностью закрывает дыру только исправленное ядро и перезагрузка. Обновление Xray, `GODEBUG=multipathtcp=0` и `net.mptcp.enabled=0` убирают самый лёгкий путь атаки, но не саму ошибку.
## Что произошло
31 октября 2026 года разработчики Xray выпустили [экстренное обновление v26.10.31](https://github.com/XTLS/Xray-core/releases/tag/v26.10.31). В описании выпуска сказано прямо: в ядре Linux нашли способ удалённо получить root через слушатель IPv4 MPTCP, а Go 1.24+ включает MPTCP по умолчанию, поэтому новая версия его выключает. Предыдущая версия v26.10.29 отозвана, пользователям советуют обновиться как можно скорее и заодно обновить ядро Linux, потому что исправить ошибку в корне может только оно.
За выпуском стоит цепочка событий короче месяца. Исправление в ядро Linux приняли 5 октября, [по данным The Hacker News](https://thehackernews.com/2026/10/linux-kernel-tcp-flaw-with-98-cvss.html), 15 октября опубликовали CVE. Положение изменилось 27 октября: Anthropic опубликовала разбор, где её модель написала рабочий эксплойт с удалённым root, и целью в нём был сервер с MPTCP-слушателем. Через два дня связь с Go заметили в трекере Go и в Xray, и обсуждение пошло уже о том, у кого такие слушатели есть.
![[mptcp-rce-timeline.png]]
## Ошибка в ядре: гонка при приёме TCP-подключения
Чтобы понять ошибку, нужно вспомнить, как сервер принимает подключение. Клиент присылает пакет SYN («хочу подключиться»), сервер отвечает SYN-ACK, клиент подтверждает. Пока рукопожатие не закончено, ядро держит для будущего подключения временную запись — запрос на соединение (`request socket`). Когда рукопожатие завершается, ядро создаёт из неё настоящий сокет подключения. Подробнее о самом рукопожатии рассказано в заметке [[VLESS/dpi-tls-june-2026|о том, как DPI «замораживает» VLESS]].
В IPv4-пакете бывают IP-опции — редкие служебные поля в заголовке. Если они пришли в SYN, ядро хранит их в записи о запросе. По [описанию CVE-2026-98432 в NVD](https://nvd.nist.gov/vuln/detail/CVE-2026-98432), при создании сокета подключения функция `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 в обсуждении исправления](https://github.com/XTLS/Xray-core/pull/7291#issuecomment-6540309985), ею пользуются немногие.
## Как Anthropic дошла до root
27 октября 2026 года команда Frontier Red Team компании Anthropic опубликовала [разбор пяти цепочек атак](https://www.anthropic.com/research/discovering-vulnerabilities-with-claude), которые нашла и превратила в эксплойты её внутренняя, ещё не выпущенная исследовательская модель. Одна из них — удалённое выполнение кода в ядре Linux. По словам компании, после начальной постановки задачи Claude написал эксплойт, который позволяет удалённому атакующему отправлять пакеты на сервер Linux с MPTCP-слушателем и выполнять любые команды от root, без учётных данных и без действий пользователя. На русском новость [пересказал канал Black Triangle](https://t.me/black_triangle_tg/9741).
Атака идёт в два этапа. На первом атакующий обходит KASLR — случайное размещение ядра в памяти, из-за которого заранее неизвестно, где лежат нужные функции. Гонка заставляет ядро прочитать поле длины, которое контролирует атакующий, и отправить ему лишние байты памяти. Как только в одном из ответов оказывается адрес внутри ядра, расположение ядра раскрыто. На втором этапе та же ошибка переполняет буфер и перезаписывает указатель на функцию (`callback`) адресом заранее подложенной в память ядра нагрузки. Когда ядро вызывает этот указатель, нагрузка цепочкой обычных функций ядра запускает команду атакующего от root.
Главное свойство этой гонки, по словам Anthropic, в том, что проигрыш ничего не ломает: срывается одно рукопожатие, система работает дальше, поэтому настойчивый атакующий пробует, пока не получится. В демонстрации утечка адреса ядра заняла 48 минут, а ещё пять минут ушло на выполнение команды. Код эксплойта, версию ядра и настройки стенда компания не опубликовала, [как отмечает The Hacker News](https://thehackernews.com/2026/10/linux-kernel-tcp-flaw-with-98-cvss.html).
![[mptcp-rce-attack-chain.png]]
Проще говоря: сервер не падает от неудачных попыток, поэтому администратор и мониторинг могут не заметить, что его час подряд атакуют, а в конце атакующий получает полный контроль.
## При чём тут MPTCP и Go
MPTCP (`Multipath TCP`) — расширение TCP, которое позволяет одному подключению идти сразу по нескольким сетевым путям, например одновременно через Wi-Fi и мобильную сеть. В Linux программа должна сама попросить MPTCP при создании сокета, а ядро при этом по умолчанию его разрешает (`net.mptcp.enabled=1`). Если клиент MPTCP не предлагает, подключение работает как обычный TCP, поэтому снаружи включённый MPTCP никак не заметен.
С версии 1.24 язык Go [включает MPTCP по умолчанию для всех слушающих сокетов](https://github.com/golang/go/commit/3d4daa38a763260e07f4745110f2b5fcbec25126) на 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 пишет](https://access.redhat.com/security/cve/cve-2026-98432), что вызвать гонку может удалённый атакующий, которому доступен любой открытый TCP-сервис. Но вызвать гонку и довести её до root — разные вещи. RPRX рассуждает так: все IPv4 TCP-слушатели затронуты, однако через MPTCP получить root особенно легко, иначе Anthropic атаковала бы обычный TCP. Это вывод по косвенным признакам, а не доказанный факт: на 31 октября 2026 года публично root без MPTCP никто не показал, и [команда безопасности Go](https://groups.google.com/g/golang-announce/c/PCoQcdxoScw/m/aD-MgXEvAAAJ) прямо предупреждает, что системы без MPTCP-слушателей тоже могут оказаться уязвимы к похожим атакам.
> [!note] MPTCP-слушатели есть не только у Xray
> На проверочном хосте 31 октября 2026 года команда `ss -Mlnp` (её разбор ниже) показала MPTCP-слушатели у `xray`, у `tailscaled` и у собственного сервиса на Go. Это наблюдение одной машины, но оно показывает общую картину: MPTCP открывает любая программа на Go 1.24+, а не только прокси.
## Позиция Go и решение Xray
29 октября в трекере Go открыли [предложение выключить MPTCP по умолчанию](https://github.com/golang/go/issues/82717). В ночь на 30 октября по московскому времени команда безопасности Go ответила [заявлением в рассылке golang-announce](https://groups.google.com/g/golang-announce/c/PCoQcdxoScw/m/aD-MgXEvAAAJ), которое [переслали и в oss-security](https://www.openwall.com/lists/oss-security/2026/10/30/1). Лучшее исправление, по словам команды, — обновить ядро. MPTCP можно выключить переменной окружения `GODEBUG=multipathtcp=0`, строкой `godebug multipathtcp=0` в `go.mod` при сборке или для отдельного сокета через `net.ListenConfig.SetMultipathTCP`. При этом команда называет выключение MPTCP в каждой программе по отдельности ненадёжной защитой: стоит забыть одну программу, и система уязвима, к тому же неизвестно, все ли рабочие эксплойты требуют MPTCP. Менять поведение самого Go в ответ на эту ошибку команда считает преждевременным.
Xray решил иначе. В [запросе на изменение #7291](https://github.com/XTLS/Xray-core/pull/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 встречаются нередко — например, [[xray/happ-problems|у Happ ядро Xray обновляется медленно]]. О том, чем ещё опасен открытый SOCKS-порт клиента, рассказано в заметке [[VLESS-SOCKS5-vulnerability|про неаутентифицированный SOCKS5 на localhost]].
**Обычные устройства, которые ничего не слушают.** Ошибка находится в коде, который принимает входящие подключения. Устройство, у которого нет открытых для сети TCP-портов, этим путём не атакуется, а Go по умолчанию включает MPTCP только для слушающих сокетов, не для исходящих. Это вывод из описания исправления, а не отдельное заявление разработчиков.
> [!warning] Версия: MPTCP как примета Go-серверов
> В том же комментарии RPRX мимоходом заметил, что неизвестно, не получил ли Великий китайский файрвол «бонус», и что REALITY, у которого MPTCP включён пассивно, по умолчанию выглядит ещё более странно. Возможное прочтение: [[xray/reality|REALITY]] выдаёт себя за чужой сайт, а настоящий сайт на nginx на предложение MPTCP отвечает обычным TCP. Сервер на Go 1.24+ отвечает согласием, и по этой разнице его можно отличить от маскировки. Это гипотеза из реплики разработчика, а не подтверждённый способ обнаружения; выключение MPTCP в v26.10.31 её снимает.
## Как проверить свой сервер
Сначала узнайте версию ядра командой `uname -r` и сравните её с исправленными версиями выше. Для ядер из дистрибутива надёжнее смотреть трекер безопасности самого дистрибутива, потому что исправление переносят в старые ветки под их собственными номерами. В [Debian исправление уже вышло](https://security-tracker.debian.org/tracker/CVE-2026-98432): `6.1.190-1` для bookworm и `6.12.113-1` для trixie. В [Ubuntu на 31 октября 2026 года](https://ubuntu.com/security/CVE-2026-98432) все поддерживаемые выпуски значатся уязвимыми, исправление «в работе». Red Hat, по данным The Hacker News на 30 октября, относит RHEL 8, 9 и 10 к затронутым, а исправленных ядер ещё не выпустил.
Дальше проверьте, включён ли MPTCP в системе и кто его слушает:
```bash
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.
## Что делать
![[mptcp-rce-defenses.png]]
- [ ] **Обновите ядро и перезагрузите сервер.** Это единственная мера, которая закрывает ошибку целиком, в том числе для обычного 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 предупредили](https://www.openwall.com/lists/oss-security/2026/10/30/6), что программы на Go, запущенные после изменения, переходят на обычный TCP без проблем, а уже работающие могут выдавать ошибки на новых подключениях.
- [ ] **Проверьте, что `net.ipv4.tcp_migrate_req` равен 0**, если не включали его сознательно.
- [ ] **Если исправленного ядра для вашего дистрибутива ещё нет**, [Red Hat предлагает правило nftables](https://access.redhat.com/security/vulnerabilities/RHSB-2026-016), которое отбрасывает входящие 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`.
> [!important] Вывод
> Выключенный MPTCP убирает путь, по которому root уже показан, и поэтому выпуск Xray v26.10.31 стоит поставить сразу. Но ошибка остаётся в общем коде IPv4 TCP, и, как подчёркивают и Go, и Red Hat, окончательно сервер защищает только исправленное ядро.
## Источники
- [XTLS/Xray-core, 31 октября 2026 — выпуск v26.10.31](https://github.com/XTLS/Xray-core/releases/tag/v26.10.31)
- [XTLS/Xray-core — PR #7291 «DefaultListener: Disable MPTCP by default»](https://github.com/XTLS/Xray-core/pull/7291)
- [XTLS/Xray-core — комментарий RPRX в PR #7291, 31 октября 2026](https://github.com/XTLS/Xray-core/pull/7291#issuecomment-6540309985)
- [NVD — CVE-2026-98432](https://nvd.nist.gov/vuln/detail/CVE-2026-98432)
- [Anthropic, 27 октября 2026 — Discovering vulnerabilities with Claude](https://www.anthropic.com/research/discovering-vulnerabilities-with-claude)
- [Black Triangle, Telegram — пересказ разбора Anthropic на русском](https://t.me/black_triangle_tg/9741)
- [The Hacker News — Linux Kernel TCP Flaw With 9.8 CVSS Score Affects Ubuntu, Red Hat and Other Distributions](https://thehackernews.com/2026/10/linux-kernel-tcp-flaw-with-98-cvss.html)
- [golang-announce, 30 октября 2026 — Protecting against CVE-2026-98432](https://groups.google.com/g/golang-announce/c/PCoQcdxoScw/m/aD-MgXEvAAAJ)
- [oss-security, 30 октября 2026 — пересылка заявления Go](https://www.openwall.com/lists/oss-security/2026/10/30/1)
- [oss-security, 30 октября 2026 — системное отключение MPTCP через sysctl](https://www.openwall.com/lists/oss-security/2026/10/30/6)
- [golang/go #82717 — proposal: net: Disable MPTCP by default](https://github.com/golang/go/issues/82717)
- [golang/go — коммит «net: enable multipath TCP by default for listeners»](https://github.com/golang/go/commit/3d4daa38a763260e07f4745110f2b5fcbec25126)
- [Red Hat — страница CVE-2026-98432](https://access.redhat.com/security/cve/cve-2026-98432)
- [Red Hat — бюллетень RHSB-2026-016 с правилом nftables](https://access.redhat.com/security/vulnerabilities/RHSB-2026-016)
- [Debian Security Tracker — CVE-2026-98432](https://security-tracker.debian.org/tracker/CVE-2026-98432)
- [Ubuntu Security — CVE-2026-98432](https://ubuntu.com/security/CVE-2026-98432)
## 📚 См. также
- [[xray/xray|Раздел Xray, VLESS и REALITY]] — обзор ядра Xray-core и его протоколов
- [[xray/reality|REALITY]] — как прокси выдаёт себя за чужой сайт и почему любая разница в поведении сервера важна
- [[xray/happ-problems|Чем плох Happ]] — в том числе почему клиенты с устаревшим ядром Xray опасны
- [[VLESS-SOCKS5-vulnerability|Уязвимость VLESS-клиентов: SOCKS5 на localhost]] — другой риск открытого порта на клиенте
- [[VLESS-localhost-protection-guide|Защита VPN-клиента от localhost-атаки]] — как закрыть входящие порты клиента
---
> [!quote] 🤖 Эти статьи открыты — можно обучать на них ИИ
> При желании вы можете натренировать ИИ на наших статьях. Исходное форматирование доступно в Forgejo: [исходник этой заметки](https://cwdnvtsqdc.zapret.moe/zapretdiscordyoutube/todo/src/branch/main/xray/mptcp-linux-kernel-rce-cve-2026-98432.md) · [скачать весь репозиторий одним zip-архивом](https://cwdnvtsqdc.zapret.moe/zapretdiscordyoutube/todo/archive/main.zip).