TeamPCP : backdoor LiteLLM - analyse d’une compromission de la chaîne d’approvisionnement Python
Églantine Montclair
Une chaîne d’approvisionnement compromise ? En 2026, plus de 30 % des incidents majeurs signalés par l’ANSSI proviennent de bibliothèques open-source. Cette statistique laisse entrevoir l’ampleur du danger lorsqu’un acteur tel que TeamPCP infiltre un package Python populaire comme LiteLLM. Analyse des menaces du 24 mars 2026
Le backdoor LiteLLM découvert dans les versions 1.82.7 et 1.82.8 constitue un exemple emblématique de supply chain attack. Dans cet exposé, vous comprendrez le fonctionnement de l’injection, les conséquences pour les environnements Kubernetes et CI/CD, ainsi que les mesures concrètes à mettre en œuvre pour protéger vos projets.
Comprendre la compromission de LiteLLM
Contexte du package et de son usage
LiteLLM est une bibliothèque Python largement adoptée pour la gestion de modèles de langage large (LLM). Elle simplifie l’interfaçage avec les API d’OpenAI, Anthropic ou Cohere, et s’intègre naturellement aux pipelines CI/CD grâce à des étapes de test automatisées. En France, de nombreuses startups du secteur IA l’utilisent pour développer des chatbots et des assistants vocaux, souvent au sein de clusters Kubernetes hébergés sur des clouds européens.
Mécanisme d’injection du code malveillant
Les versions 1.82.7 et 1.82.8 ont été publiées le 24 mars 2026 sur PyPI, après passage par le scanner Trivy intégré au workflow GitHub Actions du développeur. Deux vecteurs distincts ont été introduits :
- Modification du fichier
litellm/proxy/proxy_server.py- le code malveillant est exécuté dès l’import du module, grâce à une fonction placée au niveau racine du script. - Insertion d’un fichier
.pth(litellm_init.pth) - ce fichier est lu automatiquement par site.py à chaque démarrage de l’interpréteur Python, déclenchant ainsi le payload même si LiteLLM n’est jamais importé.
« Python .pth files placed in site-packages are processed automatically by site.py at interpreter startup », explique Endor Labs. Cette subtilité technique rend la détection difficile, d’autant plus que le code est encodé en Base64 et déployé via un sous-processus. VoidStealer malware evasion techniques
Les trois étapes de l’attaque
Collecte d’identifiants et exfiltration
Le premier stade consiste en un credential harvester qui balaie les clés SSH, les jetons Kubernetes, les fichiers .env et même les portefeuilles de cryptomonnaies. Les données sont empaquetées dans une archive chiffrée tpcp.tar.gz puis envoyées via un POST HTTPS vers le domaine de commande-et-contrôle models.litellm.cloud.
Mouvement latéral dans Kubernetes
Une fois les secrets en main, le malware démarre un toolkit de déplacement latéral : il crée un pod privilégié sur chaque nœud du cluster, monte le système de fichiers hôte en chroot et déploie un service systemd nommé sysmon.service. Ce service exécute un script Python (~/.config/sysmon/sysmon.py) qui interroge toutes les 50 minutes l’URL checkmarx.zone/raw.
Persistance via systemd
Le composant de persistance repose sur un systemd user service qui assure la relance du script même après redémarrage du nœud. Le trafic sortant est filtré : si l’URL retournée pointe vers youtube.com, le script s’arrête, ce qui constitue un kill switch observé dans plusieurs campagnes de TeamPCP.
« This campaign is almost certainly not over », prévient Endor Labs. Le groupe exploite chaque jeu d’identifiants volés pour cibler de nouvelles infrastructures, créant ainsi un effet boule de neige.
Impact sur l’écosystème français
Risques pour les entreprises utilisant PyPI
En France, plus de 650 000 projets Python sont recensés sur le registre officiel, dont une part importante dépend de LiteLLM. Une compromission de ce type expose les données sensibles de secteurs critiques : fintech, santé et télécommunications.
Conséquences sur les pipelines CI/CD
Le recours à des scanners comme Trivy ou KICS dans les GitHub Actions ne suffit plus à garantir la sécurité. L’injection s’est produite pendant le processus de création du wheel (.whl), après la phase de scan, démontrant que les contrôles statiques doivent être complétés par des vérifications d’intégrité des artefacts.
Détection et réponse
- Audit des dépendances : répertoriez toutes les installations de
litellmet identifiez les versions 1.82.7/1.82.8. - Isolation immédiate : retirez les hôtes concernés du réseau et suspendz les pods Kubernetes suspects.
- Analyse réseau : filtrez le trafic sortant vers
models.litellm.cloudetcheckmarx.zone. - Suppression des services persistants : supprimez le fichier
sysmon.serviceet le script associé. - Rotation des secrets : révoquez toutes les clés SSH, tokens et credentials exposés.
- Renforcement du CI/CD : ajoutez des étapes de vérification de l’intégrité des wheel (hash SHA-256) après chaque build.
Tableau comparatif des versions
| Version | Présence du .pth | Payload exécuté à l’import | Pod privilégié déployé | Persistance systemd |
|---|---|---|---|---|
| 1.82.6 (clean) | ❌ | ❌ | ❌ | ❌ |
| 1.82.7 (malicieux) | ❌ | ✔️ (proxy_server.py) | ✔️ | ✔️ |
| 1.82.8 (malicieux) | ✔️ | ✔️ (via .pth) | ✔️ | ✔️ |
Exemple de script de détection (Python)
import pkg_resources
import subprocess
import re
# Liste les paquets installés et leurs versions
for dist in pkg_resources.working_set:
if dist.project_name.lower() == "litellm":
print(f"[!] LiteLLM détecté : {dist.version}")
if dist.version in ("1.82.7", "1.82.8"):
# Recherche d'un .pth suspect dans site-packages
site_pkgs = subprocess.check_output(["python", "-m", "site"], text=True)
if re.search(r"litellm_init\.pth", site_pkgs):
print("[!] Fichier .pth malveillant trouvé")
Bonnes pratiques pour sécuriser la chaîne d’approvisionnement
Renforcer les scans CI/CD
Intégrez des outils de analysis dynamique (sandbox) qui exécutent le wheel dans un environnement isolé avant publication. Coupez les permissions du runner GitHub Actions afin qu’il ne puisse pas pousser directement sur PyPI sans approbation manuelle.
Gestion des dépendances
Adoptez une politique de verrouillage des versions (requirements.txt ou poetry.lock) et surveillez régulièrement les alertes de sécurité publiées par les bases de données comme Snyk ou OSS Index. Un système de mise à jour automatisée doit être précédé d’une phase de validation manuelle lorsqu’une nouvelle version majeure apparaît.
Surveillance continue
Déployez des agents de runtime monitoring capables de détecter l’injection de modules au moment de l’import (ex. : importlib.metadata) et alertez immédiatement les équipes SRE. Conservez les journaux d’audit pendant au moins 90 jours afin de retracer toute activité suspecte.
Conclusion : agir dès maintenant pour stopper la propagation
IA et fraude musicale : 10 M$ de royalties fantômes L’incident du backdoor LiteLLM illustre la fragilité de la supply chain open-source et la nécessité d’une défense en profondeur. En appliquant les contrôles recommandés - audit des versions, renforcement des pipelines CI/CD, et surveillance continue - vous limitez les chances que vos environnements Python deviennent le prochain vecteur d’attaque de TeamPCP. Restez vigilant, revoyez vos pratiques de gestion des dépendances et assurez-vous que chaque artefact publié soit certifié intègre avant d’être déployé en production.