Шпионский код в LiteLLM активировался без вызова библиотеки: атака затронула PyPI и Docker-образы
Атакующие внедрили шпионский код в релиз LiteLLM 1.107.0, который был доступен для загрузки 21 октября. Под удар попали все семь wheel-сборок, размещённых в PyPI, а также контейнерные образы Docker. Разработчики подтвердили, что вредоносные файлы распространялись через официальную систему выпуска, что делало релиз внешне легитимным.
Главным инструментом скрытой активации стал файл cook.pth. Установщик помещал его в каталог site-packages, а интерпретатор Python автоматически обрабатывает такие файлы при каждом запуске. Строка import cook в нём запускала спрятанный в cook.py модуль, который начинал похищать данные.
Никакого явного обращения к LiteLLM из кода приложения не требовалось. Аналитики компании Upwind обнаружили и второй компонент автоматической загрузки — sitecustomize.py. Он также запускался без участия разработчика и создавал фоновый процесс, готовый выполнять команды, полученные извне.
Шпион целенаправленно искал пароли и cookie-файлы браузеров, SSH-ключи, токены GitHub, AWS, Azure и Google Cloud, а также конфигурации различных ИИ-инструментов. В средах, где был развёрнут сам LiteLLM, вредоносная программа могла извлечь из его базы данных ключи доступа к подключённым моделям. Все собранные сведения шифровались и отправлялись на домен litellm.dev, который не имеет отношения к проекту.
Точное число пострадавших установить пока не удалось. Для закрепления в системе использовался отдельный механизм. Раз в час вредонос проверял файл в репозитории на GitHub, чтобы получить адрес управляющего сервера и загрузить оттуда команды для выполнения.
На момент анализа этот файл оставался пустым, поэтому активность второй стадии через данный канал не подтверждена. В операционной системе Windows часть этого механизма не функционировала, однако сам похититель учётных данных сохранял полную работоспособность. Код появился не в публичном репозитории LiteLLM, а в его подделке.
Злоумышленники заменили источник сборки на Berri-AI/litellm, использовав лишний дефис в названии, чтобы имитировать официальный BerriAI/litellm. Для выпуска релиза они применили токены GitHub CLI, принадлежавшие трём разным разработчикам. Один токен позволил обойти защиту ветки, второй — одобрить публикацию, а третий — удалить журналы сборки, заметая следы.
Команда LiteLLM предполагает, что токены утекли через журналы внутреннего шлюза, который был доступен из интернета. Разработчики зафиксировали случаи, когда инструмент Claude Code включал OAuth-токен GitHub CLI в текст своего ответа, и эта информация затем попадала в логи LiteLLM. На сервере также была найдена незнакомая учётная запись, но первоначальный вектор проникновения ещё выясняется.
В PyPI заражённая версия находилась с 11:39 до 13:23 по UTC, а вредоносные Docker-образы оставались доступны до 14:20 UTC. Команда оперативно отозвала все сборки, восстановила чистые теги и ограничила доступ к репозиторию на GitHub. Клиенты, использовавшие закрытый корпоративный реестр, не пострадали.
Библиотеку LiteLLM скачивают около 23 миллионов раз в неделю, но количество загрузок конкретно вредоносного релиза пока не раскрывается. Разработчики рекомендуют сначала удалить вредоносные файлы без запуска Python, поскольку даже команда pip может повторно активировать шпиона. После этого необходимо пересоздать окружения, перейти на проверенную версию 1.106.2 и сменить все ключи, к которым у скомпрометированной машины был доступ.
Это не первая атака на цепочку поставок LiteLLM: предыдущий инцидент произошёл в марте. Однако доказательств связи нынешнего случая с той кампанией на данный момент нет.