Как пакет для работы с нейросетями стал стилером: полный разбор атаки на LiteLLM

Обложка: Как пакет для работы с нейросетями стал стилером: полный разбор атаки на LiteLLM

Если между 24 и 25 марта 2026 года вы обновляли LiteLLM — проверьте версию прямо сейчас. Ваши API-ключи от OpenAI, Anthropic и облачных провайдеров могли утечь.

LiteLLM — это open-source прокси для работы с API различных LLM-провайдеров: OpenAI, Anthropic, Azure, Bedrock и ещё сотней других. Библиотека позволяет переключаться между моделями через единый интерфейс с автоматическими фоллбэками, ретраями и трекингом расходов. При 97 миллионах загрузок в месяц (около 3,4 млн в день) это один из самых популярных инструментов в AI-инфраструктуре.

В скомпрометированных версиях 1.82.7 и 1.82.8, опубликованных на PyPI, обнаружили встроенный стилер учётных данных. Он крал SSH-ключи, токены облачных сервисов, API-ключи и пароли, а затем расползался по Kubernetes-кластерам.

Ключевое: Версии LiteLLM 1.82.7 и 1.82.8 на PyPI содержали стилер, крадущий SSH-ключи, облачные токены и API-ключи. Версия 1.82.8 запускала вредоносный код при каждом старте Python — даже без импорта библиотеки. Если вы устанавливали LiteLLM 24 марта 2026 года — проверьте свои системы. Последняя чистая версия — 1.82.6.

Но эта атака — не изолированный инцидент. Это финал пятидневной supply chain атаки (атаки через цепочку поставок — внедрение вредоносного кода в легитимный пакет через компрометацию его инфраструктуры). За ней стоит группировка TeamPCP — ранее неизвестная группа, которая за последнюю неделю марта целенаправленно атаковала инструменты безопасности и разработки. Кампания началась с компрометации сканера уязвимостей Trivy и через цепочку украденных CI/CD-креденшалов дотянулась до LiteLLM.

Разбираем всю цепочку атаки от начала до конца — подробнее, чем где-либо ещё.

Хронология: пять дней, три вендора, пять экосистем

Чтобы понять, как LiteLLM оказался скомпрометирован, нужно отмотать на пять дней назад. Атакующие не ломали LiteLLM напрямую — они добрались до него через цепочку компрометаций, каждая из которых давала доступ к следующей цели.

19 марта: Trivy — точка входа

Всё началось с Trivy — open-source сканера уязвимостей от Aqua Security, которым пользуются тысячи компаний для проверки контейнеров и кода.

Атакующие использовали скомпрометированные учётные данные мейнтейнера, чтобы:

  • Опубликовать вредоносный релиз Trivy v0.69.4, который прошёл через стандартную release-машинерию и попал в GHCR, ECR Public, Docker Hub, deb/rpm-пакеты
  • Подменить 76 из 77 тегов aquasecurity/trivy-action на вредоносные коммиты
  • Заменить все 7 тегов aquasecurity/setup-trivy

Вредоносный код в GitHub Actions сканировал память процесса Runner.Worker, собирал креденшалы, шифровал данные AES+RSA и отправлял на подставной домен scan.aquasecurtiy[.]org — обратите внимание на опечатку в слове «security». Если прямая эксфильтрация не удавалась, малварь создавала публичный репозиторий tpcp-docs через GitHub-токен жертвы и сливала данные туда.

20–22 марта: npm-червь и дефейс

Уже на следующий день украденные токены пошли в дело. Атакующие запустили самораспространяющегося npm-червя: 28 пакетов в @EmilGroup, 16 в @opengov, плюс отдельные пакеты в других скоупах. Червь крал npm-токены из скомпрометированных окружений, проверял, к каким пакетам они дают доступ, поднимал patch-версию, подставлял оригинальный README для маскировки и переиздавал пакет с вредоносной начинкой.

