Атака на npm: 14 пакетов-двойников охотились за секретами AWS, Vault и CI/CD

Microsoft Threat Intelligence описала кампанию, в которой злоумышленник за четыре часа опубликовал 14 пакетов-тайпсквоттеров. Полезная нагрузка запускалась на install и выгребала токены AWS, HashiCorp Vault, npm и GitHub Actions.

DB
DBG · по материалам Microsoft Security Blog
0

28 мая Microsoft Threat Intelligence опубликовала разбор кампании в npm, которая била прицельно по CI/CD. За четырёхчасовое окно один злоумышленник выложил 14 вредоносных пакетов — часть в скоупах, часть без. Имена подобраны под инфраструктурную рутину: opensearch-setup, elastic-opensearch-helper, env-config-manager. В метаданных пакеты указывали на настоящий GitHub-репозиторий OpenSearch, а номера версий были искусственно завышены, чтобы создать иллюзию зрелого проекта с долгой историей релизов.

Запуск шёл через lifecycle-хуки npmpreinstall, install, postinstall. То есть жертве не нужно было ничего импортировать в код: достаточно было один раз выполнить установку. Дальше работал стейджер, и здесь интересная деталь: исследователи выделили два поколения. Первое ходило за второй стадией на внешний C2 по HTTP, помечая свои запросы характерным заголовком X-Supply: 1. Второе поколение отказалось от сетевого шума вовсе — оно использовало легитимный рантайм Bun как загрузчик, а сам ~195-килобайтный скомпилированный бинарник ехал прямо внутри npm-тарболла. Никакого исходящего трафика на этапе доставки, а значит и никаких срабатываний у сетевых детекторов.

Собирал бинарник ровно то, что даёт максимальный рычаг. AWS: метаданные EC2 (IMDS), роли ECS-задач, Secrets Manager — перебором более чем по 16 регионам. HashiCorp Vault: токены. npm: publish-токены, то есть возможность продолжить цепочку и заразить уже ваши пакеты. GitHub Actions: креды воркфлоу. И до кучи — все переменные окружения CI/CD, куда команды по привычке складывают ключи к чему угодно. Это не кража кошельков, это захват конвейера поставки.

Что делать практикующему разработчику. Самая дешёвая и самая эффективная мера — выключить lifecycle-скрипты там, где они вам не нужны: npm config set ignore-scripts true локально и npm ci --ignore-scripts в пайплайне. Да, часть пакетов с нативными биндингами после этого потребует ручного разрешения — заведите короткий allowlist, это меньшая боль, чем ротация всех секретов компании. Дальше по списку: проверьте package-lock.json и логи сборок за конец мая на упомянутые имена пакетов; заблокируйте C2-домен aab.sportsontheweb[.]net на периметре; прогоните CloudTrail на предмет обращений к Secrets Manager из нетипичных регионов — перебор 16 регионов подряд выглядит в логах абсолютно неестественно. И стратегически: если ваши воркфлоу до сих пор ходят в AWS по долгоживущим ключам в secrets, переезжайте на OIDC — короткоживущий токен, украденный на этапе npm install, стоит несравнимо дешевле постоянной пары ключей.

Комментарии