SlowMist: Зловредный JS Udesk крадет данные и изменяет адреса переводов

iconMetaEra
Поделиться
AI summary iconСводка
SlowMist обнаружил вредоносный JS-скрипт в системе Udesk, связанный с ончейн-новостями о скомпрометированных платформах, таких как mgbx.com и bitxex.io. Скрипт, загружаемый через udeskApi.2026-10-16.cached.js и deeps.js, крадет данные сессии и изменяет адреса пополнения. Злоумышленники используют удалённый загрузчик для внедрения кода, что создает риск кражи средств. Данные по инфляции и волатильность рынка могут усилить потери для пострадавших пользователей. Взлом подчеркивает срочные проблемы безопасности на нескольких биржах.
Как с помощью одной атаки скрипта одновременно атаковать пользовательские данные и переводы средств?

Автор статьи, источник: Slow Mist Tech

Контекст

Недавно сотрудники безопасности SlowMist при ежедневном анализе угроз обнаружили атаку, связанную с отравлением скриптов, связанных с системой поддержки Udesk. Команда получила два JavaScript-образца — udeskApi.2026-10-16.cached.js и deeps.js — и провела анализ, чтобы выяснить, как вредоносный код проникает на страницы через скрипты поддержки, а также какие действия он выполняет с данными пользователей и бизнес-операциями.

Проверка образца поэтапно выявила два типа рисков: вредоносный скрипт одновременно собирает данные сессий и чувствительную информацию, введенную пользователями на веб-странице, и изменяет адреса пополнения и копирует содержимое в соответствии с правилами сайта. Первый тип может позволить злоумышленнику имитировать сессию входа или взять контроль над учетной записью, а второй — заставить пользователя перевести средства пополнения на замененный адрес получения. Мы начали с точки загрузки скрипта службы поддержки, проследили за логикой чтения данных, отправки по сети и изменения страницы, чтобы восстановить способы реализации и условия активации этих двух типов поведения.

MistEye ответ

MistEye — это веб-3-система разведки угроз и динамического мониторинга безопасности, разработанная SlowMist, которая объединяет возможности мониторинга безопасности и агрегации интеллектуальных данных для предоставления пользователям оперативных предупреждений о рисках и защиты активов.

MistEye немедленно синхронизировала риски через каналы информирования и оповещения клиентов.

Вредоносный загрузчик и механизм загрузки удаленного полезного груза

После открытия udeskApi.2026-10-16.cached.js можно увидеть код функций, таких как кнопка службы поддержки, iframe чата, отслеживание посетителей и передача сообщений. Продолжив проверку конца файла, после основного кода обнаруживается отдельная функция: она декодирует две строки с помощью _ud(), создает элементы и вставляет их в head текущего документа.

Этот фрагмент не содержит явно указанных меток и удаленных URL. Если искать только доменные имена в открытом виде, точка загрузки может быть пропущена. Прослеживая реализацию _ud(), мы обнаружили, что она каждый раз извлекает два шестнадцатеричных символа и преобразует их в символы; после раскрытия констант цель загрузки становится очевидной.

736372697074 декодируется как script, другая константа декодируется как https[:]//udeskqlobal[.]com/deeps.js. Доменное имя содержит qlobal, начинающееся с буквы q, и при поиске эта орфография должна сохраняться. Загрузчик устанавливает сценарий как асинхронный, а затем вставляет его на страницу; когда достигается эта точка и политика браузера и сеть позволяют, удаленный код может быть выполнен в текущем документе.

Полезная нагрузка, соответствующая этому URL, — deeps.js. Фокус расследования сместился с SDK службы поддержки на саму полезную нагрузку. Классический сторонний скрипт выполняется в контексте встроенного документа, и доступные ему данные зависят от страницы или iframe, на которых он фактически запущен. Окно чата службы поддержки использует iframe и не изолирует автоматически скрипты, загруженные на хостовой странице.

