TL, д-р
14 сентября 2025 года исследователи обнаружили Шай-Хулуд, самовоспроизводящийся червь, скрытый внутри пакеты нпм, превращая обычное обновление зависимостей в полномасштабное атака цепочки поставок. Впервые замечен в @ctrl/tinycolor В пакете Даниэля дос Сантоса Перейры Shai-Hulud собирает секретные данные, просматривает их через репозитории и рабочие процессы GitHub и повторно публикует себя в реестре, используя украденные учетные данные. В течение нескольких дней число зараженных пакетов выросло с десятков до сотен, что подтверждает, что Шайхудуд это не просто очередной троян, а червь, предназначенный для автоматического распространения по экосистеме npm.
Влияние: Любой разработчик или исполнитель непрерывной интеграции, устанавливающий публичные пакеты npm, подвергается риску.
Немедленные действия: блокируйте известные версии, переключайтесь на установку только с помощью файлов блокировки, проводите ротацию токенов npm и GitHub, проверяйте рабочие процессы и отслеживайте индикаторы компрометации (IoC).
Что случилось?
Команда Атака на цепочку поставок Шаи-Хулуда в пакетах npm Это один из самых разрушительных инцидентов за последнее время. В отличие от отдельных троянов, этот червь сочетает в себе кража учетных данных, автоматическая эксфильтрация и саморепликация. В результате сроки заражения сократились с недель до нескольких часов.
Для команд DevOps урок ясен: если каждая установка может выполнять код, то каждое обновление зависимостей является потенциальной точкой нарушения.
Возможный начальный вектор и целевые учетные данные
Ранний анализ указывает на то, что атака, вероятно, началась с украденные учетные данные. Например, фишинговые кампании, подделывающие npm login или запросы MFA могли перехватить токены разработчика. Как только злоумышленники закрепились на этой первой позиции, червь распространялся, внедряясь в пакеты npm и похищая дополнительные секреты из:
- файлы конфигурации npm " У аборигенов
.npmrc, часто содержащие токены публикации. - Переменные среды и конфигурации с GitHub PAT и CI/CD секреты.
- Конечные точки облачных метаданных (AWS, GCP, Azure), дающие кратковременные полномочия для бокового перемещения.
Таким образом, кража учётных данных стала стартовой площадкой. Имея действительные токены npm и секреты GitHub, Shai-Hulud мог самовоспроизводиться в нескольких пакетах и репозиториях без дополнительных человеческих усилий.
Влияние атаки на цепочку поставок Шаи-Хулуда на руководство
Shai-Hulud активен и по сей день. Этот червь ускоряет сроки воздействия. То, что раньше занимало недели при использовании трояна, теперь разворачивается за часы. В результате распространение происходит быстрее и его сложнее сдержать. Он продвигается за счет:
- Кража токенов публикации npm и секретов GitHub.
- Перепубликация в других пакетах npm.
- Добавление вредоносных рабочих процессов GitHub Actions для обеспечения устойчивости.
Кто затронут:
Любая команда, устанавливающая публичные пакеты npm, подвергается риску. Более того, разработчики с кэшированными токенами npm или GitHub подвергаются высокому риску. Непрерывные исполнители, использующие секреты с широкой областью действия, также уязвимы.
Деловой риск
Влияние на бизнес быстро растёт. Украденные токены могут привести к захвату учётных записей, перехвату пакетов и даже нецелевому использованию облака. Кроме того, постоянное присутствие в рабочих процессах GitHub затрудняет очистку. Поэтомукоманды должны относиться к Шаи-Хулуду как к продолжающемуся инциденту, а не закрытому.
Как работает атака на цепочку поставок Шаи-Хулуд в пакетах npm
Цели и мотивы нападающего
Кампания оптимизируется по трем параметрам:
- Первая цель - кража учетных данных в больших масштабах с ноутбуков разработчиков и CI-серверов. Сюда входят токены публикации npm, токены GitHub и учётные данные в облаке. Фактически, многочисленные анализы подтверждают систематический сбор секретных данных, например, запуск TruffleHog и запросы к конечным точкам метаданных облака.
- Вторая цель — распространяются автоматически злоупотребляя правами на публикацию скомпрометированных разработчиков. В результате один плацдарм быстро разрастается во множество, поскольку новые зараженные версии других пакетов появляются без дополнительных человеческих усилий.
- Третья цель — надежно сохраняться и эксфильтроваться через инфраструктуру GitHub. Злоумышленники создают публичный репозиторий под названием «Shai-Hulud» с двойной кодировкой base64. данные.json, и кроме того, они внедряют рабочий процесс, который сериализует ${{ toJSON(секреты) }} и отправляет его в статический вебхук.
Вероятный выигрыш включает в себя долгосрочный доступ к реестрам и исходному коду, быстрое горизонтальное перемещение в облачные аккаунты и возможность дальнейшего использования цепочки поставок в качестве оружия. Публичные отчёты показывают, что частные репозитории были преобразованы в публичные с «-миграция» суффикс, который увеличивает доступность данных и импульс
Внутри полезной нагрузки Шаи-Хулуда: пакет.js в пакетах npm
Шаи-Хулуд поставляется как большой, упакованный в Webpack и сильно минифицированный Файл JavaScript (пакет.js, около 3–3.7 МБ) который выполняется из послеустановка крючок в пакет.json. Следовательно, Каждая установка автоматически запускает полезную нагрузку. Такая конструкция скрывает идентификаторы, сжимает поток управления и объединяет всю логику в единый артефакт, который выполняется во время установки. Аналитики постоянно подтверждают наличие пакета Webpack, необычный размер файла и выполнение во время установки.
Черты запутывания и антианализа, которые вы увидите в образцах:
- Минимизированный модульный граф с числовыми идентификаторами модулей, редкими комментариями и упрощённым потоком управления. Более того,, такая структура делает ручную проверку крайне сложной.
- Скрытие строк через слои base64 и вспомогательные инструменты построения. Например,, Повторное кодирование и декодирование base64 обычно происходит во время процедур эксфильтрации.
- Динамическая отправка через Evalшаблоны стилей и генерируемые тела функций, что позволяет коду изменять поведение во время выполнения.
- Фильтрация ОС предпочесть выполнение Linux и macOS, особенно на CI-платформах и ноутбуках разработчиков.
С функциональной точки зрения комплект является модульным. В записях описываются модули для обнаружения ОС, сканирования файловой системы и секретов Git, доступа к облачному SDK, операций с API GitHub и механизма распространения, который редактирует другие пакеты, принадлежащие разработчику. Более того, StepSecurity и ReversingLabs выделяют функцию, которая автоматически обновляет пакеты с вредоносным хуком.
Выполнение во время установки в Шаи-Хулуде: как пакеты npm запускают червя
Атака начинается, когда postinstall запускает узел пакет.js. На этом этапе скрипт инициализируется и распаковывает рабочее состояние в память, подготавливая почву для полноценной работы червя.
Открытие и сбор урожая
- Полезная нагрузка создаёт дамп process.env и сканирует локальные файлы на наличие высокоэнтропийных секретов и префиксов токенов. Кроме того, она расширяет охват, запуская TruffleHog.
- Он запрашивает конечные точки облачных метаданных для сбора краткосрочных учетных данных. Например, звонки в
169.254.169.254на AWS илиmetadata.google.internalна GCP часто появляются у инфицированных хозяев. - Следовательно, любые найденные учетные данные сразу же становятся пригодными для публикации новых пакетов npm или отправки рабочих процессов GitHub.
эксфильтрации
- Червь создает новый репозиторий GitHub под названием Шай-Хулуд и записывает двойной код в формате base64
data.jsonс информацией о платформе, дампами окружения и секретами. Как видите, это шумное поведение легко заметить, если защитники знают, куда смотреть. - Он также запускает рабочий процесс GitHub Actions, часто на ветке с именем шай-хулуд, который сериализует
${{ toJSON(secrets) }}и отправляет данные в статический вебхук. Более того, этот рабочий процесс сохраняется до тех пор, пока кто-то его активно не удалит.
Распространение
- При наличии любого обнаруженного токена npm полезная нагрузка перечисляет все пакеты, принадлежащие скомпрометированному сопровождающему. Затем она извлекает каждый tar-архив, внедряет bundle.js и запись postinstall, а затем повторно публикует пакет.
- В результате за считанные часы могут появиться десятки зараженных пакетов, многократно увеличивая радиус поражения в экосистеме.
Настойчивость и воздействие
Червь поддерживает вредоносные рабочие процессы активными и в некоторых случаях превращает частные репозитории в публичные с помощью «-миграция» суффикс. В совокупности это обеспечивает злоумышленнику сохранение позиции и максимизирует утечку данных.
Примечание по обнаружению ключа
Это необычное использование ${{ toJSON(secrets) }} в рабочих процессах Actions встречается редко. Следовательно, Команды должны воспринимать это как сигнал высокого уровня во время охоты.
Упрощенная модель рабочего процесса, за которой стоит следить
Это необычное использование в JSON(секреты) в Действиях - это высокосигнальный индикатор в данном инциденте.
Псевдокод распространения высокого уровня (безопасный, описательный)
async function propagate(token, owner) {
const pkgs = await npmApi.listPackages(owner, token);
for (const p of pkgs) {
const tgz = await npmApi.fetchTarball(p, token);
const modified = injectBundleAndPostinstall(tgz); // adds bundle.js + "postinstall"
await npmApi.publish(modified, token); // publishes new malicious version
}
}
Аналитики наблюдали эту петлю в больших масштабах, что объясняет быстрый скачок от десятков до сотен зараженных пакетов.
Почему это червь в экосистеме пакетов
Червь — это вредоносное ПО, которое распространяется самостоятельно, не требуя ручного вмешательства пользователя на каждом этапе. В операционных системах черви обычно используют сетевые уязвимости для перемещения с одного компьютера на другой. В отличие от него, Shai-Hulud работает внутри реестра npm. Его эффективный путь — через повторное использование учетных данных.
Червь использует украденные npm-токены публикации. Как только он получает действительные учётные данные, он перепубликовывает заражённые версии в других пакетах, принадлежащих тому же мейнтейнеру. Впоследствии эти пакеты устанавливаются ничего не подозревающими разработчиками или исполнителями непрерывной интеграции, и цикл повторяется.
По этой причине аналитики безопасности, в том числе Темное Чтение, классифицируют Шаи-Хулуд как самореплицирующийся червь а не просто троян или инцидент с тайпсквоттингом. Разница существенная: троян обычно атакует один хост, а червь автоматически усиливает своё воздействие на всю экосистему.
Шпаргалка «Как это работает»
Чтобы подвести итог жизненному циклу Шаи-Хулуда, вотcisРазбивка его основных этапов:
- Пакет с послеустановка установлен, и
bundle.jsвыполняет. - Полезная нагрузка выводит переменные среды, сканирует файлы и историю git, запускается TruffleHogи запрашивает облачные метаданные. Следовательно, любой найденный секрет сразу же становится полезным.
- Эксфильтрация происходит двумя способами: во-первых, путем создания публичного репозитория с именем Шай-Хулуд с двойной кодировкой base64
data.json; во-вторых, путем внедрения рабочего процесса GitHub Actions, который публикует${{ toJSON(secrets) }}к вебхуку. - Используя любой украденный токен npm, червь переиздает все остальные пакеты, принадлежащие скомпрометированному мейнтейнеру, используя тот же вредоносный хук. Таким образом, заражение быстро размножается.
- Наконец, злоумышленник имеет больше секретов, больше пакетов для распространения и настойчивость внутри аккаунтов и репозиториев GitHub.
Как избежать этого класса атак на практике
Шаи-Хулуд — это тревожный сигнал. Червь, ворующий токены и переиздающий себя, не представляет угрозы в будущем, он уже существует. экосистема пакетов npm Сегодня. Чтобы предотвратить этот тип атака цепочки поставоккомандам нужны элементы управления, которые можно программировать, автоматизировать и применять непосредственно в CI/CD pipelines. Это те же самые средства защиты, которые вы уже можете реализовать. Ксигени.
Остановите плохие артефакты у ворот
Пакеты npm и tar-архивы следует сканировать до того, как они попадут к разработчикам или в задачи непрерывной интеграции. bundle.js файлы, подозрительные послеустановочные hooksи маркеры обфускации служат ранними сигналами тревоги. Более того, применение периодов охлаждения и закреплённых версий pipelines предотвращает автоматическое потребление свежих, непроверенных релизов.
затвердеть CI/CD по умолчанию
Guardrails in CI/CD Они необходимы. Они отклоняют слияния или установки, которые вводят новые скрипты или двоичные файлы. В то же время они блокируют рабочие процессы, которые сериализуют секреты или пытаются отправлять внешние сообщения. Командам также следует требовать установки только с файлами блокировки (npm ci) по всем pipelineпоэтому наборы зависимостей остаются воспроизводимыми и безопасными.
Уменьшить радиус взрыва токенов
Секреты не должны стать едиными точками отказа. Постоянно проверяйте код, конфигурации и pipeline выход для раскрытые учетные данныеТокены должны иметь узкую область применения, короткий срок жизни и автоматически ротироваться при обнаружении уязвимости. Как правило, любой токен, используемый на хосте, выполнившем подозрительную пост-установку, следует считать скомпрометированным.
Наблюдайте за поведением червей на ранней стадии
Обнаружение аномалий Это ключевой момент. Например, внезапные всплески событий публикации npm, новые рабочие процессы, появляющиеся без причины, или новые публичные репозитории, заполненные файлами со странной кодировкой, — всё это может быть признаком активности червя. Поэтому командам следует быстро сообщать об этом и изолировать всех разработчиков или исполнителей, у которых наблюдаются подобные признаки.
Быстрое исправление без нарушения сборки
Скорость и безопасность должны идти рука об руку. Автоматизировано. pull requests можно заменить скомпрометированные пакеты npm проверенными версиями. Кроме того, достижимость и уязвимостей Анализ гарантирует минимальное количество обновлений и стабильность. Наконец, после подтверждения заражения восстановите затронутые CI-маршрутизаторы из чистых образов, предотвращая дальнейшее распространение атаки.
Индикаторы компрометации (IoCs)
При анализе Шаи-Хулуда командам следует обращать внимание на оба фактора: статические IoC в файлах и поведенческие IoC in pipelines. В совокупности эти сигналы помогают обнаружить заражение на ранней стадии и принять меры до того, как червь распространится дальше.
Статические IoC
Наблюдается соответствие следующих дайджестов SHA-256 bundle.js образцы:
- 46faab8ab153fae6e80e7cca38eab363075bb524edd79e42269217a083628f09
- 81d2a004a1bca6ef87a1caf7d0e0b355ad1764238e40ff6d1b1cb77ad4f595c3
- dc67467a39b70d1cd4c1f7f7a459b35058163592f4a9e8fb4dffcbba98ef210c
Кроме того, обратите внимание на следующие повторяющиеся закономерности:
- A
bundle.jsв корне пакета. "postinstall": "node bundle.js"внутриpackage.json.- Репозитории названы Шай-Хулуд.
- Рабочие процессы GitHub, содержащие
${{ toJSON(secrets) }}.
Поведенческие IoC
Помимо сигнатур файлов, активность червя проявляется через поведение. Например:
- Внезапные всплески событий публикации npm от одного сопровождающего.
- Новые рабочие процессы, передающие данные на внешние конечные точки.
- Исходящие запросы POST, инициированные исполнителями CI.
- Недавно созданные публичные репозитории с закодированными блоками данных.
Быстрая охота
# Find postinstall in package.json
grep -R --line-number '"postinstall"' --include="package.json" /path/to/archives
# Detect tarballs with bundle.js
find /path/to/tarballs -name "*.tgz" -print0 \
| xargs -0 -n1 -I{} sh -c 'tar -tf "{}" | grep bundle.js && echo "== {}"'
# Search workflows for toJSON(secrets)
grep -R --line-number "toJSON(secrets)" --include="*.yml" .github || true
Заключение: уроки Шаи-Хулуда
Команда Атака на цепочку поставок Шаи-Хулуда В пакетах npm показано, насколько хрупкой стала современная цепочка поставок программного обеспечения. Этот червь не просто добавил вредоносный код. Он похитил токены, отправил данные, а затем автоматически опубликовал себя заново. Благодаря этому атака распространилась за считанные часы, а не за несколько недель.
Для разработчиков и команд DevOps уроки очевидны:
- Каждая установка запускает код. Даже обычный пакет npm может скрывать в себе червя, устанавливаемого после установки.
- Каждый токен имеет высокую ценность. После кражи его можно использовать для дальнейшего распространения вредоносного ПО.
- Каждая pipeline нужны проверки. Без guardrails в отношении зависимостей, рабочих процессов и секретов любая компрометация может быстро нанести удар по производству.
Поэтому для предотвращения атак, подобных Shai-Hulud, необходимы автоматизированные и легко реализуемые средства контроля. Команды должны сканировать пакеты npm перед установкой, использовать сборки с файлами блокировки, выявлять подозрительную активность публикации и обеспечивать короткий срок действия токенов. Эти шаги больше не являются обязательными. Напротив, они являются основой устойчивости в современных системах. pipelines.
В Xygeni мы рассматриваем атаку на цепочку поставок Шаи-Хулуд как предупреждение для всей экосистемы открытого исходного кода. Устойчивый путь развития — это внедрение безопасности цепочки поставок непосредственно в процесс разработки, на этапе, где код, пакеты npm и… pipelineс подключением.
Ниже представлен полный список пакетов npm и их версий, скомпрометированных в Шаи-Хулуде. Используйте его для проверки файлов блокировки, реестров и непрерывной интеграции. pipelines для экспозиции.
Список скомпрометированных пакетов
📦 Предварительный просмотр скомпрометированных пакетов npm
| Имя пакета | Версия | Дата публикации |
|---|---|---|
| json-rules-engine-simplified | 0.2.1 | 2025-09-14T17:58:51.203Z |
| воздушный пилот | 0.8.8 | 2025-09-14T18:35:07.600Z |
| mcp-knowledge-graph | 1.2.1 | 2025-09-14T18:35:09.494Z |
| начальник авиации | 0.3.1 | 2025-09-14T18:35:09.521Z |
| прыжковые ворота | 0.0.2 | 2025-09-14T18:35:09.651Z |
| тви-кли | 0.1.5 | 2025-09-14T18:35:10.996Z |
| @thangved/callback-window | 1.1.4 | 2025-09-14T20:31:38.479Z |
| @tnf-dev/api | 1.0.8 | 2025-09-14T20:31:39.547Z |
| @tnf-dev/js | 1.0.8 | 2025-09-14T20:31:41.251Z |
| @tnf-dev/mui | 1.0.8 | 2025-09-14T20:31:41.259Z |
| @tnf-dev/core | 1.0.8 | 2025-09-14T20:31:42.728Z |
| @teselagen/react-table | 6.10.20 | 2025-09-14T20:37:08.597Z |
| @hestjs/demo | 0.1.2 | 2025-09-14T20:45:52.348Z |
| @nexe/eslint-config | 0.1.1 | 2025-09-14T20:45:53.625Z |
| @hestjs/eslint-config | 0.1.2 | 2025-09-14T20:45:55.044Z |
| @nexe/config-manager | 0.1.1 | 2025-09-14T20:45:55.066Z |
| @nexe/logger | 0.1.3 | 2025-09-14T20:45:55.170Z |
| @hestjs/logger | 0.1.6 | 2025-09-14T20:45:55.197Z |
| @hestjs/validation | 0.1.6 | 2025-09-14T20:45:55.595Z |
| @hestjs/core | 0.2.1 | 2025-09-14T20:45:55.888Z |
➡️ Просмотреть полный список скомпрометированных пакетов
| Имя пакета | Версия | Дата публикации |
|---|---|---|
| json-rules-engine-simplified | 0.2.1 | 2025-09-14T17:58:51.203Z |
| воздушный пилот | 0.8.8 | 2025-09-14T18:35:07.600Z |
| mcp-knowledge-graph | 1.2.1 | 2025-09-14T18:35:09.494Z |
| начальник авиации | 0.3.1 | 2025-09-14T18:35:09.521Z |
| прыжковые ворота | 0.0.2 | 2025-09-14T18:35:09.651Z |
| тви-кли | 0.1.5 | 2025-09-14T18:35:10.996Z |
| @thangved/callback-window | 1.1.4 | 2025-09-14T20:31:38.479Z |
| @tnf-dev/api | 1.0.8 | 2025-09-14T20:31:39.547Z |
| @tnf-dev/js | 1.0.8 | 2025-09-14T20:31:41.251Z |
| @tnf-dev/mui | 1.0.8 | 2025-09-14T20:31:41.259Z |
| @tnf-dev/core | 1.0.8 | 2025-09-14T20:31:42.728Z |
| @teselagen/react-table | 6.10.20 | 2025-09-14T20:37:08.597Z |
| @hestjs/demo | 0.1.2 | 2025-09-14T20:45:52.348Z |
| @nexe/eslint-config | 0.1.1 | 2025-09-14T20:45:53.625Z |
| @hestjs/eslint-config | 0.1.2 | 2025-09-14T20:45:55.044Z |
| @nexe/config-manager | 0.1.1 | 2025-09-14T20:45:55.066Z |
| @nexe/logger | 0.1.3 | 2025-09-14T20:45:55.170Z |
| @hestjs/logger | 0.1.6 | 2025-09-14T20:45:55.197Z |
| @hestjs/validation | 0.1.6 | 2025-09-14T20:45:55.595Z |
| @hestjs/core | 0.2.1 | 2025-09-14T20:45:55.888Z |
| @hestjs/cqrs | 0.1.6 | 2025-09-14T20:45:55.966Z |
| @hestjs/scalar | 0.1.7 | 2025-09-14T20:45:56.386Z |
| ng2-файл-загрузка | 7.0.3 | 2025-09-15T02:44:29.555Z |
| обработчик уведомлений конденсатора | 0.0.2 | 2025-09-15T04:54:48.431Z |
| конденсатор-плагин-vonage | 1.0.2 | 2025-09-15T04:54:48.501Z |
| конденсатор-плагин-healthapp | 0.0.2 | 2025-09-15T04:54:48.704Z |
| разрешения для конденсатора и Android | 0.0.4 | 2025-09-15T04:54:48.753Z |
| voip-callkit | 1.0.2 | 2025-09-15T04:54:49.223Z |
| конденсатор-плагин-ihealth | 1.1.8 | 2025-09-15T04:55:08.113Z |
| @art-ws/common | 2.0.22 | 2025-09-15T05:21:15.411Z |
| @art-ws/config-eslint | 2.0.4 | 2025-09-15T05:21:17.199Z |
| ngx-ws | 1.1.5 | 2025-09-15T05:21:17.514Z |
| @art-ws/slf | 2.0.15 | 2025-09-15T05:21:17.524Z |
| @art-ws/http-server | 2.0.21 | 2025-09-15T05:21:17.745Z |
| pm2-gelf-json | 1.0.4 | 2025-09-15T05:21:18.413Z |
| @art-ws/di | 2.0.28 | 2025-09-15T05:21:18.488Z |
| @art-ws/di-node | 2.0.13 | 2025-09-15T05:21:18.849Z |
| @art-ws/config-ts | 2.0.7 | 2025-09-15T05:21:19.408Z |
| @art-ws/db-context | 2.0.21 | 2025-09-15T05:21:19.814Z |
| @art-ws/openapi | 0.1.9 | 2025-09-15T05:21:19.969Z |
| @art-ws/web-app | 1.0.3 | 2025-09-15T05:21:20.383Z |
| @art-ws/ssl-info | 1.0.9 | 2025-09-15T05:21:20.927Z |



