В экосистему npm внедрена сложная программа-червь, похищающая данные разработчиков через блокчейн

information security

Крупная атака на цепочку поставок программного обеспечения была выявлена в популярном npm-пакете "pgserve", представляющем собой встраиваемый сервер PostgreSQL для нужд разработки. Злоумышленникам удалось опубликовать три вредоносные версии библиотеки, которые автоматически запускают сложный скрипт для кражи учетных данных при каждой установке через "npm install". Эта кампания отличается не только масштабом сбора конфиденциальной информации, но и использованием передовых технологий для обеспечения устойчивости и самораспространения, превращая её в полноценного червя, способного заражать другие пакеты.

Описание

Инцидент начался 21 апреля 2026 года, когда в публичный реестр npm были загружены версии "pgserve" 1.1.11, 1.1.12 и 1.1.13. Важно отметить, что ни одна из этих версий не имеет соответствующего тега в основном репозитории на GitHub, что является первым красным флагом. Последней легитимной версией остаётся 1.1.10, выпущенная 17 апреля. Пакет "pgserve" пользуется спросом у разработчиков Node.js, так как предоставляет базу данных PostgreSQL с автоматической настройкой, что делает его удобным инструментом для локальной разработки и тестирования. Именно эта популярность и стала мишенью для атаки.

Механизм заражения был реализован через стандартный для npm хук "postinstall". Вредоносный код был добавлен всего в два файла по сравнению с чистой версией 1.1.10: скрипт "check-env.js" и файл с открытым RSA-ключом "public.pem". В файле "package.json" хук был изменён на ""postinstall": "node scripts/check-env.cjs || true"". Конструкция "|| true" выполняет ключевую роль - она гарантирует, что процесс установки завершится с видимым успехом, даже если вредоносный скрипт завершится с ошибкой, что маскирует его деятельность от разработчика.

Сам скрипт "check-env.js" представляет собой сложную программу на 1143 строки, выполняющую шесть последовательных операций. Сначала он проводит сбор переменных окружения, сканируя их с помощью примерно 40 регулярных выражений, нацеленных на такие шаблоны, как "TOKEN", "SECRET", "KEY", "PASSWORD", а также префиксы популярных облачных сервисов (AWS, Azure, GCP) и систем (GitHub, GitLab, NPM). Далее скрипт обращается к файловой системе, собирая файлы с учётными данными из домашнего каталога пользователя: токены менеджеров пакетов, SSH-ключи, облачные конфигурации, данные криптокошельков и даже сохранённые пароли из браузера Chrome.

Перед отправкой все собранные данные шифруются по гибридной схеме. Генерируется случайный сессионный ключ AES-256-CBC, которым шифруется полезная нагрузка. Затем этот ключ шифруется с помощью прилагаемого RSA-4096 открытого ключа. Такой подход делает перехваченные данные бесполезными без приватного ключа злоумышленника. Эксперты StepSecurity в своём отчёте подтвердили, что во время контролируемого запуска в среде GitHub Actions было собрано и зашифровано 38 переменных окружения и файловых секретов общим объёмом 4.4 КБ.

Наиболее инновационной и опасной чертой этой атаки является механизм эксфильтрации данных и самораспространения. Основным каналом для вывода информации выбран не обычный веб-сервер, а так называемый канстер (canister) в протоколе Internet Computer (ICP) - по сути, смарт-контракт, размещённый на блокчейне. Адрес "cjn37-uyaaa-aaaac-qgnva-cai.raw.icp0.io" невозможно заблокировать через отзыв доменного имени или давление на хостинг-провайдера, что обеспечивает атакующему практически гарантированный доступ к украденным данным. Вторичным каналом служит домен "telemetry.api-monitor.com", не имевший ранее известных связей с вредоносной активностью.

После кражи данных червь переходит в фазу распространения. Он ищет на скомпрометированной машине токен для публикации в npm. Если токен найден, скрипт автоматически получает список пакетов, которые жертва имеет право публиковать, и внедряет себя в каждый из них, увеличивая номер патч-версии и публикуя обновлённый пакет. Это превращает единичный случай компрометации в каскадное заражение всей экосистемы. Более того, если обнаруживается токен PyPI, вредоносная логика также пытается распространиться на пакеты Python через технику внедрения в ".pth"-файлы.

Обнаружение этой сложной атаки стало возможным благодаря инструментам автоматизированного анализа. AI Package Analyst от StepSecurity сразу поместил все три скомпрометированные версии в категорию "Критический / Отклонён", идентифицировав десять сигнатур угроз, включая кражу учётных данных, эксфильтрацию данных из окружения и файловой системы, кражу паролей браузера и сетевое взаимодействие с подозрительными доменами. Параллельно система Harden Runner, работающая в режиме аудита, перехватила и заблокировала сетевые соединения с вредоносными канстерами во время контролируемого запуска, подтвердив живую активность угрозы.

Этот инцидент наглядно демонстрирует эволюцию атак на цепочки поставок. Злоумышленники переходят от простого внедрения майнеров или программ-вымогателей к созданию сложных, самораспространяющихся механизмов, использующих инфраструктуру жертв для собственного размножения. Использование устойчивых к блокировке технологий, таких как блокчейн, и перекрёстное заражение между экосистемами (npm и PyPI) задаёт новый уровень угрозы для открытого исходного кода. Для разработчиков и компаний это служит жёстким напоминанием о необходимости строгого контроля версий зависимостей, использования инструментов статического анализа безопасности для зависимостей (SCA) и мониторинга необычного сетевого трафика в средах сборки и разработки, особенно исходящих в сторону неизвестных или блокчейн-хостов.

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

  • Compromised packages: pgserve@1.1.11, pgserve@1.1.12, pgserve@1.1.13
  • Safe version: pgserve@1.1.10 and earlier
  • Exfil domain (ICP canister): cjn37-uyaaa-aaaac-qgnva-cai.raw.icp0.io
  • Exfil endpoint (ICP): https://cjn37-uyaaa-aaaac-qgnva-cai.raw.icp0.io/drop
  • Exfil domain (webhook): telemetry.api-monitor.com
  • Exfil endpoint (webhook): https://telemetry.api-monitor.com/v1/telemetry
  • Malicious files injected: scripts/check-env.js, scripts/public.pem
  • Trigger: postinstall hook

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