Механизм сбора данных с веб-сайта и область воздействия

deeps.js сначала считывает window.location.hostname и генерирует конфигурацию C по правилам трех сайтов. Чтобы определить, какие страницы будут собираться, этой конфигурации недостаточно: необходимо выяснить, ограничивает ли она весь скрипт или только определенный модуль, и продолжить отслеживание места выхода.

При проверке вдоль потока управления мы видим, что чтение файлов cookie и веб-хранилища, отправка снимка запуска, а также хуки форм и запросов аутентификации находятся до if (!C) return;. Ниже приведены операторы отправки снимка и XHR-хук в конце по порядку исходного кода; комментарии указывают на пропущенный код, соответствующий форматированному представлению D:L100, D:L151–L166.

Место выхода определило область влияния: даже если hostname не совпадает с правилами трех сайтов, скрипт сначала войдет в путь сбора данных и установит хуки, а затем выйдет из модуля адресов. При поиске раскрытых страниц нельзя ограничиваться только поиском по конфигурациям этих трех сайтов.

При запуске нагрузка считывает Cookie, localStorage и sessionStorage, доступные на текущей веб-странице. Эти места могут хранить информацию о состоянии входа, профиле пользователя и бизнес-данных; если среди них содержатся еще действующие и повторно используемые маркеры входа, злоумышленник, получив их, может использовать сеанс пользователя. Скрипт также включает URL верхнего уровня страницы и origin текущего документа, чтобы эти данные отправлялись вместе с исходной страницей.

Процесс сбора данных реализован с поэлементной устойчивостью к ошибкам. При неудачной попытке чтения верхнего URL из другого источника скрипт заменяет его на x и продолжает обработку других полей; два типа веб-страниц сохраняются в виде сериализованного JSON. Область действия куки ограничена содержимым, доступным через document.cookie; HttpOnly-куки не включаются.

Скрипт также сохраняет точки входа для данных, отправляемых позже. При отправке формы он перебирает элементы input, select и textarea, копирует непустое содержимое и продолжает исходный процесс отправки. Поля, фактически заполненные пользователем, такие как имя пользователя, пароль, капча и т.д., могут попасть в дополнительный путь отправки данных, и их утечка может быть использована для входа в аккаунт или его захвата.

Этот путь реализован путем обертывания HTMLFormElement.prototype.submit и прослушивания событий submit на этапе захвата. Для страниц, которые отправляют данные напрямую через интерфейс, скрипт также обертывает fetch и XHR: когда запрос содержит тело и URL содержит ключевые слова, такие как login|signin|auth|register|signup|password, копируется соответствующее содержимое с сохранением исходного вызова запроса. В ветке fetch дополнительно требуется, чтобы URL был строкой, а тело — из параметров запроса; при прямой сериализации в JSON объектов, таких как FormData, собранные данные могут содержать недостающие поля.

Механизм передачи данных и резервный канал

Вышеуказанный входной пункт сбора в конечном итоге вызывает одну и ту же функцию _send(). При дальнейшем отслеживании этой функции видно, что фиксированный получатель — https[:]//udeskqlobal[.]com/c.php. Снимок запуска использует поля s, o, c, l, ss для передачи адреса страницы, текущего источника, читаемых файлов cookie и двух типов веб-хранилищ; последующие запросы форм и аутентификации отправляются при их соответствующем срабатывании.

Функция извлекает параметры после знака вопроса в URL и помещает их в тело асинхронного POST-запроса, устанавливая Content-Type: application/x-www-form-urlencoded. Ниже полностью сохранена функция отправки (D:L45–L60):

Путь отправки также включает резервный запрос изображения: при ошибке XHR или синхронном сбое в процессе отправки скрипт создает объект Image, присваивая параметризованному URL атрибут src, чтобы попытаться снова передать данные через GET. URL обрезается до первых 8000 JavaScript-символов, и более длинное содержимое может быть неполным.

