litellm — Python-библиотека для унифицированной работы с API разных LLM была отравлена.Один
pip install - и твои SSH-ключи, AWS/GCP/Azure креды, K8s Secrets, пароли от БД, криптокошельки, все API-ключи из .env — всё это упаковывается, шифруется через AES-256 и отправляется POST-запросом на поддельный домен http://models.litellm.cloud. Если обнаруживается среда K8s , то дополнительно разворачивается привилегированный Pod на каждом узле для латерального распространения.Самое неприятное — способ активации. В пакет подложили файл
litellm_init.pth размером 34 КБ. В Python .pth — это файлы конфигурации путей, которые автоматически обрабатываются модулем site при старте интерпретатора. Если строка начинается с import — она просто выполняется. Атака использует это поведение:import os, subprocess, sys; subprocess.Popen([sys.executable, "-c", "import base64; exec(base64.b64decode('...'))"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)Тебе не нужно импортировать
litellm и не нужно вызывать никакие функции. Запускаешь pip, python -c, IDE поднимает language server, или pytest гоняет тесты — достаточно старта Python-интерпретатора, и вредоносный код уже выполняется. Установил — значит уже скомпрометирован. Всё происходит незаметноПейлоад — трёхслойная base64-обфускация:
- первый слой (.pth) стартует подпроцесс
- второй — оркестратор с вшитым RSA-публичным ключом (4096 бит)
- третий — сборщик секретов, который вычищает
/home, /opt, /srv, /var/www, /app, /data, /tmpПосле сбора:
- генерируется случайный 32-байтовый AES-ключ
- данные шифруются
- ключ шифруется через RSA-OAEP
- всё пакуется в
tpcp.tar.gz и уходит наружуПомимо этого есть персистентный бэкдор:
- устанавливается как user-service systemd:
~/.config/sysmon/sysmon.py- каждые 50 минут ходит на
http://checkmarx.zone за командами- скачивает в
/tmp/pglog и исполняет- стартует с задержкой 5 минут (обход песочниц)
Даже если удалить
litellm, бэкдор остаётся.pip install --require-hashes тоже не спасает — вредоносный файл легитимно прописан в RECORD, хэши совпадают, потому что пакет опубликован с украденного, но валидного PyPI-токена.Даже если ты сам не ставил
litellm, он тянется как зависимость в 2000+ пакетов (например, DSPy, MLflow, Open Interpreter и др.). По данным Mandiant, уже заражено 1000+ SaaS-окружений, прогноз — до 10 000.Ирония в том, что атаку почти не обнаружили - её выдал баг у самих атакующих.
.pth запускал подпроцесс, а тот при старте снова обрабатывал тот же .pth, вызывая рекурсивный запуск и фактически fork bomb. Это сожрало память у одного пользователя Cursor — так всё и вскрылось. Как отметил Karpathy: если бы код был чуть аккуратнее, атаку могли бы не замечать неделями.Ещё абсурднее сама точка входа:
- 19 марта был скомпрометирован сканер безопасности Trivy
- через него группа TeamPCP украла PyPI-токен
litellm- 24 марта они выкатили заражённую версию
Инструмент безопасности стал вектором атаки.
После того как в GitHub создали issue:
- через 102 секунды атакующие с 73 взломанных аккаунтов наспамили 88 комментариев
- затем закрыли issue через скомпрометированный аккаунт мейнтейнера
Скрипт для самопроверки (версии, .pth, бэкдоры, сетевые соединения, K8s):
https://gist.github.com/sorrycc/30a765b9a82d0d8958e756b251828a19
Безопасная версия:
litellm==1.82.6Если у тебя стояли
1.82.7 или 1.82.8 — считай, что все креды утекли. Срочно ротируй всё. 🔨
