Уязвимость в популярной библиотеке LiteLLM: новый эпизод масштабной кампании против цепочек поставок ПО

information security

Компрометация популярной библиотеки LiteLLM для работы с языковыми моделями стала кульминацией пятидневной целенаправленной кампании против инфраструктуры разработки ПО, затронувшей проекты Trivy, Aqua Security, npm, Checkmarx и OpenVSX. Инцидент демонстрирует, как кража учетных данных из одной системы непрерывной интеграции (CI/CD) может привести к каскадному заражению множества проектов и экосистем за считанные дни, превращая единичный взлом в угрозу для всей отрасли.

Описание

24 марта 2026 года в официальном репозитории Python Package Index (PyPI) появились две вредоносные версии библиотеки LiteLLM - 1.82.7 и 1.82.8. Важно подчеркнуть, что это была не поддельная или опечатанная библиотека, а компрометация реального, широко используемого проекта. PyPI позднее изолировал пакет, но к тому моменту уязвимые версии могли быть уже установлены в сотнях тысяч сред разработки и production-систем. LiteLLM представляет собой библиотеку и прокси-слой на Python, унифицирующий работу с API множества провайдеров больших языковых моделей (LLM), что делает её критически важным компонентом для многих AI-приложений.

Расследование специалистов по безопасности компании Datadog, опубликованное в их блоге, показало, что атака на LiteLLM является частью скоординированной кампании, начавшейся 19 марта. В тот день злоумышленники, используя скомпрометированные учётные данные, внедрили вредоносный код в инструмент безопасности Trivy и связанные с ним GitHub Actions репозитория aquasecurity. Вредоносная версия v0.69.4 автоматически распространилась через официальные каналы, включая Docker Hub и GitHub Container Registry (GHCR). Полезная нагрузка была нацелена на хищение секретов из памяти CI-раннеров, их шифрование и эксфильтрацию на поддельный домен, имитирующий ресурс Aqua Security.

Последующие дни показали стремительную эволюцию кампании. Уже 20 марта атакующие начали использовать украденный доступ для распространения саморазмножающегося червя в реестре npm, заразив пакеты под несколькими издательскими областями (scopes). К 22 марта активность переместилась в Kubernetes-кластеры, где скрипты, в зависимости от локализации системы, либо уничтожали файловую систему (на иранских хостах), либо устанавливали постоянный бэкдор. В тот же день была дефейсована внутренняя GitHub-организация Aqua Security. 23 марта под удар попали инструменты компании Checkmarx и расширения для OpenVSX, что продемонстрировало единый почерк атакующего и подготовило почву для финального удара по LiteLLM.

Технический анализ вредоносных версий LiteLLM раскрывает изощрённость атаки. Полезная нагрузка выполняет многоступенчатый сценарий. Сначала она собирает широкий спектр конфиденциальных данных: переменные окружения, SSH-ключи, облачные учётные данные, конфигурации Kubernetes и Docker, историю командной оболочки, секреты CI/CD. Собранная информация шифруется гибридной схемой с использованием AES-256 и RSA-4096. Затем зашифрованный архив отправляется на контролируемый злоумышленниками домен models.litellm[.]cloud. Для обеспечения устойчивого присутствия в системе создаётся служба systemd, после чего вредоносная программа начинает опрашивать командный сервер для получения и выполнения дополнительных инструкций. Наиболее опасной возможностью является эскалация привилегий в кластерах Kubernetes: при обнаружении токена сервисного аккаунта payload создаёт привилегированные поды, превращая компрометацию одного пакета в угрозу для всего кластера.

Ключевое различие между версиями 1.82.7 и 1.82.8 заключается в механизме активации. В версии 1.82.7 вредоносный код был внедрён непосредственно в файл "proxy_server.py" и выполнялся при импорте этого модуля в приложении. Версия 1.82.8 представляет большую опасность, так как содержит файл "litellm_init.pth". Согласно документации Python, исполняемые строки в ".pth"-файлах запускаются автоматически при старте интерпретатора. Это означает, что само событие установки пакета через "pip install" может привести к немедленному выполнению вредоносного кода, даже если библиотека никогда явно не импортируется в коде приложения.

Для специалистов по информационной безопасности инцидент означает необходимость пересмотра подхода к реагированию. Установка версий 1.82.7 или 1.82.8 должна рассматриваться не просто как наличие уязвимой зависимости, а как полноценное событие компрометации с потенциальной утечкой всех доступных на хосте учётных данных. Первоочередные действия должны включать идентификацию всех затронутых систем - рабочих станций разработчиков, контейнеров и CI-заданий. Далее необходимо определить круг секретов, к которым мог получить доступ вредоносный код, и выполнить их полную ротацию. Особое внимание следует уделить токенам, имеющим права на публикацию кода, так как именно они стали катализатором распространения этой кампании. Очистка среды не должна ограничиваться удалением пакета LiteLLM; требуется охота за артефактами устойчивости, анализ исходящего сетевого трафика и аудит логов Kubernetes на предмет подозрительной активности.

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

Индикаторы компрометации

Domains

  • aquasecurtiy.org
  • championships-peoples-point-cassette.trycloudflare.com
  • investigation-launches-hearings-copying.trycloudflare.com
  • models.litellm.cloud
  • souls-entire-defined-routes.trycloudflare.com
  • tdtqy-oyaaa-aaaae-af2dq-cai.raw.icp0.io

URLs

  • checkmarx.zone/raw

OpenVSX extension

  • ast-results 2.53.0
  • cx-dev-assist 01.07.2000

