Сергей Попов

Администратор
30.12.2015
6 264
6 980
Специализация
  1. OSINT
  2. Веб-безопасность
Статус верификации
  1. ✓ Verified
Крупный план платы xrdp-сервера на антистатическом коврике: обугленная дорожка тянется от повреждённого чипа к разъёму RJ-45 с портом 3389, лазерная гравировка на текстолите называет уязвимость пер...


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), логика такая:
  1. Если первый символ доменного имени - подчёркивание ([I]), функция копирует данные от второго символа до двойного подчёркивания (_[/I]) в буфер resultIP.
  2. Проверка длины копируемых данных отсутствует: доменное имя может содержать до 512 байт между маркерами [I] и _[/I], а целевой буфер вмещает только 256.
  3. «Лишние» байты записываются за пределы буфера на стек потока, перезаписывая адрес возврата.
Классическое сочетание CWE-121 (Stack-based Buffer Overflow) и CWE-787 (Out-of-bounds Write). Программа пишет данные за границу стекового буфера, модифицируя содержимое стека включая return address. Если атакующий формирует доменное имя так, что после переполнения адрес возврата содержит подконтрольное значение - поток исполнения при выходе из функции перенаправляется на произвольный код в контексте процесса xrdp-сервера.

Нюанс с кодировками: атакующему нужно, чтобы 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:
  1. Закрепление (Persistence): модификация PAM-модулей, добавление cron-задач, SSH-ключей. Процесс xrdp запускается от root или от пользователя xrdp с потенциалом для privilege escalation через SUID-бинарники и уязвимости ядра.
  2. Сбор учётных данных: конфигурация xrdp-sesman (/etc/xrdp/sesman.ini), PAM-стек, SSH-ключи, history-файлы, переменные окружения с токенами.
  3. Боковое перемещение: если скомпрометированный xrdp-сервер - jump-хост или имеет доступ к внутренним подсетям, пивотирование через SSH, RDP-подключения или эксплуатацию других сервисов.
Для внутреннего пентеста, когда xrdp используется для управления серверами внутри периметра, эксплуатация ближе к T1210 (Exploitation of Remote Services) - атакующий уже внутри сети и использует уязвимость для lateral movement.

По 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.
 
Мы в соцсетях:

Взломай свой первый сервер и прокачай скилл — Начни игру на HackerLab

Похожие темы

🚀 Первый раз на Codeby?
Гайд для новичков: что делать в первые 15 минут, ключевые разделы, правила
Начать здесь →
🧭 Навигатор · ИБ 2026
Не знаешь, какой трек твой?
5 направлений ИБ, реальные зарплаты и точка входа для каждого — в одном треде.
JuniorSenior+
100K → 600K+ ₽ /мес
Открыть навигатор →
🔴 Свежие CVE, 0-day и инциденты
То, о чём ChatGPT ещё не знает — обсуждаем в реальном времени
Threat Intel →
💼 Вакансии и заказы в ИБ
Pentest, SOC, DevSecOps, bug bounty — работа и проекты от проверенных компаний
Карьера в ИБ →

HackerLab