Две независимые команды безопасности — Aikido Security и SafeDep — зафиксировали масштабную кампанию по краже облачных и инфраструктурных учётных данных через экосистему GitHub. По данным Aikido, злоумышленник использовал учётные данные 4837 взломанных аккаунтов, чтобы внедрить вредоносный скрипт в репозитории, доступные этим пользователям для записи. Скрипт, по оценке компании, сработал как минимум в 1806 репозиториях. Отдельный анализ SafeDep выявил 8093 репозитория, получивших вредоносные изменения в период с 12:46 UTC во вторник до 04:36 UTC 12 ноября. Важно, что эта цифра учитывает все обнаруженные репозитории с вредоносными коммитами, а не только те, где скрипт фактически выполнился. При этом проверка охватывала лишь основные ветки публичных проектов, поэтому реальный масштаб инцидента, по признанию аналитиков, может быть больше.

Как начиналась атака: тестовый pull request

Кампания стартовала с разведки: злоумышленник отправлял тестовый запрос на слияние изменений (pull request) с заголовком «docs: dependency audit notes» из ветки wfx-docs, проверяя, может ли скомпрометированный аккаунт действительно изменять содержимое репозитория. Подобные запросы появились в 61 764 проектах, после чего в части из них добавлялся похититель секретов. SafeDep обнаружила 7309 случаев внедрения скрипта в существующие рабочие процессы GitHub Actions и ещё 771 случай, когда вредоносный код распространялся через механизм npm postinstall — автоматическое выполнение кода при установке пакета. В последнем случае скрипт мог запускаться не только в облачной инфраструктуре проекта, но и непосредственно на компьютере разработчика. Обычно после внедрения злоумышленник откатывал изменения через несколько минут, а журналы выполнения удалялись вместе с самими запусками, поэтому отсутствие видимых следов атаки ещё не означает, что данные не были похищены.

Что именно выкачивал скрипт

Вредоносный код собирал практически все доступные ему учётные данные: секреты GitHub Actions, токены GITHUB_TOKEN, временные токены OIDC и Actions Runtime, ключи ИИ-сервисов, а также данные из файлов конфигурации AWS, Azure, Google Cloud, Kubernetes, npm, PyPI и SSH. Дополнительно скрипт копировал содержимое репозитория, последние 100 коммитов и недавние артефакты рабочих процессов. На собственных серверах компаний (self-hosted runners) он мог получать дополнительные облачные учётные данные из метаданных виртуальных машин, сведения о Docker-контейнерах и конфигурации systemd. Похищенная информация отправлялась через HTTP POST на удалённые серверы или в Telegram: при проверке 200 вредоносных коммитов примерно в 20% случаев использовался исключительно Telegram.

Закрепление в облачной инфраструктуре

Особую опасность представляли механизмы закрепления (persistence) в облаке. Получив токены GitHub OIDC, злоумышленник мог обменивать их на сеансы доступа к AWS, Google Cloud и Azure, создавать постоянные ключи AWS и менять политики доверия облачных ролей. В Azure он мог добавлять федеративные учётные данные с префиксом wfx-ci-, позволяющие рабочим процессам авторизоваться без сохранённого пароля. Ключевая проблема в том, что такие механизмы могли продолжать работать даже после отзыва первоначальных токенов и смены ключей, что делает стандартные меры реагирования недостаточными без полного аудита политик доверия.

Связь с атакой GhostAction

Aikido также обнаружила пересечение с атакой GhostAction, проведённой в октябре: аккаунты, пострадавшие тогда, примерно в 1000 раз чаще становились участниками новой кампании. При этом компания пока не связывает обе атаки с одним и тем же злоумышленником, поскольку в них использовались разные инструменты и инфраструктура. Для пострадавших организаций это означает необходимость срочного отзыва всех токенов и ключей, аудита политик доверия облачных ролей, проверки рабочих процессов GitHub Actions и npm-зависимостей, а также мониторинга аномальных авторизаций, в том числе федеративных учётных данных с подозрительными префиксами.