Компрометация цепочки поставок Trivy: как Luntry противостоит Supply Chain атакам
09 ноября 2026
Атаки на цепочку поставок (Supply Chain атаки) остаются одним из самых критичных векторов угроз для российских компаний и глобального ИТ-сообщества. Злоумышленники все чаще атакуют не сами целевые системы, а доверенные инструменты, которые эти системы используют.

Что произошло. 

19 марта 2026 года злоумышленники скомпрометировали сканер уязвимостей Trivy компании Aqua Security, внедрив вредоносное ПО, предназначенное для кражи учетных данных, в официальные версии и GitHub Actions. Хотя компания Aqua сообщает, что с тех пор вредоносные версии были удалены, организациям, использующим Trivy, следует немедленно провести проверку своих систем.


Мы решили разобрать этот кейс через призму возможностей Luntry, чтобы продемонстрировать наши возможности, как ранее мы уже делали это на примере скомпрометированного образа Kong Ingress Controller в статье «Инцидент SolarWinds в контейнерном мире».

Luntry не использует Trivy ни в каком виде — ни напрямую, ни частично, ни в форме форка или модифицированной версии. Это означает, что Luntry не зависит от данного инструмента и не включает его компоненты в свою инфраструктуру. Соответственно, использование Luntry никак не могло поставить клиентов под угрозу, связанную с возможными компрометациями, затрагивающими Trivy.

Хронология инцидента с Trivy

После первичной компрометации Trivy злоумышленники из группы TeamPCP развили атаку, распространив вредоносные компоненты, которые в итоге используются для атак на Kubernetes кластеры. Вредоносное ПО при определённых условиях разворачивается в инфраструктуре и может полностью уничтожать системы — в частности, он проверяет настройки среды и, если обнаруживает иранские системы, запускает разрушительный сценарий с удалением всех данных и перезагрузкой узлов. В остальных случаях вредонос устанавливает бэкдор и закрепляется в кластере, используя механизмы Kubernetes (например, DaemonSet) для распространения, что делает атаку особенно опасной и масштабируемой. 
Конец февраля 2026 года:
злоумышленники воспользовались ошибкой в настройках среды GitHub Actions в репозитории Trivy, получив токен с привилегированным доступом и закрепившись в процессах автоматизации репозитория и выпуска версий.
1 марта 2026 года:
команда Trivy сообщила о произошедшем инциденте и провела ротацию учетных данных. Последующее расследование показало, что ротация была неполной, что позволило злоумышленникам сохранить остаточный доступ с помощью учетных данных, которые по-прежнему оставались действительными.
19 марта 2026 года
(~17:43 UTC):
злоумышленники сделали force-push 76 из 77 тегов версий в репозитории aquasecurity/trivy-action и все 7 тегов в aquasecurity/setup-trivy. Одновременно с этим скомпрометированная учетная запись aqua-bot запустила пайплайн, чтобы опубликовать вредоносный бинарный файл Trivy с версией v0.69.4.
19 марта 2026 г.
(~20:38 UTC):
команда Trivy выявила и локализовала атаку, удалив вредоносные артефакты из каналов распространения.
20 марта 2026 г.:
для специалистов по информационной безопасности были опубликованы безопасные версии, рекомендации для пользователей и индикаторы компрометации.
Более подробно о всей ситуации можно почитать в блоге Aqua Security.
Воспроизведение окружения и анализ полезной нагрузки

Поскольку оригинальные артефакты были удалены, для анализа мы опирались на публичные Threat Intelligence отчеты и хэши IoC (источник: Wiz Blog, VirusTotal).
Photograph: Lee Scott / Unsplash
Скачав бинарный файл, мы воспроизвели оригинальный образ, добавив скомпрометированный Trivy в корень репозитория. Итоговый Dockerfile будет выглядеть так:

