TL, д-р
14 вересня 2025 року дослідники визначили Шай Хулуд, самовідтворюваний черв'як, захований усередині npm-пакети, перетворюючи рутинне оновлення залежностей на повномасштабне атака ланцюга поставокВперше помічений у @ctrl/tinycolor Пакет від Даніеля душ Сантуша Перейри, Shai-Hulud збирає секрети, витягує їх через репозиторії та робочі процеси GitHub та повторно публікує себе в реєстрі, використовуючи викрадені облікові дані. Протягом кількох днів кількість заражених пакетів зросла з десятків до сотень, що підтверджує, що Шайхулуд це не просто черговий троян, а черв'як, призначений для автоматичного поширення по екосистемі npm.
Вплив: Будь-який розробник або виконавець неперевершеної інтеграції, який встановлює публічні npm-пакети, перебуває під загрозою.
Негайні дії: блокувати відомі версії, переходити до встановлення лише з файлів блокування, ротувати токени npm та GitHub, проводити аудит робочих процесів та відстежувати індикатори компрометації (IoC).
Що трапилося?
Команда Атака Shai-Hulud на ланцюг поставок у пакетах npm є одним із найруйнівніших інцидентів за останній час. На відміну від окремих троянів, цей черв'як поєднує в собі крадіжка облікових даних, автоматизоване вилучення та самореплікаціяЯк наслідок, терміни зараження скоротилися з тижнів до лічені години.
Для команд DevOps урок очевидний: якщо кожна інсталяція може виконувати код, то кожне оновлення залежностей є потенційною точкою порушення безпеки.
Можливі початкові векторні та цільові повноваження
Ранній аналіз вказує на те, що атака, ймовірно, розпочалася з вкрадені облікові даніНаприклад, фішингові кампанії, що підробляють npm login або запити MFA могли захопити токени розробника. Щойно зловмисники отримали цю першу точку опори, черв'як поширився, вбудовуючись у пакети npm та крадучи більше секретів з:
- конфігураційні файли npm як
.npmrc, часто містять токени публікації. - Змінні середовища та конфігурації з PAT-файлами GitHub та CI/CD секрети.
- Кінцеві точки метаданих хмари (AWS, GCP, Azure), що забезпечує короткочасні облікові дані для горизонтального переміщення.
Тому крадіжка облікових даних стала стартовим майданчиком. Маючи дійсні токени npm та секрети GitHub, Shai-Hulud міг самостійно реплікуватися в кількох пакетах та репозиторіях без додаткових людських зусиль.
Вплив атаки Шай-Хулуда на ланцюжок поставок на керівництво
Shai-Hulud досі активний. Цей черв'як пришвидшує часові рамки впливу. Те, що колись займало тижні у випадку з трояном, тепер розгортається за лічені години. В результаті, поширення відбувається швидше і його важче стримати. Він просувається шляхом:
- Крадіжка токенів публікації npm та секретів GitHub.
- Повторна публікація себе в інших npm-пакетах.
- Додавання шкідливих робочих процесів GitHub Actions для збереження.
Кого це стосується:
Будь-яка команда, яка встановлює публічні npm-пакети, піддається ризику. Більше того, розробники з кешованими npm-токенами або GitHub стикаються з високим ризиком. Також вразливі CI-виконавці, які використовують секрети широкого спектру.
Бізнес ризик
Вплив на бізнес швидко зростає. Викрадені токени можуть призвести до захоплення облікового запису, викрадення пакетів і навіть зловживання хмарою. Крім того, збереження робочих процесів GitHub ускладнює їх очищення. Тому, команди повинні розглядати Шай-Хулуд як триваючий інцидент, а не як закритий.
Як працює атака Shai-Hulud на ланцюг поставок у npm-пакетах
Цілі та мотиви нападника
Кампанія оптимізується для трьох цілей:
- Перша мета полягає в тому, щоб крадіжка облікових даних у великих масштабах з ноутбуків розробників та виконавців непреривчастої інтеграції. Це включає токени публікації npm, токени GitHub та хмарні облікові дані. Фактично, численні аналізи підтверджують систематичний збір секретних даних, такий як запуск TruffleHog та запити кінцевих точок хмарних метаданих.
- Друга мета полягає в тому, щоб поширюватися автоматично зловживаючи правами на публікацію скомпрометованих розробників. В результаті один плацдарм швидко розширюється на багато, оскільки нові заражені версії інших пакетів з'являються без додаткових людських зусиль.
- Третя мета полягає в тому, щоб зберігаються та надійно виходять назовні через інфраструктуру GitHub. Зловмисники створюють публічний репозиторій під назвою «Shai-Hulud» з подвійною базою64 data.json, а також вони розробляють робочий процес, який серіалізує ${{ toJSON(секрети) }} і публікує його на статичному вебхуку.
Ймовірна винагорода включає довготривалий доступ до реєстрів та вихідного коду, швидкий горизонтальний перехід до хмарних облікових записів та можливість подальшого використання ланцюга поставок як зброї. Публічна звітність показує, що приватні репозиторії перетворюються на публічні з... «-міграція» суфікс, що збільшує охоплення даних та імпульс
Усередині корисного навантаження Шай-Хулуд: bundle.js у пакетах npm
Шай-Хулуд постачається як великий, об'єднаний з Webpack та сильно мініфікований Файл JavaScript (bundle.js, приблизно 3–3.7 МБ) що виконується з після встановлення гачок package.jsonОтже, Кожне встановлення автоматично запускає корисне навантаження. Така конструкція приховує ідентифікатори, стискає потік керування та зводить всю логіку в один артефакт, який виконується під час встановлення. Аналітики постійно підтверджують об'єднання Webpack, незвичайний розмір файлу та виконання під час встановлення.
Риси заплутування та антианалізу, які ви побачите у зразках:
- Мінімізований граф модулів з числовими ідентифікаторами модулів, розрідженими коментарями та сплющеним потоком керування. Більше того, Така структура надзвичайно ускладнює ручну перевірку.
- Приховування рядка через шари base64 та помічники побудови. Наприклад, Повторне кодування та декодування base64 зазвичай з'являється навколо процедур вилучення.
- Динамічна диспетчеризація через евал-стиль шаблонів та згенерованих тіл функцій, що дозволяє коду змінювати поведінку під час виконання.
- Фільтрація ОС надавати перевагу виконанню в Linux та macOS, особливо на комп'ютерах з непреривчастою інтеграцією та ноутбуках розробників.
З функціональної точки зору, комплект є модульним. У статтях описано модулі для виявлення ОС, сканування файлової системи та секретних даних git, доступу до хмарного SDK, операцій API GitHub та механізму поширення, який редагує інші пакети, що належать розробнику. Фактично, StepSecurity та ReversingLabs виділяють функцію, яка автоматично оновлює пакети зі шкідливим гачком.
Виконання під час встановлення в Shai-Hulud: Як npm-пакети запускають хробака
Атака починається, коли після встановлення запускає вузол bundle.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) }} у робочих процесах «Дії» трапляється рідко. Таким чином, Команди повинні розглядати це як індикатор високого сигналу під час полювання.
Очищений шаблон робочого процесу, на який варто звернути увагу
Це незвичайне використання до JSON (секрети) «Дії» є важливим індикатором у цьому інциденті.
Псевдокод поширення високого рівня (безпечний, описовий)
Аналітики спостерігали цей цикл у великих масштабах, що пояснює швидкий стрибок від десятків до сотень заражених пакетів.
Чому це черв'як в екосистемі пакетів
Черв'як — це шкідливе програмне забезпечення, яке поширюється самостійно, не вимагаючи ручних дій оператора на кожному етапі. В операційних системах черв'яки зазвичай використовують мережеві вразливості для переходу з однієї машини на іншу. Натомість Shai-Hulud працює всередині реєстру npm. Його ефективний шлях лежить через повторне використання облікових даних.
Черв'як використовує викрадені токени публікації npm. Щойно він отримує дійсні облікові дані, він повторно публікує заражені версії в інших пакетах, що належать тому ж розробнику. Згодом ці пакети встановлюються нічого не підозрюючими розробниками або CI-менеджерами, і цикл повторюється.
З цієї причини аналітики з безпеки, зокрема Темне читання, класифікують Шай-Хулуда як самовідтворюваний черв'як а не простий троян чи інцидент з помилкою в опечатці. Різниця важлива: троян зазвичай компрометує один хост, але черв'як автоматично посилює свій вплив на всю екосистему.
Шпаргалка «Як це працює»
Підсумовуючи життєвий цикл Шай-Хулуда, ось один недолікcisрозбивка його основних етапів:
- Пакет з після встановлення встановлено, і
bundle.jsвиконує. - Корисне навантаження виводить змінні середовища, сканує файли та історію git, запускає ТрюфельнийХогінта запитує хмарні сервіси метаданих. Отже, будь-який знайдений секрет одразу стає корисним.
- Вилучення відбувається двома способами: по-перше, шляхом створення публічного репозиторію під назвою Шай Хулуд з подвійним кодуванням base64
data.jsonпо-друге, шляхом впровадження робочого процесу GitHub Actions, який публікує${{ toJSON(secrets) }}до вебхука. - Використовуючи будь-який вкрадений токен npm, черв'як повторно публікує всі інші пакети, що належать скомпрометованому розробнику, з тим самим шкідливим гачком. Таким чином, інфекція швидко розмножується.
- Зрештою, зловмисник має більше секретів, більше пакетів для поширення та наполегливість всередині облікових записів та репозиторіїв GitHub.
Як уникнути цього класу атак на практиці
Шай-Хулуд – це тривожний дзвінок. Черв'як, який краде токени та перепублікує себе, не є ризиком у майбутньому, він активно працює в екосистема пакетів npm сьогодні. Щоб запобігти цьому типу атака ланцюга поставоккомандам потрібні засоби контролю, які можна програмувати, автоматизувати та застосовувати безпосередньо CI/CD pipelineс. Це ті самі захисні засоби, які ви вже можете реалізувати за допомогою Ксігені.
Зупиніть погані артефакти біля воріт
Вам слід сканувати npm-пакети та tar-архіви, перш ніж вони потраплять до розробників або завдань непреривної інтеграції. bundle.js файли, підозрілі після встановлення hooks, а маркери обфускації слугують ранніми тривожними сигналами. Крім того, забезпечення періодів охолодження та закріплення версій у pipelines запобігає автоматичному споживанню нових, неперевірених релізів.
Затвердіти CI/CD за замовчуванням
Guardrails in CI/CD є важливими. Вони відхиляють злиття або встановлення, які вводять нові скрипти чи бінарні файли. Водночас вони блокують робочі процеси, які серіалізують секрети або намагаються публікувати зовнішні повідомлення. Команди також повинні вимагати встановлення лише з файлами блокування (npm ci) по всіх pipelineтому набори залежностей залишаються відтворюваними та безпечними.
Зменшити радіус вибуху жетонів
Секрети не повинні ставати єдиними точками відмови. Постійно скануйте код, конфігурації та pipeline вихід для розкриті облікові даніТокени повинні мати вузьку область дії, короткий термін їх існування та автоматично змінюватися при виявленні впливу. Як правило, будь-який токен, що використовується на хості, який виконав підозрілу постімплантаційну операцію, слід вважати скомпрометованим.
Виявляйте поведінку черв'яків на ранній стадії
Виявлення аномалії є ключовим. Наприклад, раптові сплески подій публікації npm, нові робочі процеси, що з'являються без причини, або нові публічні репозиторії, заповнені дивними закодованими файлами, можуть сигналізувати про активність хробаків. Тому команди повинні швидко попереджати та ізолювати будь-яких розробників або виконавців, які показують ці попереджувальні ознаки.
Швидке виправлення без порушення збірок
Швидкість і безпека повинні йти поруч. Автоматизовано pull requests може замінити скомпрометовані npm-пакети перевіреними версіями. Крім того, доступність та експлуатаційність Аналіз гарантує, що оновлення залишаться мінімальними та стабільними. Нарешті, після підтвердження впливу, відновіть уражені CI-виконавці з чистих образів, запобігаючи подальшому поширенню атаки.
Показники компромісу (IoC)
Аналізуючи Шай-Хулуд, команди повинні звертати увагу на обидва статичні 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.
- Нещодавно створені публічні репозиторії із закодованими блоб-об'єктами.
Швидке полювання
Висновок: Уроки Шай-Хулуда
Команда Атака на ланцюг поставок Шай-Хулуд у npm-пакетах показує, наскільки крихким став сучасний ланцюг поставок програмного забезпечення. Цей черв'як зробив більше, ніж просто додав шкідливий код. Він крав токени, надсилав дані, а потім автоматично перевидавався. Через це атака поширилася за лічені години, а не тижні.
Для розробників та DevOps-команд уроки очевидні:
- Кожна інсталяція запускає код. Навіть звичайний npm-пакет може приховувати постісталювального хробака.
- Кожен токен має високу вартість. Після крадіжки його можна використовувати для подальшого поширення шкідливого програмного забезпечення.
- Кожен pipeline потребує перевірок. Без guardrails щодо залежностей, робочих процесів та секретів, один компроміс може швидко вплинути на продакшн.
Тому для зупинки таких атак, як Shai-Hulud, потрібні автоматичні та прості у застосуванні засоби контролю. Команди повинні сканувати npm-пакети перед встановленням, використовувати збірки lockfile, виявляти дивну публікаційну активність та тримати токени короткочасними. Ці кроки більше не є необов'язковими. Натомість вони є основою стійкості в сучасних умовах. pipelines.
У Xygeni ми розглядаємо атаку Shai-Hulud на ланцюг поставок як попередження для всієї екосистеми відкритого коду. Сталий шлях вперед полягає у безпосередньому впровадженні безпеки ланцюга поставок у процес розробки, на етапі, коли код, npm-пакети та pipelineз’єднання.
Нижче наведено повний список пакетів та версій npm, які були скомпрометовані в Shai-Hulud. Використовуйте його для перевірки файлів блокування, реєстрів та неперервної інтеграції. pipelines для експозиції.
Список скомпрометованих пакетів
📦 Попередній перегляд скомпрометованих npm-пакетів
| Ім'я пакета | версія | Дата публікації |
|---|---|---|
| спрощений механізм керування правилами json | 0.2.1 | 2025-09-14T17:58:51.203Z |
| аеропілот | 0.8.8 | 2025-09-14T18:35:07.600Z |
| mcp-граф-знань | 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 |
| tvi-cli | 0.1.5 | 2025-09-14T18:35:10.996Z |
| @thangved/вікно зворотного виклику | 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/демо | 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/валідація | 0.1.6 | 2025-09-14T20:45:55.595Z |
| @hestjs/core | 0.2.1 | 2025-09-14T20:45:55.888Z |
➡️ Переглянути повний список скомпрометованих пакетів
| Ім'я пакета | версія | Дата публікації |
|---|---|---|
| спрощений механізм керування правилами json | 0.2.1 | 2025-09-14T17:58:51.203Z |
| аеропілот | 0.8.8 | 2025-09-14T18:35:07.600Z |
| mcp-граф-знань | 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 |
| tvi-cli | 0.1.5 | 2025-09-14T18:35:10.996Z |
| @thangved/вікно зворотного виклику | 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/демо | 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/валідація | 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/скаляр | 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 |
| конденсатор-плагін-здоров'я-app | 0.0.2 | 2025-09-15T04:54:48.704Z |
| дозволи конденсатора Android | 0.0.4 | 2025-09-15T04:54:48.753Z |
| VoIP-дзвінки | 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-сервер | 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/веб-додаток | 1.0.3 | 2025-09-15T05:21:20.383Z |
| @art-ws/ssl-info | 1.0.9 | 2025-09-15T05:21:20.927Z |




