Атака на CI/CD: как пакеты-«спящие агенты» крадут ключи и захватывают серверы

Исследователь по безопасности Кирилл Бойченко из компании Socket обнаружил активную атаку на цепочку поставок программного обеспечения, затрагивающую сразу две экосистемы — Ruby и Go. За атакой стоит GitHub-аккаунт под названием BufferZoneCorp. Злоумышленники распространяли вредоносные пакеты, замаскированные под популярные библиотеки: activesupport-logger, devise-jwt, go-retryablehttp, grpc-client и config-loader. На момент публикации Ruby-пакеты уже удалены с RubyGems, Go-модули заблокированы.
Атака на CI/CD: как пакеты-«спящие агенты» крадут ключи и захватывают серверы
Изображение носит иллюстративный характер

Всего выявлено 16 вредоносных пакетов: 7 Ruby gems и 9 Go-модулей. Среди Ruby-пакетов числятся knot-activesupport-logger, knot-devise-jwt-helper, knot-rack-session-store, knot-rails-assets-pipeline, knot-rspec-formatter-json, а также два так называемых «спящих» пакета — knot-date-utils-rb и knot-simple-formatter. В Go-экосистеме атакующие разместили , go-weather-sdk, go-retryablehttp, go-stdlib-ext, grpc-client, net-helper, config-loader, и два «спящих» модуля — log-core и go-envconfig.
Термин «спящий пакет» здесь не метафора. Такие пакеты не содержат немедленно активного вредоносного кода при первом анализе — они выглядят безобидно, но закладываются в инфраструктуру заранее, ожидая обновления или иного триггера для активации. Это существенно затрудняет обнаружение через стандартные статические проверки.
Ruby-часть атаки нацелена на максимально быстрое хищение данных прямо в момент установки пакета. Как только разработчик или CI-runner выполняет установку, вредоносный код без каких-либо дополнительных действий собирает переменные окружения, SSH-ключи, секреты AWS, файлы.npmrc и.netrc, конфигурацию GitHub CLI и учётные данные RubyGems. Всё это немедленно уходит на подконтрольный атакующим эндпоинт — простой и трудно блокируемый способ эксфильтрации данных.
Go-модули работают иначе и преследуют более долгосрочные цели. Вредоносная логика распределена по нескольким пакетам кластера, а не сконцентрирована в одном месте. Запуск происходит через функцию init(), которая в Go выполняется автоматически при импорте пакета. Первым делом код проверяет наличие переменных GITHUB_ENV и GITHUB_PATH, характерных для среды GitHub Actions.
Если переменные найдены, пакет выставляет HTTP_PROXY и HTTPS_PROXY, после чего записывает в кэш-директорию поддельный исполняемый файл Go и добавляет эту директорию в PATH рабочего процесса так, чтобы фейковая обёртка вызывалась раньше настоящего бинарника. Хитрость в том, что обёртка не ломает сборку — она перехватывает управление, делает своё дело и передаёт выполнение легитимному Go-инструменту. CI-задача завершается успешно, никаких ошибок нет, а атака остаётся незамеченной.
Помимо манипуляций с GitHub Actions, Go-пакеты реализуют механизм персистентности: в файл ~/.ssh/authorized_keys записывается жёстко прошитый SSH-публичный ключ атакующего. После этого злоумышленник получает постоянный удалённый доступ к скомпрометированному хосту — независимо от того, будет ли пакет впоследствии удалён.
Основные цели атаки — разработчики, CI-раннеры и любые build-окружения, где эти пакеты могли быть установлены. Особую опасность это несёт для командных и корпоративных сред, где компрометация одного CI-раннера открывает доступ к секретам всей организации.
Тем, кто устанавливал перечисленные пакеты, необходимо действовать незамедлительно. Первый шаг — полное удаление пакетов со всех систем. Затем нужно проверить файл ~/.ssh/authorized_keys на предмет посторонних ключей и убрать всё, что туда не добавлялось вручную. Все потенциально скомпрометированные учётные данные — AWS, SSH, GitHub, RubyGems — подлежат немедленной ротации. Сетевые логи стоит просмотреть на предмет исходящих HTTPS-соединений с . Наконец, нужно проверить системные файлы на признаки несанкционированного доступа к чувствительным данным.
Эта атака наглядно показывает, насколько уязвимыми оказываются современные сборочные конвейеры к пакетам с говорящими именами из знакомых неймспейсов. Префикс knot- или принадлежность к аккаунту BufferZoneCorp — детали, которые легко пропустить при беглом взгляде на зависимости. Механизм с подменой Go-бинарника через PATH — отдельно изящный технический приём, поскольку он не требует привилегий и не вызывает ошибок в логах сборки.


Новое на сайте

20086Мне не передали текст статьи для анализа — в структуре, которую ты предоставил,... 20085Живая квантовая сеть в Нью-Йорке: как Qunnect пытается построить интернет, который нельзя... 20084Живые обои: дрожжи, алгинат и 3D-принтер вместо поклейки 20082CVE-2026-5027: почему уязвимость в Langflow уже активно эксплуатируется хакерами? 20081GreatXML: новый обход BitLocker через Recovery Partition 20080Июньский Patch Tuesday 2026: 206 уязвимостей, три zero-day и неуправляемый ИИ в поиске дыр 20079Почему CISOs массово переводят бюджеты на BAS после того, как ИИ уничтожил привычное... 20078Почему npm 12 запрещает запускать скрипты без вашего разрешения? 20077Ivanti, Fortinet и SAP выпустили критические патчи: что стоит за каждой уязвимостью? 20076Кто стоит за защитой, которую никто не замечает: итоги Cybersecurity Stars Awards 2026 20075Чистый отчёт по пентесту — это хорошо или плохо? 20072Эффект красоты решает исход собеседования до первых слов 20069Как черта характера крадёт деньги на переговорах 20068Карточная игра против главной дисфункции команды
Ссылка