Mini Shai-Hulud: компрометация цепочки поставок в эпоху разработки, управляемой ИИ

11 мая 2026 года была обнаружена новая волна активности Shai-Hulud, которая повлияла на экосистемы npm и PyPI из-за сложного червя цепочки поставки с путями выполнения JavaScript и Python. Кампания является значительной компрометацией процессов разработки и выпуска программного обеспечения. По данным публичных отчетов, ее влияние распространилось более чем на 170 пакетов. Среди пораженных пакетов – компоненты TanStack со встроенными бэкдорами, а также пакеты, связанные с OpenSearch, Mistral AI, Guardrails AI, UiPath, Squawk и другими.

Основная цель остается такой же, как и в предыдущей активности Shai-Hulud: похищение учетных данных из машин разработчиков и сред выполнения CI/CD, а затем использование этих учетных данных для компрометации дополнительных пакетов, репозиториев и сред. В этой волне изменились масштаб, путь релиза и модель исполнения. Вредоносное ПО предназначено для выполнения внутри систем сбора, злоупотребления скриптами жизненного цикла npm, установки или вызова среды выполнения Bun, похищения учетных данных npm, GitHub, облачных сервисов, Kubernetes, Vault и CI/CD, а также использования авторизованных путей публикации для загрузки новых скомпрометированных пакетов.

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

Cynet помогает организациям снижать риски, связанные с Mini Shai-Hulud и подобными атаками на цепочку поставок, на конечных устройствах, где он установлен. Платформа обеспечивает многоуровневую видимость, выявление, предотвращение и реагирование на подозрительную активность, связанную со скомпрометированными зависимостями и угрозами для цепочки поставок программного обеспечения.

Команды Cynet Research и CyOps активно отслеживают и исследуют активность Mini Shai-Hulud, анализируют новые индикаторы и поведенческие признаки атак, а также производят поиск подозрительной активности в средах клиентов.

Новый риск: автоматизированные рабочие процессы разработки, управляемые ИИ

Mini Shai-Hulud демонстрирует рост рисков в автоматизированных рабочих процессах разработки, управляемых ИИ. Кодинговые агенты, системы сборки и автоматизированные инструменты по работе с зависимостями могут устанавливать, обновлять или рекомендовать пакеты без достаточной проверки со стороны человека. В таких средах скомпрометированная зависимость может быть добавлена ​​к проекту, выполнена автоматически и получить доступ к чувствительным токенам, конфигурационным файлам или учетным данным CI/CD.

Проблема заключается не только во вредоносном ПО, но и в скорости, с которой современные рабочие процессы разработки могут его внедрить. Кодинговые агенты ИИ и автоматизированные системы сборки могут установить или обновить пакеты, прежде чем человек проверит риск. В таком сценарии скомпрометированная зависимость может быстро выполниться, получить доступ к чувствительным учетным данным и потенциально распространиться через существующие рабочие процессы разработки и выпуска.

Обнаружение Cynet: установление зависимостей с помощью ИИ

Во время одной из волн атаки Shai-Hulud на цепочку поставок Cynet зафиксировала активность, показывающую, как среды разработки с поддержкой ИИ могут стать частью пути возникновения риска. Зафиксированная цепочка процессов включала вспомогательный плагин Cursor, который запускал Node.js и npm для установления зависимости из пакета GitHub, обозначенного в контексте активности, связанной с Shai-Hulud:

Cursor Helper (Plugin) → /usr/bin/env node → npm install github:asyncapi/cli#2efa4dff59bc3d3cecdf897ccf178f99b115d63d

  • Родительский процесс: Cursor Helper (Plugin)
  • Запущенная среда выполнения: /usr/bin/env node
  • Действие менеджера пакетов: npm install
  • Зависимость GitHub: github:asyncapi/cli
  • Зафиксированный commit: 2efa4dff59bc3d3cecdf897ccf178f99b115d63d

Эта активность важна, поскольку она показывает, как современные инструменты разработчика могут инициировать установку зависимостей непосредственно с GitHub, в частности из зафиксированных commit-ов, при ограниченной видимости или проверке со стороны пользователя. В контексте атаки на цепочку поставки такой тип рабочего процесса может позволить быстро добавить и выполнить скомпрометированную или подозрительную зависимость в среде разработчика.

Такую активность следует рассматривать как серьезный признак подозрительного поведения и исследовать в контексте, особенно относительно дальнейшего выполнения скриптов, активности Bun, доступа к учетным данным или артефактам установки пакетов.

Технические подробности

