Уязвимость в протоколе REALITY XTLS/Xray-core: быстрый фикс уязвимости Aparecium
На прошлой неделе была обнаружена уязвимость в известном ПО для создания прокси соединений XTLS/Xray-core, а именно в протоколе REALITY, позволяющая выявлять работу этого протокола.
Для тех, кто не в курсе: REALITY — это уникальный протокол прокси, который позволяет маскировать прокси-трафик под легитимное посещение реальных сайтов (например, google.com
или любого другого), при этом не требуя покупки домена и настройки TLS-сертификата на своем сервере.
Обнаружение уязвимости
В начале июня 2025 года исследователь под ником ban6cat6 опубликовал утилиту под названием Aparecium. Ее цель — находить серверы, использующие протоколы вроде REALITY.
В чем была суть уязвимости?
Утилита обнаружила, что серверы на базе OpenSSL после завершения основного TLS-рукопожатия (handshake) обычно отправляют клиенту один или два служебных сообщения NewSessionTicket
. Это стандартное поведение, позволяющее возобновлять сессии. Протокол REALITY в своей реализации это поведение не имитировал.
Это тонкое различие позволяло Aparecium с высокой точностью отличать настоящий веб-сервер от сервера с REALITY, просто проанализировав последовательность TLS-сообщений.
Быстрый фикс
Информация об уязвимости была опубликована в виде issue #4778 в репозитории Xray-core. Разработчики, в частности RPRX, отреагировали практически молниеносно.
Вместо того чтобы добавить отправку фейковых NewSessionTicket
, они пошли по более правильному пути. Уже через несколько дней в версии Xray-core v25.6.8 появилось «предварительное» решение:
Теперь при первом запуске сервер REALITY, используя отпечаток клиента Chrome, сам подключается к целевому сайту (
dest
), «подсматривает», какие именно post-handshake сообщения и какой длины тот отправляет, кэширует эту информацию и в дальнейшем идеально имитирует именно это поведение.
На это «зондирование» уходит около 30 секунд при первом старте сервера, но оно по большей части решает основную проблему. Вместе с этим был исправлен и неприятный баг с производительностью из-за неработающего аппаратного ускорения AES-NI.
Глубокий анализ
Казалось бы, проблема решена, однако разработчики начали копать глубже, и вот что выяснилось:
Загадка «лишнего пакета» от
bilibili.com
Один из разработчиков заметил, что при подключении к некоторым сайтам (например,bilibili.com
) с отпечатком Chrome, сервер возвращает не толькоNewSessionTicket
, но и еще один небольшой пакет. После анализа выяснилось, что это не TLS-сообщение, а кадр настроек HTTP/2 (settings frame). Это значит, что для идеальной маскировки нужно имитировать не только TLS-уровень, но и поведение прикладного протокола (HTTP/2), который был согласован в ходе рукопожатия.Проблема разных отпечатков (
fingerprints
)
Выяснилось, что один и тот же сайт может по-разному отвечать наClientHello
от разных клиентов. Например, на запрос с отпечатком Chrome он может отправить дваNewSessionTicket
иsettings
фрейм, а на запрос от Go-клиента — только одинNewSessionTicket
. Похоже, что статического зондирования недостаточно.Идея «живого обучения»
В ходе мозгового штурма родилась идея для долгосрочного решения, которое было оформлено в issue #4788. Суть в том, чтобы сервер REALITY, получивClientHello
от нового клиента, не просто использовал стандартный отпечаток для зондирования, а копировал отпечаток реального клиента и именно с ним обращался к целевому сайту. Это позволит динамически адаптироваться под любого клиента и достичь практически идеальной мимикрии.
Разработчики рекомендуют всем обновить сервера и клиенты, использующие Xray-core, до версии 25.6.8.