К 22 марта та же инфраструктура начала обслуживать Kubernetes-скрипт с разделением жертв по геолокации. На иранских системах деплоился DaemonSet с контейнером kamikaze, который удалял файловую систему хоста и перезагружал ноду. На остальных — устанавливал персистентный бэкдор.

В тот же день атакующие дефейснули 44 репозитория внутренней GitHub-организации Aqua Security (aquasec-com), переименовав их с префиксом tpcp-docs- и описанием «TeamPCP Owns Aqua Security».

23 марта: Checkmarx

Кампания добралась до Checkmarx — ещё одного крупного вендора в сфере безопасности приложений. Были скомпрометированы:

  • Checkmarx/kics-github-action — сканер инфраструктурного кода
  • Checkmarx/ast-github-action — GitHub Action для платформы Checkmarx
  • Расширения VS Code в реестре Open VSX: ast-results v2.53.0 (около 36 000 загрузок) и cx-dev-assist v1.7.0 (около 500 загрузок)

Паттерн тот же: стилер креденшалов, привязанный к домену checkmarx[.]zone, с фоллбэком на публичный репозиторий docs-tpcp для эксфильтрации.

24 марта: LiteLLM

В 10:52 UTC на PyPI появилась версия LiteLLM 1.82.8. Соответствующий тег или релиз на GitHub отсутствовал — пакет был загружен напрямую, в обход стандартного процесса. По данным ReversingLabs, был скомпрометирован GitHub-аккаунт сооснователя и CEO LiteLLM Криша Дхолакии — предположительно, через CI/CD-пайплайн, где Trivy использовался без пиннинга версии.

Через три часа команда безопасности PyPI поставила проект на карантин. Скомпрометированные версии были удалены. Последняя чистая версия — 1.82.6. Но при 3,4 миллионах загрузок в день даже три часа — это огромное окно.

Мейнтейнеры LiteLLM опубликовали security-апдейт, подтвердив компрометацию и рекомендовав всем пользователям обновиться до версии 1.82.6 или выше (после снятия карантина). Issue #24512 на GitHub, описывающий уязвимость, был закрыт — предположительно, самим атакующим через скомпрометированный аккаунт.

Как работает вредоносный код

Теперь разберём, что именно попадало на машины жертв. LiteLLM оказался скомпрометирован в двух версиях, и они существенно различаются по механизму запуска.

Версия 1.82.7: инъекция в proxy_server.py

В версии 1.82.7 вредоносный код был внедрён в файл litellm/proxy/proxy_server.py. Малварь запускалась только при реальном использовании LiteLLM Proxy в приложении. Если пакет был установлен, но прокси-сервер не запускался, код мог не сработать.

Версия 1.82.8: .pth-файл — запуск без импорта

Версия 1.82.8 принципиально опаснее. В wheel-пакет был добавлен файл litellm_init.pth размером 34 628 байт, содержащий дважды закодированный в base64 вредоносный код.

.pth-файлы — малоизвестная особенность Python. Согласно документации модуля site, исполняемые строки в .pth-файлах выполняются автоматически при каждом запуске интерпретатора. Не при импорте библиотеки, а при запуске любого Python-процесса в окружении, где установлен пакет.

Это означает: достаточно было выполнить pip install litellm==1.82.8, и каждый последующий запуск Python на этой машине активировал стилер. Не нужно писать import litellm — даже python -c "print('hello')" запускал вредоносный код.

Три стадии: сбор, шифрование, эксфильтрация

Стадия 1 — сбор. Скрипт прочёсывает машину и собирает:

  • SSH-ключи и конфигурации (~/.ssh/)
  • .env-файлы с секретами
  • Креденшалы AWS (Access Key, Secret Key), GCP (ADC), Azure
  • Конфигурации Kubernetes (~/.kube/config)
  • Docker-конфиги (~/.docker/config.json)
  • Пароли баз данных
  • Историю шелла (bash_history, zsh_history)
  • Файлы криптокошельков
  • Все переменные окружения
  • Данные с облачных metadata-эндпоинтов (IMDS)