При понимании этого пути необходимо различать «отправку запроса» и «чтение ответа». Скрипт не читает ответ c.php; межсайтовый POST-запрос, соответствующий условиям простого запроса, может быть отправлен первым, а чтение ответа ограничивается браузером, поэтому ошибка CORS может возникнуть одновременно с отправкой запроса. При проверке следует одновременно анализировать тело POST-запроса и параметры GET изображения, а политика выхода должна отдельно проверять connect-src и img-src. Обычная форма, вызывающая навигацию документа, также может повлиять на возможность завершения асинхронного запроса.

Теперь стало ясно, куда направляются данные веб-сессии и последующие отправляемые данные. Однако после проверки выхода с сайта нагрузка сохраняет еще одну группу операций: определение формата адреса, изменение текста на странице и перехват пути копирования. Этот код дополнительно направляет расследование на бизнес по пополнению.

Замена адреса пополнения и механизм перехвата буфера обмена

После if (!C) return; скрипт переходит в модуль адресов. Первые три правила hostname теперь имеют четкое назначение: сопоставление mgbx[.]com, bikingex[.] и bitxex[.]io для выбора селекторов элементов адреса и кнопки копирования на разных страницах.

Эти регулярные выражения не содержат якорей в начале и конце, поэтому диапазон совпадения шире, чем при точном сравнении доменных имен. Правила страницы также проверяют полный location.href, и ключевые слова, такие как deposit, recharge, assets, в параметрах запроса или фрагментах также учитываются при определении. После совпадения с форматом страницы, элемента или адреса скрипт сканирует каждые 200 миллисекунд и заменяет обнаруженные адреса депозита на значения из конфигурации. Если пользователь совершит действительный перевод на заменённый адрес, получатель станет этим адресом.

Три ветки сайта используют шесть общих конфигурационных значений, обозначенных в коде как BTC, EVM, TRON, Solana, LTC и DOGE. Идентификация адресов основывается исключительно на форме символов и порядке совпадения, без проверки выбранной пользователем сети или контрольной суммы адреса, что также может привести к ошибочной идентификации обычных бизнес-идентификаторов.

Продолжайте проверять скопированный код, можно увидеть, что образец одновременно вмешивается в отображение страницы и содержимое буфера обмена. Таким образом, даже если пользователь сравнивает адрес страницы с результатом копирования, он может получить согласованные измененные значения. Три пути:

  • Обертка API буфера обмена. navigator.clipboard.writeText сначала вызывает R() для замены параметров, а затем передает управление исходному методу. Этот путь ограничен только настройкой hostname, повторная проверка условий страницы пополнения не выполняется и не зависит от сканирования DOM для уже найденных элементов.
  • Заменить кнопку копирования. Скрипт клонирует найденную кнопку, устанавливает новый слушатель клика и заменяет исходный узел. Новый слушатель блокирует действие по умолчанию и распространение события, пытаясь скопировать адрес, сохраненный в общей переменной _cur.
  • Перехват события копирования. Когда _cur не пуст и выполняется правило страницы, слушатель на document заменяет копируемый контент на _cur, не проверяя, является ли выделенный пользователем текст адресом.

При этом API буфера обмена и слушатель copy расположены рядом в исходном коде (D:L260–L275), но имеют разные условия срабатывания:

_cur сохраняет последний фактически заменённый адрес. При наличии нескольких адресов на экране последняя замена перезаписывает предыдущую запись; несколько кнопок могут копировать одно и то же значение. Если при загрузке страницы уже отображается конфигурационный адрес, сканирование не инициализирует _cur, и добавленные слушатели событий для кнопок не записывают содержимое; клонированные встроенные атрибуты событий HTML по-прежнему участвуют в обработке событий.