GitHub action

  • aquasecurity/setup-trivy 0.2.0 to 0.2.6
  • aquasecurity/trivy-action All tags not starting with v, except 0.35.0
  • Checkmarx/kics-github-action v1.1
  • Checkmarx/ast-github-action v2.3.28

Python package

  • litellm 1.82.7, 1.82.8

Docker image

  • aquasec/trivy 0.69.4, 0.69.5, 0.69.6
  • ghcr.io/aquasecurity/trivy 0.69.4, 0.69.5, 0.69.6
  • docker.io/aquasec/trivy:0.69.4 0.69.4, 0.69.5, 0.69.6
  • public.ecr.aws/aquasecurity/trivy 0.69.4, 0.69.5, 0.69.6

npm package

  • @airtm/uuid-base32 1.0.2
  • @emilgroup/accounting-sdk 1.27.3,1.27.2,1.27.1
  • @emilgroup/accounting-sdk-node 1.26.2,1.26.1
  • @emilgroup/account-sdk 1.41.2,1.41.1
  • @emilgroup/account-sdk-node 1.40.2,1.40.1
  • @emilgroup/api-documentation 1.19.2,1.19.1
  • @emilgroup/auth-sdk 1.25.2,1.25.1
  • @emilgroup/auth-sdk-node 1.21.2,1.21.1
  • @emilgroup/billing-sdk 1.56.2,1.56.1
  • @emilgroup/billing-sdk-node 1.57.2,1.57.1
  • @emilgroup/changelog-sdk-node 1.0.3,1.0.2
  • @emilgroup/claim-sdk 1.41.2,1.41.1
  • @emilgroup/claim-sdk-node 1.39.2,1.39.1
  • @emilgroup/commission-sdk 1.0.3,1.0.2,1.0.1
  • @emilgroup/commission-sdk-node 1.0.3,1.0.2,1.0.1
  • @emilgroup/customer-sdk 1.54.5,1.54.4,1.54.3,1.54.2,1.54.1
  • @emilgroup/customer-sdk-node 1.55.2,1.55.1
  • @emilgroup/discount-sdk 1.5.3,1.5.2,1.5.1
  • @emilgroup/discount-sdk-node 1.5.2,1.5.1
  • @emilgroup/document-sdk 1.45.2,1.45.1
  • @emilgroup/document-sdk-node 1.43.6,1.43.5,1.43.4,1.43.3,1.43.2,1.43.1
  • @emilgroup/document-uploader 0.0.12,0.0.11,0.0.10
  • @emilgroup/docxtemplater-util 1.1.4,1.1.3,1.1.2
  • @emilgroup/gdv-sdk 2.6.2,2.6.1
  • @emilgroup/gdv-sdk-node 2.6.3,2.6.2,2.6.1
  • @emilgroup/insurance-sdk 1.97.6,1.97.5,1.97.4,1.97.3,1.97.2,1.97.1
  • @emilgroup/insurance-sdk-node 1.95.2,1.95.1
  • @emilgroup/notification-sdk-node 1.4.2,1.4.1
  • @emilgroup/numbergenerator-sdk-node 1.3.3,1.3.2,1.3.1
  • @emilgroup/partner-portal-sdk 1.1.3,1.1.2,1.1.1
  • @emilgroup/partner-portal-sdk-node 1.1.2,1.1.1
  • @emilgroup/partner-sdk 1.19.3,1.19.2,1.19.1
  • @emilgroup/partner-sdk-node 1.19.2,1.19.1
  • @emilgroup/payment-sdk 1.15.2,1.15.1
  • @emilgroup/payment-sdk-node 1.23.2,1.23.1
  • @emilgroup/process-manager-sdk 1.4.2,1.4.1
  • @emilgroup/process-manager-sdk-node 1.13.2,1.13.1
  • @emilgroup/public-api-sdk 1.33.2,1.33.1
  • @emilgroup/public-api-sdk-node 1.35.2,1.35.1
  • @emilgroup/setting-sdk 0.2.3,0.2.2,0.2.1
  • @emilgroup/setting-sdk-node 0.2.3,0.2.2,0.2.1
  • @emilgroup/task-sdk 1.0.4,1.0.3,1.0.2
  • @emilgroup/task-sdk-node 1.0.4,1.0.3,1.0.2
  • @emilgroup/tenant-sdk 1.34.2,1.34.1
  • @emilgroup/tenant-sdk-node 1.33.2,1.33.1
  • @emilgroup/translation-sdk-node 1.1.2,1.1.1
  • @leafnoise/mirage 2.0.3
  • @opengov/form-builder 0.12.3
  • @opengov/form-renderer 0.2.20
  • @opengov/form-utils 0.7.2
  • @opengov/ppf-backend-types 1.141.2
  • @opengov/ppf-eslint-config 0.1.11
  • @opengov/qa-record-types-api 1.0.3
  • @pypestream/floating-ui-dom 2.15.1
  • @teale.io/eslint-config 1.8.16,1.8.15,1.8.14,1.8.13,1.8.12,1.8.11,1.8.10,1.8.9
  • @virtahealth/substrate-root 1.0.1
  • babel-plugin-react-pure-component 0.1.6
  • cit-playwright-tests 1.0.1
  • eslint-config-ppf 0.128.2
  • eslint-config-service-users 0.0.3
  • jest-preset-ppf 0.0.2
  • opengov-k6-core 1.0.2
  • react-autolink-text 2.0.1
  • react-leaflet-cluster-layer 0.0.4
  • react-leaflet-heatmap-layer 2.0.1
  • react-leaflet-marker-layer 0.1.5
Комментарии: 0