Двадцать первого октября 2026 года в версии 1.107.0 LiteLLM обнаружили вредоносный код. Речь о прокси с открытым исходным кодом, который маршрутизирует запросы между десятками провайдеров больших языковых моделей. Заражены семь скомпилированных пакетов на PyPI, охватывающих все поддерживаемые платформы, включая macOS, Linux с musl и Windows. Исходный репозиторий и архив исходников при этом остались чистыми. В колесах нашли два компонента: сборщик учётных данных и программу удалённого доступа.
Описание
Внедрение опирается на два механизма автозапуска интерпретатора Python. Файл с расширением .pth в каталоге установленных пакетов содержит единственную строку импорта, поэтому модуль выполняется при каждом старте Python. Второй файл носит имя sitecustomize и срабатывает до пользовательского кода, порождая фоновый процесс с блокировкой от повторного запуска. Все три файла перечислены в манифесте RECORD колеса, а метки времени внутри архива совпадают с метками легитимных файлов (по данным технического разбора). Ни один из них не встречается в архиве исходников версии 1.107.0, а остальное дерево библиотеки совпадает с легитимным выпуском.
Сборщик учётных данных выполняется в отдельном потоке и срабатывает один раз на хост. В перечень целей входят ключи SSH и GPG, истории оболочек, пароли и файлы cookie браузеров на Chromium и Firefox, токены Kubernetes, секреты CI и учётные данные облачных провайдеров. Отдельный модуль обращается к базе самого прокси и выгружает сохранённые ключи провайдеров вместе с конфигурацией моделей. Собранные данные шифруются случайным ключом AES-256, ключ оборачивается открытым ключом RSA-4096 из полезной нагрузки, а архив уходит по незашифрованному HTTP на домен, имитирующий имя проекта. Метка успешной отправки создаётся только после эксфильтрации.
Загрузчик раз в час читает управляющий файл в публичном репозитории GitHub и исполняет полученный оттуда код Python без проверки целостности. На момент наблюдения этот файл отдавался пустым, поэтому адрес сервера не определялся (как сообщила команда JFrog Security Research). Кто изменил сборочное дерево и через какую учётную запись артефакты попали на PyPI, не установлено. В конфигурации сборочного инструмента maturin появилась директива, добавляющая в колесо содержимое каталога, отсутствующего в репозитории и теге. Метаданные архива скорее указывают на включение при обычной сборке, чем на ручную перепаковку.
Для LiteLLM это второй документированный взлом за 2026 год. В марте первый случай прошёл через незакреплённую по версии сборку сканера Trivy и закончился публикацией двух версий с бэкдором. Тогда доступ к сборочным и публикационным учётным данным позволил выпустить вредоносный код под видом обычного обновления. Наборы файлов автозапуска, поведение закрепления и сетевая инфраструктура у кампаний различаются, поэтому их считают раздельными. Полезная нагрузка срабатывает даже там, где приложение ни разу не импортировало библиотеку. Затронуты рабочие станции разработчиков, сборочные узлы, контейнеры и хосты прокси с доступом к базе LiteLLM.
Индикаторы не показывают, дошла ли эксфильтрация до сервера. Отсутствие метки означает лишь то, что отправка не завершилась, а не чистоту машины. Ветка загрузчика на Windows не выполняется из-за отсутствия системного вызова fork, но сборщик учётных данных там работает. Пустой управляющий файл можно наполнить в любой момент, поэтому состояние покоя обратимо. Имена служебных файлов встречаются и у других пакетов, из-за чего возможны ложные срабатывания.