Атака на цепочку поставок npm: вредоносные пакеты Red Hat Cloud Services заражают среды разработки

security

Безопасность цепочки поставок программного обеспечения вновь оказалась под угрозой. Система мониторинга MistEye зафиксировала инцидент, связанный с публикацией вредоносных версий пакетов, принадлежащих организации Red Hat Cloud Services. В общей сложности атака затронула 32 npm-пакета, было выпущено 96 подозрительных версий. Для детального анализа специалисты отобрали три локальных образца, которые не являются подделками или попытками опечатки названия (typo-squatting). Это легитимные версии пакетов, выпущенные в пространстве имен @redhat-cloud-services, но содержащие в своем составе вредоносный код. Внутри архивов (tarball) были обнаружены многослойно обфусцированные загрузчики (loader), активирующиеся автоматически на этапе установки.

Описание

Полная реконструкция атаки показала, что основная полезная нагрузка (payload) обладает широчайшим спектром возможностей. Среди них - чтение памяти GitHub Actions Runner, сбор учетных данных из облачных сред и локальных конфигураций, передача данных через GitHub API, внедрение вредоносных workflow в репозитории, самовоспроизведение через npm, а также механизмы закрепления (persistence) в системе и противодействия системам безопасности. По оценкам экспертов, под ударом могут оказаться рабочие станции разработчиков, сборочные конвейеры CI/CD, контейнеры для сборки, GitHub-репозитории, workflow Actions и даже облачные учетные данные.

Исследователи из SlowMist, разработавшие систему MistEye, опубликовали детальный отчет об инциденте. Анализ кода и тактик злоумышленников позволяет утверждать, что данное вредоносное ПО является вариантом известного семейства Shai-Hulud. Система MistEye уже выдала критическое предупреждение и сформировала полный набор индикаторов компрометации (IOC) и структуру цепочки атак.

Как устроена атака

Технический анализ проводился исключительно методами локальной офлайн-статики. Исследователи распаковали три архива tgz, декодировали и деобфусцировали их содержимое. Входная точка атаки идентична для всех трех образцов. В файлах package.json обнаружена директива "scripts.preinstall = “node index.js”". Это означает, что при любой попытке установки такой версии пакета на рабочей станции разработчика или в среде CI/CD корневой файл index.js запускается автоматически. Пользователю не нужно импортировать модуль или выполнять бизнес-логику. Этот механизм является классическим перехватом жизненного цикла npm.

Внешне файлы index.js во всех трех выборках выглядят как огромные однострочные JavaScript-файлы. Они содержат массив чисел, который преобразуется в строку через "String.fromCharCode", после чего применяется шифр Цезаря (ROT) для восстановления текста. Затем результат передается в "eval". Важно, что параметры кодирования (величина сдвига) в разных пакетах отличаются. Например, для пакета "frontend-components-config" сдвиг составляет 10, для "types" - 4, а для "rule-components" - 11. Такая вариативность затрудняет создание универсальных статических сигнатур для антивирусов.

После расшифровки первого слоя код переходит ко второму этапу. Используется алгоритм AES-128-GCM (Advanced Encryption Standard - Galois/Counter Mode), встроенный в Node.js. Этот слой извлекает два ключевых компонента: загрузчик среды выполнения Bun (далее - _b) и ядро вредоносной нагрузки (далее - _p). Критически важная находка: хотя ключи, векторы и метки шифрования в трех образцах различны, расшифрованные компоненты _b и _p имеют абсолютно одинаковые хеши SHA-256. Это доказывает, что атакующие модифицируют только внешнюю оболочку под каждый пакет, но используют единый набор зловредного кода внутри.

Следующие слои обфускации включают строковые таблицы "obfuscator.io" и кастомное шифрование B5 на основе PBKDF2 с 200 000 итераций. Внутри "_p" также находятся дополнительные встроенные ресурсы, защищенные шифрованием AES-256-GCM и сжатием gzip. Среди них - скрипты для чтения памяти под Linux, Windows и macOS, конфигурации для закрепления в системе (через Claude Code, VS Code, systemd и LaunchAgent), а также шаблон вредоносного GitHub Actions workflow.

Чем опасен данный инцидент

Последствия атаки потенциально катастрофичны для компаний, использующих открытые компоненты. Главная цель злоумышленников - кража секретов (secrets) из сред разработки. Вредоносное ПО активно проверяет, запущено ли оно внутри GitHub Actions. Если переменная "GITHUB_ACTIONS" установлена в "true", код находит процесс "Runner.Worker" и считывает его память. Из дампа извлекаются данные в формате "“<name>”:{“value”:”<value>”,”isSecret”:true}", то есть маскированные секреты, которые GitHub Actions скрывает в логах. В оперативной памяти эти значения могут находиться открытым текстом.

Кроме того, вредоносная нагрузка собирает учетные данные из множества источников. Это токены облачных провайдеров (AWS, Azure, GCP), локальные конфигурации (".npmrc", ".pypirc", SSH-ключи, Docker), данные от менеджеров паролей и даже файлы криптовалютных кошельков. Для передачи украденного используется GitHub API. Запросы маскируются под User-Agent "python-requests/2.31.0". Злоумышленники создают репозитории с фиксированным описанием "Miasma: The Spreading Blight" и загружают туда похищенные данные в формате base64.