Стадия 2 — шифрование. Собранные данные упаковываются в tar-архив и шифруются гибридной схемой: случайный сессионный ключ AES-256-CBC для данных, зашифрованный захардкоженным 4096-битным RSA-публичным ключом.

Стадия 3 — эксфильтрация. Зашифрованный архив отправляется POST-запросом на models.litellm[.]cloud (домен не имеет отношения к настоящему litellm.ai) с заголовком X-Filename: tpcp.tar.gz.

Горизонтальное распространение в Kubernetes

Если на машине обнаружен токен сервисного аккаунта Kubernetes, малварь переходит в режим горизонтального распространения (lateral movement):

  1. Читает все секреты кластера во всех неймспейсах
  2. Создаёт привилегированный pod на каждой ноде в kube-system на основе образа alpine:latest
  3. Каждый pod монтирует корневую файловую систему хоста
  4. Устанавливает персистентный бэкдор в /root/.config/sysmon/sysmon.py
  5. Регистрирует systemd user service для автозапуска

Таким образом, компрометация одного pip-пакета превращается в полную компрометацию всего Kubernetes-кластера.

Персистентность и бэкдор

На локальной машине малварь создаёт:

  • ~/.config/sysmon/sysmon.py — скрипт-бэкдор
  • ~/.config/systemd/user/sysmon.service — systemd unit для автозапуска

После установки бэкдор периодически обращается к https://checkmarx[.]zone/raw, скачивает файл в /tmp/pglog и выполняет его содержимое. Это даёт атакующим возможность удалённо выполнять произвольный код на скомпрометированных машинах в любой момент.

Как обнаружили: баг в малвари устроил fork-бомбу

Ирония истории в том, что атаку обнаружили благодаря ошибке самих хакеров.

Команда FutureSearch столкнулась с проблемой случайно: MCP-плагин в IDE Cursor подтянул LiteLLM как транзитивную зависимость. Вредоносный .pth-файл запускал дочерний Python-процесс через subprocess.Popen. Но поскольку .pth-файлы срабатывают при каждом запуске интерпретатора, дочерний процесс тоже запускал малварь, та порождала ещё один процесс — и так далее.

Результат — экспоненциальная fork-бомба, которая мгновенно съедала всю оперативную память и вешала систему. Без этого бага стилер мог бы работать незамеченным значительно дольше.

Мы были взломаны… тысячи людей, вероятно, прямо сейчас под атакой

Что делать, если вы затронуты

Если в ваших проектах, CI/CD-пайплайнах или на рабочих машинах устанавливался LiteLLM 24 марта или позже — проверьте версию:

			pip show litellm
find ~/.cache/uv -name "litellm_init.pth"
		

Если обнаружена версия 1.82.7 или 1.82.8:

  1. Удалите пакет и очистите кэши: pip cache purge, rm -rf ~/.cache/uv
  2. Проверьте наличие бэкдора: файлы ~/.config/sysmon/sysmon.py и ~/.config/systemd/user/sysmon.service
  3. В Kubernetes: аудит kube-system на наличие подов node-setup-*, проверка секретов на несанкционированный доступ
  4. Ротация всех креденшалов: SSH-ключи, облачные токены (AWS, GCP, Azure), API-ключи, пароли БД, .env-файлы
  5. Сетевые логи: проверьте обращения к models.litellm[.]cloud, checkmarx[.]zone, scan.aquasecurtiy[.]org
  6. Восстановление: не ограничивайтесь удалением пакета — пересобирайте системы из известных чистых образов с закреплёнными (pinned) зависимостями

На момент публикации публичных подтверждений массовой эксплуатации украденных ключей не зафиксировано, однако учитывая трёхчасовое окно и объём загрузок, число затронутых окружений может исчисляться тысячами.

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

Вредоносные домены:

  • models.litellm[.]cloud — C2 для LiteLLM
  • checkmarx[.]zone — C2, используемый для персистентности и Checkmarx-атаки
  • scan.aquasecurtiy[.]org — C2 для Trivy-атаки

