Заражённый релиз LiteLLM 1.107.0 на PyPI крал учётные данные и открывал бэкдор

· Безопасность
Версия 1.107.0 популярного LLM-шлюза LiteLLM, попавшая в PyPI, содержала похититель секретов и бэкдор для удалённого исполнения кода. Исходники на GitHub были чисты, а вредоносные файлы запускались при старте любого Python-процесса на машине.

cover.svg

Исследователи SafeDep сообщили, что релиз LiteLLM 1.107.0 на PyPI был скомпрометирован: все семь колёс (Linux, macOS, Windows) устанавливали в site-packages три дополнительных файла — похититель учётных данных и бэкдор. Код из официального репозитория BerriAI/litellm на GitHub этих файлов не содержал. PyPI уже удалил релиз.

Соседние версии 1.106.2, а также 1.107.0rc1 и rc2 чисты, как и сопутствующие пакеты litellm-proxy-extras и litellm-enterprise, которые релиз фиксировал.

Что делал вредонос

Файл cook.pth содержал строку import cook, из-за чего Python при каждом запуске исполнял cook.py — похититель секретов. Он собирал SSH-ключи, облачные учётные данные, секреты CI/CD, токены AI-инструментов, пароли браузеров и ключи LLM-провайдеров из базы LiteLLM-прокси. Отдельно примечательно, что модуль ai_devtools целился в токены Claude Code, Cursor, Copilot, Gemini CLI и десятка других ассистентов, а env_vars вытягивал переменные окружения чужих процессов через /proc/<pid>/environ.

Данные шифровались ключом AES-256, сам ключ — RSA, и отправлялись POST-запросом на www.litellm[.]dev (не путать с доменом проекта). Второй файл, sitecustomize.py, запускал фоновый демон: раз в час он читал адрес сервера из файла на GitHub, снова запускал похититель и скачивал с указанного сервера произвольный код, исполняя его через exec().

Поскольку оба файла срабатывали при старте любого Python-процесса — приложения, pip, языковых серверов IDE, CI-заданий, — заражался даже тот процесс, который LiteLLM никогда не импортировал.

Как имплант попал в релиз

В pyproject.toml сборочного дистрибутива нашлась одна лишняя строка — data = "cook" в секции maturin. Она заставляла копировать папку cook/ в колесо. Атакующий заодно откатил номер версии с 1.108.0 на 1.107.0 и зафиксировал сопутствующие пакеты под значения rc2 — так diff зависимостей относительно rc2 не показывал ничего подозрительного.

Собранные колёса совпадают с выводом штатного релизного конвейера BerriAI: та же версия maturin, корректные записи RECORD, раздельные нативные сборки под три платформы. В Windows-колесе все .py-файлы имеют CRLF-переводы строк — след checkout под Windows. SafeDep со средней и высокой уверенностью заключает, что частный конвейер BerriAI собрал колёса из изменённого атакующим исходника; подтвердить причину могут только логи самого конвейера.

Исход

Примерно через два часа после публикации аккаунт letters9813, хранивший адрес управляющего сервера, вернул 404 — и бэкдор перестал находить сервер. Но хосты, успевшие запустить демон раньше, могли получить и исполнить код второй стадии. Пострадавшим стоит проверить наличие упомянутых файлов и индикаторов в /tmp, а также ротировать все секреты, к которым имел доступ Python-процесс.


Источник: Hacker News

Комментарии

Войдите, чтобы комментировать.

  • Пока нет комментариев.