Вредоносный скрипт в системе поддержки Udesk собирал сессионные данные и подменял адреса пополнения

Вредоносный скрипт в системе поддержки Udesk собирал сессионные данные и подменял адреса пополнения

В скриптах системы поддержки Udesk обнаружен посторонний код, который доставляет в страницу вторую полезную нагрузку. Она читает cookie, веб-хранилища и содержимое отправляемых форм, а на страницах пополнения подменяет адрес получателя и текст в буфере обмена. Разбор двух полученных образцов показал, как код попадает в документ и от чего зависит работа его модулей. Данных о состоявшемся переводе средств на подменённый адрес в опубликованном описании нет.

Описание

Первый образец повторяет обычный скрипт интерфейса поддержки: кнопка обращения, окно чата во встроенном фрейме, отслеживание посетителя, обмен сообщениями. После основного блока в файле остаётся отдельная функция. Она собирает имя тега и адрес удалённого файла из двух строк, закодированных парами шестнадцатеричных символов, создаёт элемент script, включает асинхронное выполнение и добавляет элемент в head документа. Браузерные политики и состояние сети решают, попадёт ли внешний код в текущий документ.

В открытом виде имя тега и адрес в коде не встречаются. Поиск только по текстовому написанию домена точку входа не находит, это подтверждено разбором функции декодирования. Домен во второй строке построен на слове global с заменой первой буквы на q, и это написание сохраняют при проверке.

Вторая нагрузка выполняется в контексте той страницы, которая её загрузила; встроенный фрейм чата сам по себе внешний скрипт не изолирует. Специалисты SlowMist установили, что обработчики форм и запросов ставятся раньше проверки адресных правил, поэтому сбор данных не ограничен списком сайтов. На старте нагрузка читает cookie, локальное и сессионное хранилище браузера, адрес страницы верхнего уровня и источник текущего документа. Чтение cookie ограничено тем, что доступно скрипту страницы; cookie с признаком HttpOnly в выборку не попадают.

Отдельный путь сбора связан с формами. При отправке перебираются поля ввода, выпадающие списки и многострочные поля, непустые значения копируются, а исходная отправка продолжается. Для страниц, которые передают данные программными запросами, перехватываются два браузерных способа отправки. Тело запроса копируется, если адрес содержит слова login, signin, auth, register, signup или password. В ветке с функцией выборки (fetch) содержимое берётся из параметров запроса, и при сериализации объектов часть полей может в отправку не попасть.

Все точки сбора вызывают общую функцию отправки. Она отделяет параметры после вопросительного знака и передаёт их асинхронным POST-запросом с типом содержимого формы. При ошибке запроса или синхронном исключении создаётся объект изображения, и те же параметры уходят методом GET. Адрес в этом случае обрезается до первых 8000 символов, поэтому длинные данные могут дойти не полностью. Ответ сервера приёма скрипт не читает, так что ошибка политики кросс-доменных запросов (CORS) и состоявшаяся отправка возможны одновременно.

После проверки адресных правил нагрузка входит в модуль подмены. Правила заданы регулярными выражениями без привязки к началу и концу строки, поэтому совпадение выходит шире точного сравнения домена, а полный адрес страницы проверяется вместе с параметрами и фрагментом. На трёх сайтах скрипт находит элементы адреса и кнопки копирования, каждые 200 миллисекунд просматривает страницу и заменяет распознанные адреса пополнения на шесть заданных значений, помеченных как BTC, EVM, TRON, Solana, LTC и DOGE. Сеть и контрольная сумма адреса не проверяются, поэтому служебные строки тоже могут распознаваться как адрес.

Копирование перехватывается тремя независимыми путями. Обёртка над программным интерфейсом буфера обмена подменяет аргумент перед вызовом исходного метода и зависит только от правила домена. Клонированные кнопки копирования получают новый обработчик, который отменяет действие по умолчанию и записывает последний заменённый адрес. Обработчик события копирования на документе подменяет содержимое при совпадении с адресными правилами, не проверяя, что выделен именно адрес. Из-за общего хранилища последнего адреса несколько кнопок на одной странице могут копировать одно и то же значение.

Отмечен и дефект реализации: скрипт запрашивает описание свойства текста у одного встроенного объекта браузера, тогда как стандарт определяет это свойство на другом. Возникающее исключение перехватывается молча, но не прерывает ни опрос страницы, ни установку обработчиков буфера обмена. Описанные признаки не показывают, выполнялся ли код на конкретной странице и какие сведения дошли до сервера приёма. Не установлено и то, что подмена адреса привела к переводу средств.

Индикаторы компрометации

Комментарии: 0