Инфицирование цепи поставки начинается тогда, когда скомпрометированный пакет npm или PyPI устанавливается или загружается на машине разработчика, в системе сборки или в среде CI/CD. В проектах npm вредоносный код может автоматически выполняться при установке зависимостей через скрипты жизненного цикла пакета или вредоносное содержимое пакета. В проектах PyPI вредоносный код Python может выполняться при импорте или загрузке пакета.

Кампания имеет два основных технических пути: путь JavaScript/npm и путь Python/PyPI. Оба сосредоточены на похищении и эксфильтрации учетных данных, но отличаются методом выполнения, поддержкой платформ, структурой полезной нагрузки и последующими возможностями.

mini shai-hulud 1

Путь выполнения JavaScript/npm

Полезная нагрузка JavaScript предназначена для работы в системах Windows, Linux и MacOS. Она содержит вредоносный файл конфигурации JSON, который выполняет setup.mjs. Скрипт setup определяет операционную систему и устанавливает или вызывает среду выполнения Bun, необходимую для выполнения следующих этапов. Когда Bun становится доступным, loader запускает router_init.js, содержащий основную обфусцированную полезную нагрузку вредоносного ПО. Перед выполнением основной функциональности вредоносное ПО проводит несколько базовых проверок. Оно создает файл блокировки во временном каталоге в зависимости от операционной системы, чтобы предотвратить повторное выполнение, проверяет языковые и региональные настройки системы, а также часовой пояс, во избежание русскоязычных сред, а также определяет, выполняется ли оно внутри CI-пайплайна или на персональной рабочей станции.

Полезная нагрузка предназначена для похищения секретов посредством сопоставления регулярными выражениями и прямого сбора из локальных и облачных источников. Она ищет npm-токены, токены доступа GitHub, токены GitHub Actions и сессионные токены, JWT Kubernetes, ключи доступа AWS и секретные ключи, сессионные токены AWS, ключи и секреты Azure, токены Slack, токены Vault, а также общие секреты, определенные по ключевым словам password, pass, token и key.

Кроме сопоставления по шаблонам, вредоносное ПО непосредственно нацеливается на хранилища секретов и облачные источники.

Оно пытается собрать секреты репозиториев GitHub Actions, секреты GitHub Runner из памяти Runner.Worker, значения AWS Secrets Manager, параметры AWS SSM Parameter Store, метаданные идентичности и учетной записи AWS STS, Kubernetes Secrets в доступных namespace, а также секреты HashiCorp Vault KV из смонтированных и типичных путей, таких как secret, kv, cubbyhole и secret-v2.

Вредоносное ПО также ищет учетные данные и конфиденциальные данные конфигурации в локальных файлах. Целевые файлы и источники включают учетные данные AWS, Azure, GCP, Kubernetes и Terraform; .npmrc, .pypirc, учетные данные Git, .netrc, конфигурации Docker, SSH-ключи и конфигурации, файлы среды, конфигурационные файлы баз данных, конфигурации ИИ и инструментов разработчика, в частности настройки Claude и MCP, конфигурации VPN-клиентов, хранилища сессий приложений, историю оболочки, историю баз данных, секреты контейнеров и файлы криптовалютных кошельков.

Вариант JavaScript также содержит более широкую функциональность для цепочки поставок. Он нацелен на токены пакетов npm, которые можно использовать для модификации и повторной публикации пакетов, а также на токены GitHub, что можно использовать для создания репозиториев, злоупотребления рабочими процессами и изменения веток. Это делает вариант JavaScript более похожим на червя и позволяет ему распространяться за пределы первоначально зараженной системы.

Наконец, в части зафиксированной активности JavaScript использовался механизм фиксации в системе с помощью deadman switch. Он запускает служебный процесс мониторинга, который проверяет, остается ли украденный токен GitHub действительным, и записывает данные с префиксом IfYouRevokeThisTokenItWillWipeTheComputerOfTheOwner. Если токен впоследствии становится недействительным, служебный процесс мониторинга выполняет деструктивную команду, предназначенную для удаления домашнего каталога пользователя.

Путь выполнения Python/PyPI

Путь Python имеет другую модель выполнения. Скомпрометированный пакет PyPI содержит вредоносный файл __init__.py, который загружает следующий этап – transformers.pyz. В отличие от пути JavaScript, который может выполняться в системах Windows, Linux и macOS, этот вариант Python ограничен Linux-системами.

