В реестре npm лежит пакет imgdecode, который выглядит безобидной утилитой для обработки изображений. Внутри работает загрузчик вредоносного кода, и он срабатывает без установочного скрипта. Достаточно, чтобы программа на Node.js (среда выполнения кода на JavaScript) в системе Windows обратилась к этому пакету. Зашитая в него динамическая библиотека (DLL - скомпилированный код, который подключается к программе во время её работы) сразу начинает действовать. Тринадцатого октября 2026 года пакет всё ещё был доступен для скачивания. Опубликованы версии с 1.0.0 по 1.0.3, издатель скрывается под ником malfexteste8.
Описание
Находка продолжает кампанию MALFEX, о которой сообщили Checkmarx, CloudSEK и Orca Security в начале октября 2026 года. Разбор нового пакета опубликовала компания SafeDep. Цель кампании - разработчики, работающие на Windows. Оператор, судя по строкам в коде, говорит на португальском. Публичные отчёты перечисляют восемь пакетов, отдельную ветку с программой удалённого доступа и цепочку из трёх ролей. Первый пакет скачивает зашифрованный файл с публичного репозитория. Второй расшифровывает его и записывает исполняемый файл на диск. Третий запускает результат. Название imgdecode в тех отчётах не встречается.
Двадцать восьмого сентября 2026 года npm убрал два пакета из этой цепочки. Замены появились меньше чем через двое суток. Каждая выполняла ту же работу, но иным способом. Пакет runhelper продержался в реестре меньше суток. Затем оператор выложил imgdecode. Сначала это был обычный модуль на JavaScript: он ждал готовый расшифрованный файл и передавал его надстройке. Позже автор перенёс в бинарный модуль всю логику целиком - загрузку, расшифровку и запуск. Версию 1.0.3 он опубликовал 11 октября, через шесть дней после отчёта Checkmarx.
Смысл переноса в скомпилированный модуль понятен. Средства защиты, которые следят только за установочными скриптами, такой запуск пропускают. В архиве пакета нет ни сборочных файлов, ни самого скрипта установки - только готовая библиотека. Модуль срабатывает в момент подключения пакета, до того как вернёт программе свои функции. Документация при этом описывает функции, которых в пакете нет.
Маскировка под работу в терминале
Запуск зависит от того, куда направлен стандартный вывод программы. Если вывод уходит в файл или в канал, вредоносный код останавливается. Так устроены сборочные конвейеры, автоматические проверки и изолированные среды, которые называют песочницами. Загрузчик дожидается запуска с рабочего компьютера разработчика в интерактивной консоли. Внутренние строки библиотеки зашифрованы однобайтовым ключом, а нужные системные функции она ищет во время работы.
Дальше начинается сама атака. Библиотека скачивает из публичного репозитория файл, замаскированный под картинку, держит его в памяти и расшифровывает ключом, который выведен из жёстко зашитой парольной фразы. Если после расшифровки обнаруживается настоящий снимок в формате JPEG или PNG, загрузчик останавливается. Так у оператора остаётся возможность выключить атаку, подменив содержимое файла. Во всех остальных случаях расшифрованный шелл-код (вредоносный код, который исполняется прямо в памяти) попадает в системный процесс dllhost.exe. Для этого библиотека запускает процесс приостановленным, выделяет в нём память, копирует туда полезную нагрузку и создаёт удалённый поток. Основной поток остаётся приостановленным, работает только внедрённый. Если внедрение не удалось, предусмотрен запасной путь - исполнение внутри самого Node.js.
Что несёт финальная полезная нагрузка
Первая ступень - небольшая программа на языке Go. Она скачивает с сервера в Бразилии установочный файл размером 71,5 МБ и запускает его. Сервер отдавал этот файл и 13 октября 2026 года.
Вторая ступень - программа для кражи данных и удалённого управления, собранная как приложение на Node.js. В её настройках лежат адрес командно-контрольного сервера (C2-сервера, через который злоумышленник управляет заражённой машиной) и лицензионный ключ. Это указывает на готовый конструктор вредоносных программ. Строки написаны на португальском. По ним виден набор возможностей: проверка на виртуальные машины и инструменты анализа; сбор паролей и файлов cookie из браузеров; перехват токенов Discord; копирование данных криптовалютных кошельков, игровых клиентов и Telegram; поиск файлов, в названиях которых встречаются слова про сид-фразы, пароли и секреты; удалённое управление с доступом к командной строке, файлам, буферу обмена, снимкам экрана, мыши и клавиатуре; закрепление в системе через копирование в служебную папку и задачу планировщика; удаление следов в журналах событий и истории PowerShell. Часть этих возможностей восстановлена по строковым таблицам, и успешность их работы не подтверждена.
Масштаб заражения оценить трудно. Публичный поиск не нашёл ни одного проекта, который объявлял бы эти пакеты в зависимостях. Счётчик npm зафиксировал 929 скачиваний imgdecode с 30 сентября по 12 октября 2026 года. Пики приходятся на дни публикации новых версий. Зеркала реестра и сканеры могли дать часть этого числа. Отличить автоматические загрузки от пользовательских по счётчику нельзя. Публичные поиски при этом не охватывают закрытые проекты.
Рабочую станцию, на которой загружался imgdecode или другой пакет MALFEX, нужно считать потенциально скомпрометированной. Группам реагирования следует изолировать машину и снять дамп памяти до перезагрузки: загрузчик работает в памяти и не оставляет исполняемого файла на диске. Затем имеет смысл поискать записи автозапуска и процессы dllhost.exe, порождённые Node.js. Владельцам учётных записей нужно сменить пароли, сессионные файлы cookie, токены Discord, ключи облачных сервисов, SSH-ключи, а также токены npm и GitHub. Если на машине хранились сид-фразы криптовалютных кошельков, средства лучше перевести на новые адреса. Локальные журналы событий Windows и Sysmon надёжнее сравнить с внешними: собранная программа умеет править их записи и пересчитывать контрольные суммы.