Особую тревогу вызывает механизм распространения. Вредоносное ПО может использовать как украденные токены npm с правом публикации и отключенной двухфакторной аутентификацией (2FA), так и механизм OIDC (OpenID Connect) в GitHub Actions. В последнем случае вредоносный workflow запрашивает токен OIDC для аудитории "npm:registry.npmjs.org" и использует "доверенную публикацию" (trusted publishing) npm. Затем код скачивает легитимный пакет, распаковывает его, внедряет в корень вредоносный "index.js" и изменяет "package.json", добавляя запуск через "bun run index.js". Это создает цепную реакцию заражения внутри экосистемы npm.

Выводы и рекомендации

Данный инцидент демонстрирует, насколько сложными могут быть современные атаки на цепочки поставок. Вредоносное ПО представляет собой многоступенчатый загрузчик с развитой архитектурой, способной к самовоспроизведению и противостоянию системам защиты. Командам разработчиков и специалистам по безопасности необходимо незамедлительно принять меры. В первую очередь следует провести аудит зависимостей и lock-файлов на наличие скомпрометированных версий, а также проверить логи установки на предмет подозрительных команд. Особое внимание стоит уделить недавно созданным репозиториям, веткам и workflow в GitHub. Важно помнить, что отзыв токенов на скомпрометированной машине может спровоцировать срабатывание встроенной "кнопки самоуничтожения": зловред удалит домашнюю директорию и каталог "Documents" при обнаружении признаков блокировки. Поэтому сначала необходимо изолировать хосты, очистить процессы и записи в автозагрузке, и только затем менять пароли и ключи из доверенной среды.

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

MD5

  • 633ad8849a59e2bfb7a0fe589e816a07
  • 9e6c5af01438b52c9a411686c1f1b8ff
  • f1ffdbf5e639899f26a6ebab2eec408d

SHA1

  • 675294612f455fe6a9acb195f0cbe3687d8e2e34
  • 88d098c8d96e9ae17550e9798c3b62c420464b8c
  • f3c5c21274045ae02fef11e931de6dcf8462a067

SHA256

  • 0c9c67ec40d5f23efa1ec3470d0ac88b4993ccc0e92be913fc29a337dfc4f060
  • 0dc06ecdaa63fe24859cfd955053c23245c536e4733480239d14bebf12688e35
  • aaf00d06baa3c679b82452c50014e9824b8874e9ca2d150f19095f8de19ba90f
  • ac2a2208e1726e008be6c73dc0872d9bba163319259dff1b62055ac933ca46b6
  • d543bb3cdf1569c2b3d38c8a4081ed746cfe78bf3236c2302704d79ab7fa9558

