24 июня 2026 года злоумышленник опубликовал вредоносные версии 20 npm-пакетов, входящих в экосистему Leo Platform. Публикация произошла скоординированно в течение менее трёх секунд. Все 20 пакетов содержат идентичный инструментарий для атак на конвейеры CI/CD, который похищает секреты из раннеров GitHub Actions, облачных хранилищ учётных данных, реестров пакетов и менеджеров паролей. Похищенная информация затем отправляется через собственный токен GitHub жертвы. Совокупная еженедельная загрузка этих пакетов составляет приблизительно 13 600 установок.
Описание
Исследователи провели полный анализ пакета leo-logger@1.0.8 и выборочно проверили leo-sdk@6.0.19, чтобы подтвердить масштаб кампании. Атака использует тот же инструментарий и механизм доставки, который ранее был задокументирован в связи с кампанией Miasma. Речь идёт о хуке установки Phantom Gyp через файл binding.gyp, трёхуровневой цепочке обфускации (шифр ROT-N, AES-128-GCM, obfuscator.io) и уклонении от выполнения в среде Bun. Полный технический разбор цепочки атаки был опубликован ранее, поэтому в данном материале основное внимание уделяется специфике кампании против Leo Platform: списку из 20 скомпрометированных пакетов, скоординированной публикации и шагам по устранению угрозы.
Все 20 пакетов были опубликованы в течение трёхсекундного окна в момент времени 2026-06-24T23:04:55Z. Этот факт подтверждает, что атаку выполнила единая автоматизированная операция, нацеленная на учётные записи мейнтейнеров Leo Platform. Полезная нагрузка структурно идентична той, что использовалась в кампании Miasma, опубликованной 3 июня 2026 года. Совпадают синтаксис хука binding.gyp, трёхуровневая цепочка обфускации и URL загрузки Bun версии v1.3.13. По всей видимости, действует тот же злоумышленник, который спустя 21 день после Miasma атаковал новую экосистему.
Список пострадавших пакетов включает leo-logger (версия 1.0.8), leo-sdk (6.0.19), leo-aws (2.0.4), leo-config (1.1.1), leo-streams (2.0.1), serverless-leo (3.0.14), leo-connector-mongo (3.0.8), serverless-convention (2.0.4), rstreams-metrics (2.0.2), leo-connector-elasticsearch (2.0.6), leo-auth (4.0.6), leo-cache (1.0.2), leo-cli (3.0.3), leo-cron (2.0.2), leo-connector-redshift (3.0.6), leo-connector-oracle (2.0.1), rstreams-shard-util (1.0.1), leo-connector-mysql (3.0.3), leo-cdk-lib (0.0.2) и solo-nav (1.0.1). Все они были опубликованы неавторизованным лицом, получившим доступ к учётным данным мейнтейнера.
Техника Phantom Gyp использует shell-расширение <!(node index.js > /dev/null 2>&1 && echo stub.c)> внутри массива sources файла binding.gyp. Это позволяет выполнять произвольные команды во время установки пакета без объявления каких-либо записей в блоке scripts файла package.json. Любой пакет, содержащий файл binding.gyp, но не имеющий C++ исходников и не создающий бинарный файл .node, следует считать подозрительным.
Возможности полезной нагрузки были подробно описаны в анализе Miasma. Вкратце, инструментарий выполняет на каждой установке следующие действия: извлечение памяти процесса Runner.Worker на GitHub Actions через /proc/{pid}/cmdline и /proc/{pid}/mem для восстановления секретов, которые скрыты в логах и недоступны дочерним процессам; перебор облачных учётных данных (AWS IMDS, Secrets Manager, SSM, ECS; GCP metadata service, сервисные ключи; Azure managed identity, Key Vault, federated credentials; HashiCorp Vault, Kubernetes service account token, npm, PyPI, RubyGems, JFrog, GitHub PAT, 1Password); эксфильтрация через GitHub dead-drop: украденные учётные данные шифруются и фиксируются в репозиториях GitHub через GraphQL API с использованием токена самой жертвы, без обращения к внешнему домену; worm-компонент для заражения цепочки поставок: если найден npm-токен, полезная нагрузка публикует вредоносные версии любых пакетов, на которые у жертвы есть права публикации, через механизм bypass_2fa, обходя двухфакторную аутентификацию; модификация файлов GitHub Actions для запроса разрешения id-token: write и добавления шагов с привязанными SHA действий злоумышленника; повышение привилегий: на раннерах GitHub запись строки runner ALL=(ALL) NOPASSWD:ALL для предоставления доступа sudo без пароля.
Предоставленный запуск на платформе StepSecurity демонстрирует, как Harden-Runner обнаруживает аномальную цепочку процессов при установке пакета. Агент безопасности мониторит сетевые события, выполнение процессов, файловый доступ и исходящие соединения на уровне шагов в GitHub Actions. Harden-Runner фиксирует подозрительную активность: node-gyp порождает curl, unzip и bun, а также несанкционированное чтение памяти. После обнаружения запускается режим блокировки, выполнение рабочего процесса прерывается, что предотвращает извлечение секретов.
Для защиты от подобных атак рекомендуется использовать Secure Registry с настроенным периодом "охлаждения" для новых версий пакетов. Новопубликованные пакеты временно блокируются до тех пор, пока не будет подтверждена их безопасность. В случае с кампанией Miasma такой подход гарантировал, что ни один клиент не получил скомпрометированные версии. Дополнительно можно применять проверки на наличие известных вредоносных пакетов и средства поиска по всем запросам на слияние в организации для быстрого определения радиуса поражения.
Операция против Leo Platform является более целенаправленной и скрытной, чем Miasma. Она сфокусирована на одной поддерживаемой экосистеме, а не на массовой рассылке по множеству учётных записей. Время публикации - три секунды - говорит об улучшенных инструментах автоматизации. Отпечатки в виде синтаксиса binding.gyp, URL загрузки Bun и трёхуровневой обфускации однозначно связывают обе кампании с одним и тем же злоумышленником. Разработчикам, использующим пакеты Leo Platform, следует немедленно проверить установленные версии на предмет соответствия указанным SHA1-хешам и заблокировать любые пакеты, опубликованные в указанный временной промежуток.
Индикаторы компрометации
SHA1
- 1a5a1445fcd73133f22a0e7895993ac0a42b56da
- 1dcc0a39e1cd7293a9058cfc41e1afe8b397c943
- 24a0d9e496ec07ca978fab602d5f5e0b39fa03a0
- 47d73156df1c767bb168c4309fd17b92324d587d
- 5e75c14b8acd5752819ab7a10874ddd6389f5238
- 68a1cd589b2ce322f5f03fe7f85dc3f176a759d4
- 809ce3680adfdb8f0746189b68b6b5a6888a960f
- 888094a9b842cfe98e8e24c8f729be1fb6384563
- 92221eb202e9f2ac577e5c33658c8a05c6d67556
- 9be49287057cd6a54ef4a70a8d541a7259efbd2d
- a8cb86b78ca56befe90dc466642cb04b98079909
- be3b1f7f1b50f5d53b164a72fb3a9845f4734325
- be6bb1cf88c46e9e4a6f1a68ed001b77769d58de
- d45ad3cffbcc7c4b354ebe9d71d002fa585379ec
- d7224b6b1f5d2f9403f1cebc8f82518c20b4d0f7
- e973173fb757d2dab9c6424b440dd9f7cbe4f14a
- ed9a17d6567101fa4f9f552a4a52cfcca88fa662
- ef8bf6dd92cbc29ef8d23f3f0fa786ed20a856b1
- effa8576594fdd59907b5c5c07293ce28a9a3393
- f03a3e0dca9ef402352ce61cad59e5d850744960
Package
- leo-logger 1.0.8
- leo-sdk 6.0.19
- leo-aws 2.0.4
- leo-config 1.1.1
- leo-streams 2.0.1
- serverless-leo 3.0.14
- leo-connector-mongo 3.0.8
- serverless-convention 2.0.4
- rstreams-metrics 2.0.2
- leo-connector-elasticsearch 2.0.6
- leo-auth 4.0.6
- leo-cache 1.0.2
- leo-cli 3.0.3
- leo-cron 2.0.2
- leo-connector-redshift 3.0.6
- leo-connector-oracle 2.0.1
- rstreams-shard-util 1.0.1
- leo-connector-mysql 3.0.3
- leo-cdk-lib 0.0.2
- solo-nav 1.0.1