В ходе анализа также была обнаружена реализационная ошибка, влияющая на определение поведения: скрипт пытается прочитать дескриптор собственного свойства textContent из Element.prototype, тогда как стандартное определение свойства находится в Node.prototype. В стандартной иерархии прототипов последующий доступ к .set вызывает исключение. После неудачи в этом участке кода исключение перехватывается и подавляется; при дальнейшем анализе кода до и после этого участка видно, что опрос уже зарегистрирован, и последующие хуки копирования будут установлены в соответствии со своими условиями. Ошибка в одном участке не привела к остановке модуля перехвата адресов.

Сводка

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

Бизнес, который все еще загружает соответствующие скрипты, должен прекратить дальнейшее распространение, устранить раскрытые учетные данные и проверить цели пополнения через надежную административную панель и записи транзакций.

Рекомендации

  1. Обеспечьте безопасность и прекратите распространение заражённых ресурсов. Если производство всё ещё загружает соответствующие скрипты, немедленно заблокируйте их после сохранения фактического ответа, цепочки инициации запроса, информации о кэше и времени сбора; восстановите систему из надёжной версии, проверенной независимо, и проверьте конфигурацию хостинга сайта, CDN, сборки и управления тегами.
  2. Проверка загрузки и внедренных записей. Совместный запрос вредоносных доменов, двух путей и хешей файлов; внедренные записи проверяют как тело POST, так и GET-параметры. При анализе сжатых скриптов также ищите шестнадцатеричные URL в загрузчиках, чтобы избежать пропуска зашифрованных данных при поиске только в открытом виде.
  3. Завершите загрязненный документ и утилизируйте скомпрометированные учетные данные. Полностью закройте соответствующие страницы или документы WebView, чтобы избежать повторной загрузки старых ресурсов. В зависимости от фактического масштаба утечки, отмените сессии, смените токены и пароли в чистой среде; удаление тегов script не отменяет уже установленные хуки и таймеры.
  4. Самостоятельно проверьте адрес пополнения и транзакцию. Для страницы, выполняющей нагрузку, проверьте исходный адрес пополнения, связанную транзакцию и фактическую цель перевода через надежные каналы, оценив влияние на основе записи транзакций.
  5. Проверка скриптов и ограничения экспорта данных. В соответствии с бизнес-настройками проверьте источники и контроль целостности скриптов, включая политики connect-src, img-src и другие, ограничивая загрузку скриптов и передачу данных для udeskqlobal[.]com.

IOC

Домен

udeskqlobal[.]com

URL

https[:]//udeskqlobal[.]com/deeps[.]js

https[:]//udeskqlobal[.]com/c[.]php

Адрес кошелька

BTC: bc1qhzppfj69ywp22swj50jwcfxdamg3ym245srng9

EVM: 0x9B6EcD0023a28E1391c5124eCe578A9751A337b2

TRON: TH4L5YAhhxtC8qALbZKbPZZgausbGi25nF

Solana: AFmCUe3nNbjTaC585CcdA3vvC9iWVR8YunooFKpaQx2Z

LTC: ltc1qwz0zp39ywl34kahvn9lyk7j5x63wsy9tcxhm3w

DOGE: DAoy2w8uvFtZ92q87s9qKEoHbWgV7mVThj

Вредоносный файл

filename: udeskApi.2026-10-16.cached.js

SHA256: 45b4e8f160d8d5177819f6c1dc67acc7abbdc65eeaffc909e668799dc778bcf6

filename: deeps.js

SHA256: 57c1441c4f5bb3260981a2df64f9ff35f117abde0d8667c8c66a047880074c59

О MistEye

MistEye — это веб-платформа для анализа угроз и динамического мониторинга безопасности, разработанная SlowMist, которая через API предоставляет возможности обнаружения вредоносной активности и предупреждения о рисках цепочки поставок в экосистеме открытых пакетов.

Все вредоносные пакеты и IOC, связанные с этой кампанией, интегрированы в движок угроз MistEye. Разработчики могут использовать API для автоматической проверки зависимостей проекта, чтобы быстро определить, содержатся ли в них известные вредоносные пакеты, и получить рекомендации по устранению.

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