Скрытый захват инфраструктуры: Атака на CI/CD пайплайны через компрометацию зависимостей и poisoned runners

TechVandal

Null
Пользователь
Регистрация
3 Апр 2025
Сообщения
4
Реакции
0

Скрытый захват инфраструктуры: Атака на CI/CD пайплайны через компрометацию зависимостей и poisoned runners

Автор: TechVandal



Всем привет. Сегодняшние паблик-топики в основном вертятся вокруг RCE в WordPress и Next.js. Это все конечно рабочие вещи, но они оставляют нас в рамках одной машины. А что, если цель — не просто шелл на веб-сервере, а полный и тихий захват всей разработки компании с возможностью вливать бэкдоры в релизы, которые будут пользоваться тысячи людей? Именно об этом мы и поговорим. Мы будем атаковать не конечный продукт, а процесс его создания — CI/CD пайплайн.

Почему CI/CD — это золотая жила?

Представьте: CI/CD система (GitLab, GitHub Actions, Jenkins, etc.) — это конвейер, который автоматически берет код из репозитория, собирает его, тестирует и выкладывает на прод. Если мы можем незаметно вмешаться в этот процесс на одном из этапов, мы получаем:

  • Автоматическое распространение нашего вредоносного кода: Мы не взламываем прод-сервер, мы заставляем команду разработчиков саму выложить наш бэкдор.
  • Долгосрочное присутствие: Наш код будет попадать в каждую новую версию продукта. Нас можно найти, только если вручную ревьювить каждый коммит или собранный артефакт.
  • Доступ к ключам и секретам: В пайплайнах часто лежат API-токены, ключи от облачных инфраструктур (AWS, GCP, Azure), доступы к Docker registry и прочие вкусняшки.

Вектор атаки: Не просто package.json, а poisoned runner

Большинство статей на эту тему сводятся к "зайди в npm и залей вредоносный пакет с постинсталл-скриптом". Это работает, но это шумно и легко детектится антивирусами на раннерах (runner'ах) — виртуальных машинах, где выполняются задачи. Мы пойдем глубже.

Наша цель — не просто выполнить код, а скомпрометировать сам раннер или окружение так, чтобы все последующие сборки на этом раннере уже были отравлены.

Этап 1: Реконнейсанс и выбор цели

  1. Ищем публичные репозитории компании. Нас интересуют .gitlab-ci.yml, .github/workflows, Jenkinsfile. В них мы видим, какие образы Docker используются для сборки. Например, image: node:18-alpine или image: maven:3.8-openjdk-11.
  2. Анализируем Dockerfile'ы и скрипты. Ищем кастомные шаги. Может, они ставят какую-то специфическую утилиту с непроверенного сервера? Может, они делают curl | bash? Это наша точка входа.
  3. Ищем само-хостed раннеры. Если компания использует свои серверы/ВМ для раннеров (особенно в GitLab или Jenkins), это джекпот. У них может быть старое ядро, открытые порты, слабые учетки.
Этап 2: Компрометация зависимости (тихий вариант)

Предположим, мы нашли, что проект использует малоизвестную библиотеку super-logger версии 1.2.3. Мы не будем публиковать вредоносную версию 1.2.4. Мы создадим форк оригинального репозитория, внесем в него свои изменения (например, добавим в index.js код, который при сборке отправляет переменные окружения process.env на наш C2) и опубликуем его под другим именем, например, super-logger-fixed.

Теперь самое интересное. Мы не просто делаем пулл-реквест в репозиторий цели. Мы создаем issue или даже фейковый аккаунт "сотрудника" и пишем в issue: "Библиотека super-logger устарела и имеет уязвимость X, автор ее больше не поддерживает. Я сделал фиксированный форк super-logger-fixed, всем советую перейти". Разработчики, особенно в больших командах, могут не проверяя скопировать npm install super-logger-fixed в свой package.json. Это социальная инженерия, но на техническом уровне.

Этап 3: Отравление раннера (продвинутый вариант)

Это самый интересный этап. Допустим, мы нашли, что для сборки используется Docker-образ internal-company-builder:latest, который собирается из Dockerfile, лежащего в отдельном репозитории company/build-tools.

В Dockerfile мы видим что-то вроде:

Dockerfile:
FROM ubuntu:22.04
# ... установка базовых пакетов ...
COPY entrypoint.sh /usr/local/bin/
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]

Скрипт entrypoint.sh выполняет первоначальную настройку окружения перед запуском основной задачи. Наша цель — внести в этот скрипт свои изменения. Как?

  1. Компрометация аккаунта с правами на пуш в company/build-tools. Это может быть результатом фишинга, кражи кредов с ноутбука разработчика или эксплуатации уязвимости в каком-то внутреннем сервисе, к которому у него есть доступ.
  2. Внесение вредоносных изменений в entrypoint.sh.Что мы можем добавить?
    • Backdoor в SSHd: Если раннер поднимает SSH для дебага (плохая практика, но встречается), мы можем добавить своего публичного ключа в authorized_keys.
    • Модификация критичных утилит: Мы можем заменить бинарник git или npm на свой обертку, который будет копить логи, пароли и токены в скрытой директории, а потом периодически отправлять их нам.
    • Скрытый майнер: Вставить в entrypoint.sh запуск XMRig в фоне, замаскированный под системный процесс (/sbin/kworker).
    • Перехват артефактов: Добавить в конец скрипта команду, которая копирует собранный артефакт (.jar, .exe, .deb) в нашу облачную хранилку перед тем, как он будет залит на релизный сервер.
После того как изменения в build-tools запушены, все новые сборочные раннеры, которые будут подниматься, уже будут отравлены. Старые раннеры со временем перезагрузятся/обновятся, и мы получим контроль над всей инфраструктурой сборки.

Постэксплуатация и удержание

Теперь, когда у нас есть контроль, что делать?

  • Тихий сбор данных: Собираем все креды, которые пролетают через переменные окружения. Это ключи от AWS, токены от Docker Hub, пароли от баз данных.
  • Вливание кода в релизы: Вносим изменения в исходный код основной ветки репозитория цели. Наш бэкдор будет выглядеть как обычная фича или багфикс. Он пройдет код-ревью, будет собран отравленным раннером и выложен на прод. Никаких "взломов сервера", только чистый, легитимный релиз.
  • Удержание: Наша точка опоры — это скомпрометированный build-tools репозиторий. Даже если нас найдут в основном продукте и откатят релиз, мы можем сделать это снова. Чтобы нас не вычислили, нужно тщательно работать с git log, например, используя git rebase -i для "сплющивания" коммитов и изменения авторов.

Заключение​

Компрометация CI/CD — это не экзотика и не придуманная угроза, а один из самых недооценённых и разрушительных векторов атаки. Инфраструктура сборки — это сердце разработки: она видит исходники раньше всех, хранит секреты, создает артефакты, определяет, чему доверяют тысячи пользователей. Именно поэтому любой сбой в цепочке поставки превращается не просто в «один взломанный сервер», а в потенциальную массовую и долгоживущую компрометацию всего продукта.
 
Сверху