FROM alpine:3.23.3
RUN apk --no-cache add ca-certificates git
COPY trivy /usr/local/bin/trivy
COPY contrib/*.tpl contrib/
ENTRYPOINT ["trivy"]
 
В реальной инфраструктуре Trivy часто работает в составе trivy-operator. Для того чтобы trivy-operator использовал вредоносную версию trivy нужно внести пару изменений в ConfigMap, а именно — изменить имя образа и его тэг:
Что делает полезная нагрузка?

Поведение скомпрометированного Trivy на хостах и на сборочных раннерах несколько отличается.

Первоначально скрипт проходится по PID процессов запуска GitHub Actions (Runner.Worker, Runner. Listener, runsvc, run. sh) и читает /proc/{PID}/environ, фильтруя переменные окружения, содержащие в своих именах env или ssh.
 
На Linux-раннерах, размещенных на GitHub, закодированный в Base64 скрипт на Python декодируется и выполняется с помощью sudo. Он находит процесс Runner. Worker, считывает его memory map через /proc/{PID}/maps и извлекает секреты GitHub Actions из /proc/{PID}/mem — в частности, из JSON-структур, соответствующих «name»:{"value":"…","isSecret":true}.
 
На self-hosted раннерах другой закодированный в Base64 скрипт на Python выполняет масштабный сбор учетных данных файловой системы. Он нацелен на следующие области:
 
  • Закрытые ключи и конфигурации SSH
  • Учетные данные облачных сервисов (AWS, Google Cloud, Azure)
  • Конфигурации Kubernetes и Service Account токены
  • Учетные данные реестра Docker
  • Учетные данные баз данных (MySQL, PostgreSQL, MongoDB, Redis)
  • Конфигурации CI/CD (GitLab CI, Travis, Jenkins, Drone)
  • Секреты IaC (состояние/переменные Terraform, Ansible, Helm)
  • Закрытые ключи TLS/SSL
  • .env-файлы и ключи API
  • Ключи криптокошельков (Bitcoin, Ethereum, пары ключей валидатора Solana, Cardano и другие)
  • Системные файлы (/etc/passwd, /etc/shadow, bash history)
 
Собранные данные шифруются с помощью случайно сгенерированного сессионного ключа AES-256-CBC, а сессионный ключ упаковывается в захардкоженный 4096-битный открытый ключ RSA. Зашифрованный пакет (payload.enc + session.key.enc) упакован в tpcp.tar.gz. Это гарантирует, что расшифровать полезную нагрузку сможет только сервер злоумышленников, имеющий доступ к соответствующему закрытому ключу RSA.
 
Основной канал эксфильтрации — HTTPS POST-запрос к scan. aquasecurtiy[.]org — домену имитирующему легитимный aquasecurity.com компании Aqua Security.
 
Если эндпоинт возвращает ответ, отличный от 2XX, и доступен параметр INPUT_GITHUB_PAT, скрипт переключается на эксфильтрацию через сам GitHub. Он создаст общедоступный репозиторий с именем tpcp-docs в учетной записи GitHub жертвы, создаст релиз с меткой времени и загрузит зашифрованный пакет в качестве ресурса релиза.
Заполним необходимые поля и нажмем кнопку «Test», чтобы проверить соединение с Registry. Мы получили сообщение Success, а значит можно добавлять Registry и двигаться дальше.

Далее переходим на вкладку Settings->Scheduler и задаем настройки сканирования по расписанию для конкретного образа в интересующем нас Registry.
Помимо создания SBOM, сканирования на известные уязвимости, мисконфигурации, чувствительную информацию в образах, в Luntry, есть также функциональность для поиска вредоносных файлов и файлов двойного назначения, которая сделана специально с учетом Linux и контейнерной специфики. Это сделано для того, чтобы негативно не влиять на рабочее окружение и пользовательские приложения. Эта возможность базируется на YARA правилах, где можно использовать как наш собственный feed, так и добавлять собственные проверки.

Но мало просто обнаружить вредоносный файл — важно не допустить попадания такого образа в кластер. Для этого в Luntry есть Security Gates, которые настраиваются на этапах CI/CD, Registry и Runtime. Достаточно задать условие вида «в образе обнаружен вредоносный файл с уровнем риска Critical», и тогда сборка образа со скомпрометированным trivy будет остановлена ещё в пайплайне, образ в Registry будет помечен как не прошедший проверку, а при попытке запустить его в кластере сработает Security Gate на этапе Runtime.

Для того чтобы добавить свое YARA правило необходимо перейти на вкладку Settings->Malware и выбрать «Add rule +». Теперь необходимо указать некоторые метаданные, а также MD5 hash для определения вредоносной нагрузки.
После запуска сканирования по расписанию результаты сканирования можно посмотреть на вкладке Images -> Registry Images
Защита в Runtime

Сканирование образов — лишь одна из линий защиты. Сканер может не знать о свежем вредоносе, правило могут добавить с опозданием, а образ — оказаться в кластере в обход проверок. Поэтому важно видеть, что происходит внутри контейнеров во время работы. Посмотрим, как Luntry обнаружил бы и остановил скомпрометированный trivy в Runtime.

Модель поведения. Легитимный trivy в составе trivy-operator ведёт себя предсказуемо: читает слои образов, обновляет базу уязвимостей и обращается к registry. Скомпрометированная версия делает то, чего в модели поведения нет: запускает интерпретатор Python, читает /proc/<PID>/environ и /proc/<PID>/mem других процессов, обращается к SSH-ключам, kubeconfig и токенам Service Account, упаковывает собранное в архив tpcp.tar.gz. Все эти действия будут зафиксированы как аномалии относительно модели поведения, построенной на легитимной версии.

Правила детектирования. Помимо аномалий, гибридный движок Luntry обнаруживает атаки по правилам. Чтение памяти чужих процессов, массовый доступ к файлам с учётными данными и запуск интерпретатора внутри контейнера сканера — типичные признаки кражи секретов, на которые можно опираться как во встроенной библиотеке правил, так и в собственных правилах, например на обращение к домену scan. aquasecurtiy[.]org из опубликованных IoC.

Сетевая безопасность. На сетевой карте Luntry появится новое исходящее соединение trivy-operator к внешнему домену, которого раньше не было. А Network Policy, сгенерированная автоматически и разрешающая trivy-operator только необходимые соединения (registry и источники базы уязвимостей), закрыла бы основной канал эксфильтрации.

Предотвращение в Runtime. На основе модели поведения Luntry генерирует политики предотвращения, которые не позволят процессу выполнить нехарактерные для него действия — например, запустить Python или прочитать память другого процесса.
Выводы:

  1. Безопасность цепочки поставки становится все актуальнее и на нее нужно обращать внимание. Так как даже легитимные компоненты могут нести вредоносную функциональность или содержать НДВ (недекларированные возможности).
  2. Для обеспечения безопасности цепочки поставки нужно использовать комплексный подход контроля на всех жизненных стадиях приложения: от сборки до запуска в runtime.
  3. Решение Luntry предоставляет полный перечень механизмов для контроля безопасности микросервисных приложений с гибкими возможностями настройки под себя: от создания собственных правил детектирования до формирования моделей поведения.
  4. Сканирования образов недостаточно: вредоносный компонент может пройти проверки на этапе сборки и в Registry. Runtime-защита позволяет обнаружить его по аномальному поведению и сетевой активности уже после запуска и остановить атаку, поэтому защищать приложение нужно со всех сторон — от образа до работающего контейнера.
💡 Хотите проверить, насколько защищена ваша контейнерная инфраструктура? Запросите демонстрацию возможностей Luntry или разверните пилотный проект, чтобы увидеть, как наше решение блокирует Supply Chain атаки в реальном времени.

👉 Связаться с экспертами Luntry