В экосистеме разработки на Node.js вновь обнаружена изощрённая кампания по компрометации цепочек поставок. Аналитики компании Veracode раскрыли детали вредоносного пакета "buildrunner-dev", опубликованного в реестре NPM. Этот пакет использует многослойную обфускацию и стеганографию для скрытой доставки в систему финальной полезной нагрузки - программы удалённого доступа Pulsar. Атака демонстрирует высокий уровень целевой разработки, включая логику уклонения от конкретных продуктов антивирусной защиты и несколько методов обхода механизмов безопасности Windows.
Описание
Суть инцидента и тактика типосквоттинга
Пакет "buildrunner-dev" является классическим примером типосквоттинга. Его название намеренно схоже с названиями легитимных, но заброшенных пакетов "buildrunner" и "build-runner". Разработчик, ищущий один из этих пакетов, может случайно или намеренно установить вредоносную версию, приняв её за поддерживаемый форк. Сам пакет технически пуст - его единственная функция "postinstall" в файле "package.json" запускает скрипт "init.js" в момент установки через "npm install". Этот скрипт выступает в роли загрузчика, чья основная задача - скачать и исполнить основной вредоносный код, хранящийся не в пакете, а на внешнем ресурсе (репозитории Codeberg). Такой подход позволяет избежать статического анализа кода самого пакета.
Многослойная обфускация в пакетном файле
Скачанный файл "packageloader.bat" представляет собой произведение инженерной мысли злоумышленника, направленной на максимальное затруднение анализа. Из 1653 строк файла лишь около 21 несут реальную функциональность. Остальное - тщательно спроектированный «шум». Автор применил как минимум семь различных техник обфускации. Среди них - использование «призрачных» переменных окружения, которые, будучи неопределёнными, исчезают при выполнении, фрагментация полезной нагрузки на 909 переменных, содержащих по 2-8 символов каждая, а также множество строк с бессмысленными комментариями "REM" и поддельными командами в кодировке Base64, которые никогда не выполняются, но призваны запутать автоматические сканеры. Все имена переменных представляют собой случайные наборы символов, что исключает возможность семантического анализа.
Функциональность и эскалация привилегий
После очистки от шума логика пакетного файла становится ясной. Во-первых, он копирует себя в папку автозагрузки пользователя ("%AppData%") для обеспечения постоянного присутствия в системе. Затем проверяет наличие административных прав. Если права отсутствуют, скрипт использует известный метод обхода контроля учётных записей (User Account Control, UAC) через утилиту "fodhelper.exe" (техника MITRE ATT&CK T1548.002). Он манипулирует записями в реестре, чтобы заставить легитимный системный процесс выполнить вредоносный скрипт с повышенными привилегиями без показа запроса UAC. После успешного повышения прав скрипт собирает фрагментированную команду PowerShell и запускает её в скрытом окне через "conhost.exe --headless".
Адаптивная логика загрузки с учётом антивируса
Собранная команда PowerShell - это не статичный загрузчик, а адаптивный механизм. Первым делом она с помощью инструментария WMI ("Get-CimInstance") определяет, какой продукт антивирусной защиты установлен в системе. В зависимости от результата выбирается один из двух путей. Если обнаружены продукты Malwarebytes или F-Secure, скрипт загружает специальный PNG-файл, содержащий скрипт для обхода интерфейса Anti-malware Scan Interface (AMSI, механизм Microsoft для интеграции антивирусного сканирования в приложения). В противном случае загружается другой PNG-файл, скрывающий скомпилированную сборку .NET. Это указывает на то, что авторы атаки провели тестирование против конкретных продуктов и разработали целевые методы уклонения.
Стеганография как основной канал доставки
Ключевая особенность этой атаки - использование стеганографии для сокрытия вредоносного кода внутри обычных PNG-изображений, размещённых на бесплатном хостинге ImgBB. Алгоритм кодирования прост, но эффективен. Размер полезной нагрузки кодируется в значениях красного, зелёного и синего каналов первых двух пикселей. Начиная с третьего пикселя, каждый пиксель несёт три байта данных (по одному на каждый цветовой канал). Визуально изображения выглядят как случайный шум, что не вызывает подозрений. Таким образом, вредоносный код полностью отделён от загрузчика и может быть в любой момент заменён на новый, просто загрузив другое изображение по тому же URL.
Анализ извлечённых полезных нагрузок
Экспертам удалось извлечь данные из обоих изображений. Меньшее изображение (41×41 пиксель) содержало скрипт PowerShell для патчинга AMSI в памяти. Он использовал динамическое создание делегатов .NET через "Reflection.Emit", чтобы избежать статических объявлений, которые могли бы быть обнаружены антивирусом, и напрямую перезаписывал начало функции "AmsiScanBuffer", заставляя её всегда возвращать статус «чистый».
Большее изображение (141×141 пиксель) скрывало сжатую GZip сборку .NET размером 136 КБ. Декомпиляция выявила сложный загрузчик, использующий технику «опустошения процесса» (process hollowing). Он создаёт легитимный системный процесс (например, "conhost.exe") в приостановленном состоянии, выгружает его оригинальный код из памяти и внедряет на своё место расшифрованную вредоносную полезную нагрузку. Это позволяет маскировать активность под легитимный процесс. Интересно, что этот загрузчик содержал собственный, более изощрённый метод обхода AMSI через аппаратные точки останова и обработчики векторных исключений, не требующий модификации памяти.
Цепочка расшифровки и финальная полезная нагрузка
Загрузчик не нёс финальную полезную нагрузку в открытом виде. В его строках, защищённых шифрованием AES-256, был обнаружен URL третьего PNG-изображения. После его загрузки, извлечения данных из пикселей, расшифровки с помощью TripleDES и распаковки GZip был получен исполняемый файл .NET размером 976 КБ. Им оказался RAT Pulsar (также известный как Quasar) - мощный инструмент удалённого администрирования с открытым исходным кодом, часто используемый злоумышленниками для полного контроля над заражённой системой.
Выводы и рекомендации по защите
Данная кампания наглядно демонстрирует эволюцию атак на цепочки поставок программного обеспечения. Злоумышленники переходят от простого внедрения вредоносного кода в пакеты к созданию сложных многоэтапных загрузчиков, использующих легитимные инфраструктурные сервисы и продвинутые техники сокрытия. Для противодействия подобным угрозам организациям необходимо реализовать многоуровневую защиту. Критически важно использовать решения для анализа состава программного обеспечения, которые могут автоматически обнаруживать подозрительные и известные вредоносные зависимости в проектах. Кроме того, необходимо применять политики безопасности, запрещающие автоматическое выполнение скриптов "postinstall" из ненадёжных источников, и регулярно проводить аудит используемых в разработке открытых пакетов, обращая особое внимание на их репутацию, активность поддержки и историю обновлений. Для команд разработки лучшей практикой остаётся строгая верификация имени и источника каждого устанавливаемого пакета, особенно если он похож на известный, но давно не обновлявшийся проект.
Индикаторы компрометации
URLs
- https://i.ibb.co/tpyTL2Zg/s9rugowxbq8i.png
NPM Packages
- buildrunner-dev