Файлы на диске:

  • litellm_init.pth в site-packages/
  • ~/.config/sysmon/sysmon.py
  • ~/.config/systemd/user/sysmon.service
  • /tmp/pglog
  • /tmp/.pg_state

Kubernetes-артефакты:

  • Поды с именами node-setup-* в kube-system
  • Контейнеры с именами kamikaze или provisioner

Инциденту присвоен идентификатор CVE-2026-33634. Полный список IoC в формате CSV доступен в репозитории Datadog Security Labs.

Частые вопросы

Что такое LiteLLM и зачем его используют?

LiteLLM — это open-source Python-библиотека и прокси-сервер, который предоставляет единый интерфейс для работы с более чем 100 LLM-провайдерами (OpenAI, Anthropic, Azure, AWS Bedrock и другие). Библиотека позволяет переключаться между моделями без изменения кода, автоматически обрабатывает фоллбэки и ретраи, отслеживает расходы. По данным PyPI, пакет загружается около 3,4 миллионов раз в день.

Какие версии LiteLLM скомпрометированы?

Скомпрометированы версии 1.82.7 и 1.82.8, опубликованные на PyPI 24 марта 2026 года. Обе версии удалены. Последняя безопасная версия — 1.82.6. Версия 1.82.8 опаснее: она запускает вредоносный код при каждом старте Python через механизм .pth-файлов, тогда как 1.82.7 активируется только при использовании прокси-сервера.

Как проверить, затронут ли я?

Выполните pip show litellm для проверки версии и find ~/.cache/uv -name "litellm_init.pth" для поиска вредоносного файла в кэше. Также проверьте наличие бэкдора: файлы ~/.config/sysmon/sysmon.py и ~/.config/systemd/user/sysmon.service. В Kubernetes ищите поды node-setup-* в namespace kube-system.

Кто стоит за атакой?

Атака приписывается группировке TeamPCP, которая за последнюю неделю марта 2026 года провела серию supply chain атак на инструменты разработки и безопасности: сканер уязвимостей Trivy (Aqua Security), GitHub Actions и расширения VS Code от Checkmarx, npm-пакеты, и в финале — LiteLLM. Инциденту присвоен идентификатор CVE-2026-33634.

Что такое .pth-файл и почему он опасен?

Файлы с расширением .pth, размещённые в директории site-packages, автоматически обрабатываются модулем site Python при каждом запуске интерпретатора. Исполняемые строки в таких файлах выполняются без явного импорта библиотеки. В случае LiteLLM 1.82.8 файл litellm_init.pth содержал дважды закодированный в base64 вредоносный скрипт, который запускался при каждом вызове python в скомпрометированном окружении.

Выводы

Ирония инцидента — в том, что LiteLLM по определению хранит API-ключи ко всем LLM-провайдерам организации. Атакующие выбрали пакет, который гарантированно имеет доступ к самым ценным секретам.

Одна зависимость. Одна цепная реакция. Пять экосистем supply chain скомпрометированы менее чем за месяц
Джейкоб КреллSenior Director, Suzu Labs

TeamPCP целенаправленно атаковали инструменты безопасности — сканер уязвимостей, анализатор инфраструктурного кода, прокси для LLM. Эти инструменты по своей природе имеют широкий доступ, и компрометация одного из них даёт атакующим доступ ко всем секретам, которые этот инструмент должен был защищать.

Устанавливать пакеты из публичного реестра без проверки хешей и без lock-файлов — значит фактически отдать root-доступ любому, кто сможет скомпрометировать аккаунт мейнтейнера. Как ёмко выразилась Ноэлль Мурата, старший инженер по безопасности в Xcape: «Это цифровой эквивалент того, чтобы съесть бутерброд, найденный в метро, и удивиться пищевому отравлению».

Подробный технический анализ от Datadog Security Labs доступен здесь. Оригинальный отчёт FutureSearch — здесь. Официальный security-апдейт LiteLLM — здесь.

Проверьте свои зависимости сегодня. Команды для аудита — в разделе выше.