Перед продолжением полезная нагрузка Python выполняет несколько предварительных проверок. Она завершает работу, если хост не является Linux-системой, если язык системы похож на русский или если машина имеет два или менее CPU-ядер. Она также пытается установить пакет cryptography, если тот отсутствует, и подавляет стандартный вывод и потоки ошибок, чтобы уменьшить видимую активность.

После запуска полезная нагрузка Python работает как агрегатор учетных данных. Она динамически загружает модули-коллекторы и запускает их параллельно, собирая данные из локальных файлов, переменных среды, облачных учетных данных, конфигураций Kubernetes, инстансов Vault, контейнеров Docker, VPN-инструментов и менеджеров паролей, таких как 1Password, Bitwarden, pass и gopass.

Модули сбора, ориентированные на облачные среды, нацелены на AWS, Azure и GCP. Модуль AWS ищет переменные среды, локальные файлы с учетными данными и метаданные инстансов EC2. После этого он пытается получить список значений из AWS Secrets Manager и AWS SSM Parameter Store. Модуль для Azure использует учетные данные служебного принципала, аутентификацию по клиентскому сертификату, кэшированные токены Azure CLI или токены управляемой учетной записи. Это позволяет получить доступ к подпискам Azure и секретам в Azure Key Vault. Модуль для GCP использует файлы служебных аккаунтов, стандартные аккаунты приложений, токены обновления или токены из метаданных. Через них он пытается получить доступ к Google Secret Manager.

Полезная нагрузка также нацелена на среды Kubernetes и Vault.

Модуль для Kubernetes считывает локальные файлы kubeconfig и токены служебных аккаунтов внутри кластера. Затем он пытается найти и расшифровать секреты в доступных пространствах имен и контекстах Kubernetes. Модуль для Vault использует токены из переменных среды, локальных файлов токенов, учетных данных AppRole или интерфейса командной строки Vault. После этого он обходит хранилища секретов типа KV, чтобы получить сохраненные значения секретов.

Перед передачей наружу собранные данные сжимаются и шифруются. Для шифрования собранных данных полезная нагрузка использует AES-256-GCM, а для защиты AES-ключа – RSA-OAEP со встроенным открытым ключом. Сначала она пытается отправить зашифрованный пакет на заранее определенный адрес командно-контрольной конечной точки. Если это не удается, она может искать в коммитах GitHub подписанные сообщения FIRESCALE и использовать проверенный резервный адрес.

Как резервный способ вывода данных, вариант Python ищет GitHub-токены среди собранной информации. Если он находит подходящий токен, создает публичный репозиторий GitHub со случайным названием и загружает зашифрованные результаты в файл results.json.

Поведение вариантов JavaScript и Python

Варианты JavaScript и Python преследуют общую цель: собрать учетные данные и использовать их для дальнейшей компрометации. В то же время, их поведение существенно отличается.

Вариант JavaScript имеет более широкие возможности для атак на цепочку поставок. Он работает на разных платформах, использует Bun для запуска следующих этапов полезной нагрузки, нацеленный на доступ к публикации пакетов в npm и GitHub, а также может изменять npm-пакеты, злоупотреблять GitHub Actions, изменять ветки GitHub и закрепляться в системе.

Вариант Python имеет более узкую поддержку платформ, поскольку запускается только в Linux. В то же время он очень сфокусирован на сборе учетных данных и зашифрованной передаче их наружу. Он содержит отдельные модули (коллекторы) для Azure Key Vault и GCP Secret Manager, а также для AWS, Kubernetes, Vault, локальных файлов, сред Docker, VPN-конфигураций и менеджеров паролей.

Это еще раз показывает, что установку зависимостей и импорт пакетов в автоматизированных средах разработки следует рассматривать как действия, чувствительные с точки зрения безопасности.

Меры по снижению рисков и устранению последствий

  • Необходимо зафиксировать версию вредоносного пакета на безопасной версии, выпущенной до момента компрометации, например, my_package==1.0.0.
  • Также следует отслеживать объявления авторов скомпрометированных пакетов.
  • Репозитории нужно просканировать, чтобы проверить, не были ли они поражены вредоносным ПО. Если инцидент подтвержден, необходимо правильно определить вариант вредоносного ПО.

Для варианта Python:

  1. Удалить службу, обеспечивающую закрепление в системе.
  2. Удалить обнаруженные вредоносные файлы.
  3. Заменить скомпрометированные токены, секреты и пароли.

Для варианта JavaScript:

  1. Удалить службу механизма deadman switch.
  2. Удалить обнаруженные вредоносные файлы.
  3. Заменить скомпрометированные токены, секреты и пароли.

Подписаться на новости