Сергей Попов
Администратор
- 30.12.2015
- 6 264
- 6 980
- Специализация
- OSINT
- Веб-безопасность
- Статус верификации
- ✓ Verified
CVSS 9.1, сетевой вектор, ноль привилегий, ноль взаимодействия пользователя - CVE-2025-68670 в xrdp набрала характеристики, которые CISA Vulnrichment определяет как автоматизируемую эксплуатацию с полным техническим импактом. Нашли её исследователи Kaspersky - Денис Скворцов и Дмитрий Шмойлов - при аудите Kaspersky USB Redirector, модуля для проброса USB через xrdp-сессии. Искали баг в модуле, а нашли в самом сервере: переполнение стекового буфера в функции
xrdp_wm_parse_domain_information, которая вызывается до аутентификации клиента. Любой хост с xrdp и открытым TCP/3389 - потенциальная мишень. Активной эксплуатации пока нет (CISA KEV: отсутствует, SSVC-решение: Track), но EPSS-скор 0.0132 с перцентилем 68.37% ставит уязвимость выше медианы по вероятности эксплуатации в ближайшие 30 дней. Патчи уже есть - v0.10.5 и бэкпорты в 0.9.27 / 0.10.4.1. Дальше разберём root cause до уровня отдельных байтов, предусловия эксплуатации, индикаторы для детекта и пошаговую митигацию.Зачем злоумышленнику pre-auth RCE в xrdp
xrdp - доминирующая реализация RDP-сервера с открытым исходным кодом для Linux. В отличие от Windows, где RDP встроен в систему, Linux для графического удалённого доступа требует отдельного сервера, и xrdp стоит в дефолтных репозиториях Debian, Ubuntu, Fedora, RHEL и большинства корпоративных дистрибутивов. Типичные сценарии - VDI на Linux, тонкие клиенты (Kaspersky Thin Client, тиражные терминальные решения), рабочие станции разработчиков, лабораторные и учебные среды.Pre-auth RCE в таком сервисе - идеальная точка Initial Access по MITRE ATT&CK (T1190, Exploit Public-Facing Application). Атакующему не нужны ни учётные данные, ни токен сессии, ни предварительный доступ к сети - хватит TCP-подключения к порту 3389. Если xrdp торчит в интернет (managed service providers, dev-стенды, образовательные учреждения), атаку масштабируют сканером без ручного участия. После получения shell на xrdp-сервере - стандартный сценарий: закрепление, сбор учётных данных PAM/sesman, боковое перемещение по внутренней сети. Для организаций, где xrdp стоит на jump-хостах или системах администрирования, компрометация - это прямой доступ ко всей управляемой инфраструктуре.
Root Cause: переполнение стекового буфера в xrdp
Как доменное имя попадает на сервер
Установка RDP-соединения включает этап Secure Settings Exchange - обмен настройками до аутентификации клиента. Клиент отправляет серверу Client Info PDU со структурой TS_INFO_PACKET: имя пользователя, пароль, доменное имя, cookie автоматического переподключения. Строки кодируются в UTF-16 (до 512 байт, включая нулевой терминатор). На серверной стороне xrdp конвертирует полученные данные из UTF-16 в UTF-8 - за это отвечает функцияts_info_utf16_in.Размер буфера для распаковки доменного имени в UTF-8 (512 байт) передаётся в
ts_info_utf16_in, где реализована проверка границ при конвертации. in_utf16_le_fixed_as_utf8_proc выполняет собственно преобразование с контролем записанных байтов и нулевого терминатора. На выходе - до 512 байт UTF-8 в поле domain структуры xrdp_client_info. На этом этапе проверки работают корректно.Где ломается проверка
Уязвимость сидит в функцииxrdp_wm_parse_domain_information. Она получает доменное имя (до 512 байт UTF-8) первым аргументом и пытается записать его часть в буфер resultIP размером 256 байт. По данным исследования Kaspersky (Securelist), логика такая:- Если первый символ доменного имени - подчёркивание (
[I]), функция копирует данные от второго символа до двойного подчёркивания (_[/I]) в буферresultIP. - Проверка длины копируемых данных отсутствует: доменное имя может содержать до 512 байт между маркерами
[I]и_[/I], а целевой буфер вмещает только 256. - «Лишние» байты записываются за пределы буфера на стек потока, перезаписывая адрес возврата.
Нюанс с кодировками: атакующему нужно, чтобы UTF-8-представление доменного имени содержало более 256 байт между
[I] и _[/I], при этом UTF-16-представление не превышало 512 байт. Это достигается подбором символов, которые занимают мало места в UTF-16, но расширяются при конвертации в UTF-8. В PoC от Kaspersky использовались кириллические символы К (U+041A) в нужном количестве для перезаписи адреса возврата строкой «AAAAAAAA». PoC оформлен как .rdp-файл с IP-адресом целевого сервера и сконструированным доменным именем - при открытии mstsc.exe подключается к серверу и передаёт вредоносный Client Info PDU.Вся цепочка - от получения Client Info PDU до вызова
xrdp_wm_parse_domain_information - выполняется до аутентификации клиента. Это подтверждено стеком вызовов, опубликованным исследователями. Не нужен ни логин, ни пароль - просто TCP-коннект и правильно собранный PDU.Предусловия и ограничения эксплуатации CVE-2025-68670
Работает если
- xrdp версии ниже 0.10.5 (или без бэкпортированного патча 0.9.27 / 0.10.4.1)
- TCP/3389 доступен атакующему - из интернета или из внутренней сети
- Подключение доходит до этапа Secure Settings Exchange (Client Info PDU)
- Доменное имя в Client Info PDU начинается с
[I], содержит_[/I], между маркерами - более 256 байт UTF-8 - Бинарник xrdp собран без стековой канарейки или значение канарейки известно атакующему
Не работает если
Stack canary (стековая канарейка). Большинство современных компиляторов (gcc, clang) по умолчанию включают-fstack-protector или -fstack-protector-strong. При активной канарейке перед адресом возврата на стеке лежит случайное значение, которое проверяется при возврате из функции. В PoC от Kaspersky xrdp падал именно на проверке канарейки (SIGABRT через gdb) - тривиальная перезапись адреса возврата и запуск ROP-цепочки не проходят.Но - и это подчёркивают сами мейнтейнеры xrdp в бюллетене GHSA-rwvg-gp87-gh6f - стековая канарейка не абсолютная защита. Значение канарейки можно утечь через information disclosure или подобрать при fork-based brute force, если серверный процесс рестартится systemd без полного перезапуска (канарейка не обновляется между fork'ами). Это не теоретическая атака - на серверах, где systemd поднимает упавший xrdp за секунду, перебор канарейки вполне реалистичен.
ASLR и PIE. Address Space Layout Randomization усложняет предсказание адресов для ROP-гаджетов. Если xrdp собран с PIE (Position Independent Executable), адресное пространство рандомизируется при каждом запуске. Для успешной эксплуатации потребуется дополнительный примитив для утечки адреса - порог входа заметно растёт.
Сетевые ограничения. Если xrdp недоступен из недоверенных сетей (VPN, SSH-туннель, файрвол с whitelist), поверхность атаки сокращается до внутреннего злоумышленника.
Контекст CVSS. NVD оценивает CVE-2025-68670 в 9.1 (Critical) по CVSS v3.1 с вектором
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H. Компонент Confidentiality = None (C:N). Ряд источников, включая advisory GitHub GHSA-rwvg-gp87-gh6f, приводят оценку 9.8 с C:H - разница критична для автоматической приоритизации в vulnerability management. По NVD, непосредственный импакт затрагивает целостность (I:H - перезапись памяти, редирект исполнения) и доступность (A:H - крэш процесса), без прямого влияния на конфиденциальность. После достижения произвольного выполнения кода атакующий обеспечит доступ к данным самостоятельно, но CVSS оценивает непосредственный эффект эксплуатации.Место CVE-2025-68670 в цепочке атаки
Эксплуатация CVE-2025-68670 - это T1190 по MITRE ATT&CK (Exploit Public-Facing Application), тактика Initial Access. Первый шаг в цепочке, дающий атакующему исполнение кода на удалённом хосте без предварительного доступа.Что дальше после получения shell:
- Закрепление (Persistence): модификация PAM-модулей, добавление cron-задач, SSH-ключей. Процесс xrdp запускается от root или от пользователя xrdp с потенциалом для privilege escalation через SUID-бинарники и уязвимости ядра.
- Сбор учётных данных: конфигурация xrdp-sesman (
/etc/xrdp/sesman.ini), PAM-стек, SSH-ключи, history-файлы, переменные окружения с токенами. - Боковое перемещение: если скомпрометированный xrdp-сервер - jump-хост или имеет доступ к внутренним подсетям, пивотирование через SSH, RDP-подключения или эксплуатацию других сервисов.
По D3FEND (MITRE), рекомендованные контрмеры против T1190: Network Traffic Signature Analysis (D3-NTSA), Inbound Session Volume Analysis (D3-ISVA), Segment Address Offset Randomization (D3-SAOR) и Application Protocol Command Analysis (D3-APCA). Реализация - ниже.
Детектирование xrdp уязвимости RCE: индикаторы в логах и трафике
Логи xrdp
Основные файлы -/var/log/xrdp.log и /var/log/xrdp-sesman.log. На что смотреть:Частые крэши процесса xrdp (stack canary violation). При активной канарейке неудачные попытки эксплуатации завершаются SIGABRT. Проверка:
journalctl -u xrdp --since "1 hour ago" | grep -iE "terminated|signal|abort|segfault". Несколько аварийных завершений за короткий период - высокоприоритетный IoC. Если видите пачку SIGABRT за минуту - кто-то ломится.Всплеск pre-auth подключений без последующей аутентификации. Соединения обрываются на этапе Secure Settings Exchange - в логах видны записи о коннекте без login.
Аномальные значения в полях домена. При уровне
LOG_LEVEL=DEBUG в /etc/xrdp/xrdp.ini появляются детали парсинга Client Info PDU, включая содержимое доменного имени. Длинные строки с символами подчёркивания в начале - явный признак.Сетевой уровень: Suricata и Zeek
На уровне IDS/IPS задача - обнаружить аномальный RDP-хэндшейк с нестандартно длинным доменным именем в Client Info PDU. Публичных Suricata-правил для CVE-2025-68670 на момент написания нет, но принцип построения сигнатуры: RDP-трафик на TCP/3389, этап Secure Settings Exchange, размер поля domain в TS_INFO_PACKET превышает 256 байт после декодирования. В Zeek - мониторингrdp.log с контролем длины полей и корреляция с рестартами серверного процесса.SIEM-правила
В корреляции отслеживать комбинацию: множественные подключения к TCP/3389 с одного IP + отсутствие успешной аутентификации + рестарт или крэш процесса xrdp в пределах минуты. Этот паттерн характерен как для brute-force канарейки, так и для прямых попыток эксплуатации. Для D3-ISVA (Inbound Session Volume Analysis) - порог на количество новых RDP-сессий с одного источника за единицу времени, с немедленным алертом при превышении. Если такое прилетит в 3 ночи дежурному - вот готовый чеклист: проверить версию xrdp на целевом хосте, изолировать порт, снять дамп процесса до рестарта.Патчинг и митигация xrdp RCE: пошаговый план
📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме
4. Проверить доступность извне
nmap -Pn -p 3389 <внешний-IP> с внешнего хоста. Если порт открыт и патч не применён - изолировать немедленно.5. Верифицировать компиляцию с canary
Bash:
checksec --file=$(which xrdp) | grep -i canary
Canary found. Если No canary found - бинарник собран без -fstack-protector, и это критически снижает порог эксплуатации. Пересоберите с флагами: CFLAGS="-fstack-protector-strong".Приоритизация
Хосты с xrdp, доступным из интернета - патч или изоляция в течение 24 часов. Внутренние хосты - в рамках ближайшего планового окна. Хосты с отключённым stack canary - немедленно, вне зависимости от сетевой доступности.Ряд источников приводит для CVE-2025-68670 оценку CVSS 9.8, расходящуюся с NVD-оценкой 9.1. Разница - в компоненте Confidentiality: NVD выставляет C:N, advisory GitHub GHSA-rwvg-gp87-gh6f - C:H. На практике это влияет на автоматическую приоритизацию: если ваш vulnerability management тянет скоры из NVD, уязвимость может оказаться ниже в очереди, чем заслуживает. Мой подход: для pre-auth RCE в сетевом сервисе числовое значение CVSS - формальность. Даже 9.1 с C:N означает полный контроль над процессом xrdp, а от shell до root - вопрос нескольких команд. Реальные критерии приоритизации - доступен ли порт 3389 из недоверенной сети и есть ли stack canary на бинарнике.
Про канарейку - отдельная мысль. Мейнтейнеры xrdp прямо предупреждают: не полагайтесь исключительно на stack canary. На подавляющем большинстве продовых инсталляций канарейка - единственная линия между переполнением и произвольным исполнением кода. ASLR и PIE помогают, но fork-based brute force на сервере, который systemd поднимает после краша, - реалистичный сценарий. Патч - единственная надёжная мера, всё остальное - покупка времени. Если у вас другой стек детекции - на форуме codeby.net обсуждают адаптацию правил обнаружения под конкретные SIEM и IDS.