Девять npm-пакетов с многоступенчатой C2-инфраструктурой: атака на цепочку поставок затронула 16 систем

Атака на цепочку поставок NPM

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

Описание

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

Первая партия из семи пакетов появилась 12 сентября 2026 года, вторая из двух - 14 сентября. Названия имитировали клиентские библиотеки и утилиты времени выполнения. Во второй партии злоумышленники убрали из описаний подозрительные слова про удалённое исполнение команд и наблюдение за системой, сократили сопроводительный текст и удалили ссылки на внешние репозитории. Номера версий при этом менялись быстро и непоследовательно. Так авторы создавали видимость активной поддержки своих проектов.

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

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

Загрузчик вмешивается в системный механизм подключения модулей. Любой дочерний процесс, который запускает сторонний код, из-за этого тоже стартует без видимого окна. Полезная нагрузка внутри пакета не хранится. Вместо неё загрузчик обращается по защищённому каналу к публичному сервису обмена данными и получает код в виде текстового ответа. Затем строка декодируется и исполняется прямо в памяти. Такой подход даёт возможность менять функциональность без повторной публикации пакета. Во второй группе схема оказалась двухступенчатой: сначала загружался промежуточный модуль, и лишь он сообщал настоящий адрес командно-контрольного сервера (C2-сервера).

После запуска вредоносная программа собирает сведения о машине. Это имя компьютера и пользователя, версия операционной системы, характеристики процессора и памяти, сетевые интерфейсы, внешний IP-адрес и примерное местоположение. Затем она ищет профили браузера Chrome и забирает данные расширений. В этих хранилищах нередко лежат ключи криптовалютных кошельков и сведения из менеджеров паролей. Утечка такого набора оборачивается прямыми финансовыми потерями и потерей доступа к аккаунтам.

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

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

Отдельный интерес вызвала машина, которую считают рабочей станцией самого автора атаки. В собранных с неё данных буфера обмена нашлись фрагменты ответов ИИ-ассистента для программирования. Десятого сентября 2026 года в буфер обмена многократно попадал закодированный текст, подготовленный для загрузки на сервер управления. Примерно через 26 минут там же появился ответ ассистента. Тот разбирал, почему при запуске Chrome на экране возникает лишнее окно консоли, и предлагал способ запуска без него. Ту же технику скрытого запуска процессов позже нашли внутри вредоносных пакетов.

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

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

Package

  • @biz44/id10-client 1.1.11
  • @biz44/id12-client 1.1.13
  • @biz44/id44-client 1.1.44
  • @biz44/id79-client 1.1.80
  • @biz44/id95-client 1.1.96
  • @biz44/id99-client 1.1.100
  • @biz44/process-runtime-utils 1.1.10
  • @biz44/runtime-utils 1.1.11
  • id79-client 1.1.79

MD5

  • 0ab67d9a5b8141ef06246eb8af2a55f5
  • 0ed8f07e351b34b5ec1288bc2dd100a4
  • 44b2b250e8bb4e1ee3ed35dcd0cf7b59
  • 5ed7c5ea7aed02898574476bc740ae86
  • 9282fdd8bcbc5f68678fed5b13a248e7
  • b7f170acf3c3674e3b8999c38a09f839
  • c72b21baf3c49bcbc62b8bbfb04d2bd9
  • d2797234fa48dd5434e73fa5fef5d1fe
  • d59ce7cfe339c1159d699dd88007103b
  • d916bddfcd04990b1fd1bcd0777da72e
  • d98104cc0822d188df1e9ca072369b45

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