Атака началась не с нуля. Группировка TeamPCP, специализирующаяся на облачных системах, сначала опубликовала троянизированные релизы Trivy — популярного инструмента для сканирования уязвимостей. Конкретно под удар попала версия 0.69.4. Внутри был встроен похититель учётных данных. Именно украденные npm-токены стали топливом для всего того, что последовало дальше. Прошли почти сутки — и в реестре npm появился червь.

Исследователь безопасности Чарли Эриксен из Aikido Security первым зафиксировал заражение. На тот момент вредоносный код был обнаружен в 47 пакетах: 28 из них принадлежали области
Вредоносное ПО получило имя CanisterWorm. Эксперты из Endor Labs также называют его Shai-Hulud. По оценке аналитиков, код написан в стиле "vibe coding" — с помощью AI-инструмента, что хорошо читается по структуре файлов. Это, впрочем, не сделало его менее опасным.
Механизм заражения запускается через
Бэкдор закрепляется в системе через systemd user service с директивой
Канистра сейчас возвращает ссылку на YouTube — точнее, на «рикролл». Это не сбой и не ирония. Если в полученном URL содержится
Самое примечательное в этой атаке — её эволюция. На первом этапе в пакетах находился файл
В файле
Хенрик Плейт, руководитель исследований безопасности в Endor Labs, точно описал суть проблемы: похищение учётных данных через
Компании Wiz, JFrog, Socket, Aikido Security и Endor Labs сходятся в классификации: это двойная угроза. Пакет одновременно собирает учётные данные и сбрасывает малварь. Wiz дополнительно зафиксировала Python-дроппер

Изображение носит иллюстративный характер
Исследователь безопасности Чарли Эриксен из Aikido Security первым зафиксировал заражение. На тот момент вредоносный код был обнаружен в 47 пакетах: 28 из них принадлежали области
@EmilGroup, 16 — @opengov, плюс отдельные пакеты @teale.io/eslint-config, @airtm/uuid-base32 и @pypestream/floating-ui-dom. Компания Socket обновила эти цифры позже — 141 вредоносный артефакт, более 66 уникальных пакетов. Расползалось быстро. Вредоносное ПО получило имя CanisterWorm. Эксперты из Endor Labs также называют его Shai-Hulud. По оценке аналитиков, код написан в стиле "vibe coding" — с помощью AI-инструмента, что хорошо читается по структуре файлов. Это, впрочем, не сделало его менее опасным.
Механизм заражения запускается через
postinstall-хук — стандартный крючок жизненного цикла npm-пакета, который выполняется автоматически при установке. Хук загружает Python-бэкдор. Тот, в свою очередь, обращается не к обычному C2-серверу, а к ICP-канистре — защищённому смарт-контракту на блокчейне Internet Computer. Это первый публично задокументированный случай, когда малварь использует ICP-канистру как нетейкдаун-устойчивый dead drop для получения адреса командного сервера следующего уровня. Традиционный C2 можно заблокировать. Смарт-контракт на блокчейне — значительно сложнее. Бэкдор закрепляется в системе через systemd user service с директивой
Restart=always. Если процесс убить — он перезапустится через 5 секунд. Сервис маскируется под PostgreSQL-инструментарий и называется pgmon. Каждые 50 минут бэкдор отправляет запрос к ICP-канистре, используя подделанный User-Agent браузера, и получает в ответ обычный текстовый URL. Канистра поддерживает три метода: get_latest_link, http_request и update_link. Полученный URL парсится и исполняется. Старые бинарники при этом не завершаются — они просто продолжают работать в фоне. Канистра сейчас возвращает ссылку на YouTube — точнее, на «рикролл». Это не сбой и не ирония. Если в полученном URL содержится
youtube[.]com, скрипт пропускает его и ничего не делает. Атакующие используют YouTube-ссылку как переключатель спящего режима: оружие вооружается переключением канистры на реальный бинарник через метод update_link, и разоружается возвратом на YouTube. На этапе тестирования цепочки заражения злоумышленники временно выставляли строку hello123 — чтобы убедиться, что вся инфраструктура работает до того, как выкатить настоящую нагрузку. Самое примечательное в этой атаке — её эволюция. На первом этапе в пакетах находился файл
deploy.js — автономный инструмент развёртывания, который атакующий запускал вручную с украденными токенами, чтобы заталкивать вредоносный код в реестр. Это трудоёмко и требует участия человека. Версии CanisterWorm 1.8.11 и 1.8.12 изменили правила. В файле
index.js появилась функция findNpmTokens(). В момент выполнения postinstall-хука червь сканирует окружение разработчика в поисках npm-токенов аутентификации. Как только токен найден, deploy.js немедленно запускается как отдельный фоновый процесс с этим токеном. Машина разработчика или CI-пайплайн превращаются в новый вектор распространения — без какого-либо ручного вмешательства со стороны атакующих. Хенрик Плейт, руководитель исследований безопасности в Endor Labs, точно описал суть проблемы: похищение учётных данных через
postinstall-хуки само по себе не редкость. Но способность мгновенно использовать украденные токены для перепубликации пакетов жертвы — это другой уровень. Один взломанный разработчик становится точкой распространения для всех, кто пользуется его пакетами. Цепочка расширяется экспоненциально. Компании Wiz, JFrog, Socket, Aikido Security и Endor Labs сходятся в классификации: это двойная угроза. Пакет одновременно собирает учётные данные и сбрасывает малварь. Wiz дополнительно зафиксировала Python-дроппер
sysmon.py. Скомпрометированными оказались также релизы trivy-action и setup-trivy — инструменты, которые активно используются в CI/CD-пайплайнах. То есть заражение могло проходить не только через машины разработчиков, но и через автоматизированные сборочные процессы в продакшене.