Packages

  • npm:@redhat-cloud-services/chrome@2.3.1
  • npm:@redhat-cloud-services/chrome@2.3.2
  • npm:@redhat-cloud-services/chrome@2.3.4
  • npm:@redhat-cloud-services/compliance-client@4.0.3
  • npm:@redhat-cloud-services/compliance-client@4.0.4
  • npm:@redhat-cloud-services/compliance-client@4.0.6
  • npm:@redhat-cloud-services/config-manager-client@5.0.4
  • npm:@redhat-cloud-services/config-manager-client@5.0.5
  • npm:@redhat-cloud-services/config-manager-client@5.0.7
  • npm:@redhat-cloud-services/entitlements-client@4.0.11
  • npm:@redhat-cloud-services/entitlements-client@4.0.12
  • npm:@redhat-cloud-services/entitlements-client@4.0.14
  • npm:@redhat-cloud-services/eslint-config-redhat-cloud-services@3.2.1
  • npm:@redhat-cloud-services/eslint-config-redhat-cloud-services@3.2.2
  • npm:@redhat-cloud-services/eslint-config-redhat-cloud-services@3.2.4
  • npm:@redhat-cloud-services/frontend-components@7.7.2
  • npm:@redhat-cloud-services/frontend-components@7.7.3
  • npm:@redhat-cloud-services/frontend-components@7.7.5
  • npm:@redhat-cloud-services/frontend-components-advisor-components@3.8.2
  • npm:@redhat-cloud-services/frontend-components-advisor-components@3.8.4
  • npm:@redhat-cloud-services/frontend-components-advisor-components@3.8.6
  • npm:@redhat-cloud-services/frontend-components-config@6.11.3
  • npm:@redhat-cloud-services/frontend-components-config@6.11.4
  • npm:@redhat-cloud-services/frontend-components-config@6.11.6
  • npm:@redhat-cloud-services/frontend-components-config-utilities@4.11.2
  • npm:@redhat-cloud-services/frontend-components-config-utilities@4.11.3
  • npm:@redhat-cloud-services/frontend-components-config-utilities@4.11.5
  • npm:@redhat-cloud-services/frontend-components-notifications@6.9.2
  • npm:@redhat-cloud-services/frontend-components-notifications@6.9.3
  • npm:@redhat-cloud-services/frontend-components-notifications@6.9.5
  • npm:@redhat-cloud-services/frontend-components-remediations@4.9.2
  • npm:@redhat-cloud-services/frontend-components-remediations@4.9.3
  • npm:@redhat-cloud-services/frontend-components-remediations@4.9.5
  • npm:@redhat-cloud-services/frontend-components-testing@1.2.1
  • npm:@redhat-cloud-services/frontend-components-testing@1.2.2
  • npm:@redhat-cloud-services/frontend-components-testing@1.2.4
  • npm:@redhat-cloud-services/frontend-components-translations@4.4.1
  • npm:@redhat-cloud-services/frontend-components-translations@4.4.2
  • npm:@redhat-cloud-services/frontend-components-translations@4.4.4
  • npm:@redhat-cloud-services/frontend-components-utilities@7.4.1
  • npm:@redhat-cloud-services/frontend-components-utilities@7.4.2
  • npm:@redhat-cloud-services/frontend-components-utilities@7.4.4
  • npm:@redhat-cloud-services/hcc-feo-mcp@0.3.1
  • npm:@redhat-cloud-services/hcc-feo-mcp@0.3.2
  • npm:@redhat-cloud-services/hcc-feo-mcp@0.3.4
  • npm:@redhat-cloud-services/hcc-kessel-mcp@0.3.1
  • npm:@redhat-cloud-services/hcc-kessel-mcp@0.3.2
  • npm:@redhat-cloud-services/hcc-kessel-mcp@0.3.4
  • npm:@redhat-cloud-services/hcc-pf-mcp@0.6.1
  • npm:@redhat-cloud-services/hcc-pf-mcp@0.6.2
  • npm:@redhat-cloud-services/hcc-pf-mcp@0.6.4
  • npm:@redhat-cloud-services/host-inventory-client@5.0.3
  • npm:@redhat-cloud-services/host-inventory-client@5.0.4
  • npm:@redhat-cloud-services/host-inventory-client@5.0.6
  • npm:@redhat-cloud-services/insights-client@4.0.4
  • npm:@redhat-cloud-services/insights-client@4.0.5
  • npm:@redhat-cloud-services/insights-client@4.0.7
  • npm:@redhat-cloud-services/integrations-client@6.0.4
  • npm:@redhat-cloud-services/integrations-client@6.0.5
  • npm:@redhat-cloud-services/integrations-client@6.0.7
  • npm:@redhat-cloud-services/javascript-clients-shared@2.0.11
  • npm:@redhat-cloud-services/javascript-clients-shared@2.0.8
  • npm:@redhat-cloud-services/javascript-clients-shared@2.0.9
  • npm:@redhat-cloud-services/notifications-client@6.1.4
  • npm:@redhat-cloud-services/notifications-client@6.1.5
  • npm:@redhat-cloud-services/notifications-client@6.1.7
  • npm:@redhat-cloud-services/patch-client@4.0.4
  • npm:@redhat-cloud-services/patch-client@4.0.5
  • npm:@redhat-cloud-services/patch-client@4.0.7
  • npm:@redhat-cloud-services/quickstarts-client@4.0.11
  • npm:@redhat-cloud-services/quickstarts-client@4.0.12
  • npm:@redhat-cloud-services/quickstarts-client@4.0.14
  • npm:@redhat-cloud-services/rbac-client@9.0.3
  • npm:@redhat-cloud-services/rbac-client@9.0.4
  • npm:@redhat-cloud-services/rbac-client@9.0.6
  • npm:@redhat-cloud-services/remediations-client@4.0.4
  • npm:@redhat-cloud-services/remediations-client@4.0.5
  • npm:@redhat-cloud-services/remediations-client@4.0.7
  • npm:@redhat-cloud-services/rule-components@4.7.2
  • npm:@redhat-cloud-services/rule-components@4.7.3
  • npm:@redhat-cloud-services/rule-components@4.7.5
  • npm:@redhat-cloud-services/sources-client@3.0.10
  • npm:@redhat-cloud-services/sources-client@3.0.11
  • npm:@redhat-cloud-services/sources-client@3.0.13
  • npm:@redhat-cloud-services/topological-inventory-client@3.0.10
  • npm:@redhat-cloud-services/topological-inventory-client@3.0.11
  • npm:@redhat-cloud-services/topological-inventory-client@3.0.13
  • npm:@redhat-cloud-services/tsc-transform-imports@1.2.2
  • npm:@redhat-cloud-services/tsc-transform-imports@1.2.4
  • npm:@redhat-cloud-services/tsc-transform-imports@1.2.6
  • npm:@redhat-cloud-services/types@3.6.1
  • npm:@redhat-cloud-services/types@3.6.2
  • npm:@redhat-cloud-services/types@3.6.4
  • npm:@redhat-cloud-services/vulnerabilities-client@2.1.11
  • npm:@redhat-cloud-services/vulnerabilities-client@2.1.8
  • npm:@redhat-cloud-services/vulnerabilities-client@2.1.9

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