LiteLLM 1.107.0 piégé pour voler les clés d’IA

L’outil de passerelle pour grands modèles de langage LiteLLM a subi le 21 octobre un empoisonnement de sa chaîne d’approvisionnement. L’entreprise de sécurité cloud Wiz a révélé que la version altérée, LiteLLM 1.107.0, avait été publiée le jour même sur PyPI, et que les images de GHCR et de Docker Hub portant les étiquettes v1.107.0, latest, main-latest et main-stable contenaient elles aussi le même programme de vol de données. La dernière version sûre indiquée par le projet est la v1.106.2.

LiteLLM est développé par BerriAI et s’utilise couramment comme couche de proxy interne qui redirige, via une interface unifiée, les requêtes vers des centaines de services de modèles comme OpenAI, Anthropic ou Bedrock. Derrière le proxy sont stockées les clés d’API de chaque fournisseur, et c’est précisément ce que visait l’attaque.

À peine installé, le vol commence

Le paquet malveillant dépose trois fichiers à la racine de site-packages : cook.pth, cook.py et sitecustomize.py. Les deux premiers exploitent le mécanisme .pth de Python et s’exécutent dès le démarrage de l’interpréteur, sans qu’aucun code applicatif n’ait besoin d’importer LiteLLM.

Le voleur s’appelle en interne privcollect, compte 16 modules et vise notamment :

  • les identifiants et cookies des navigateurs Chrome, Firefox, Edge et Safari
  • les identifiants cloud d’AWS, GCP et Azure
  • les clés d’API d’éditeurs d’IA comme OpenAI, Anthropic et Cohere
  • les clés privées SSH et GPG ainsi que l’historique du shell
  • les identifiants des fournisseurs en amont, extraits directement de la base PostgreSQL de LiteLLM Proxy

Les données sont d’abord chiffrées en AES-256-CBC, la clé est ensuite enveloppée par du RSA-4096, puis le tout est envoyé en HTTP POST vers le domaine factice enregistré par les attaquants, www.litellm[.]dev. Le fichier sitecustomize.py, qui ne s’exécute que sous Linux et macOS, va chercher l’adresse de la seconde phase dans un dépôt GitHub servant de « boîte aux lettres morte » ; Wiz indique que ce fichier n’a jamais contenu autre chose que des valeurs de test, et GitHub a supprimé le dépôt.

La chronologie à plat

D’après les horaires UTC publiés par Wiz, on peut estimer grossièrement chaque fenêtre :

ÉtapeHeure (UTC)Durée
Le faux dépôt reçoit 10 commits08:56–10:46environ 1 h 50 min
Version malveillante en ligne sur PyPI11:39–13:20environ 1 h 41 min
Étiquettes Docker altérées en ligneretirées vers 13:53environ 2 h 14 min à partir de la mise en ligne sur PyPI
Les attaquants valident les identifiants AWS16:20–17:01environ 4,5 h après l’exfiltration

Un peu plus d’une heure sur PyPI semble court, mais des étiquettes comme latest sont récupérées automatiquement par de très nombreux pipelines CI et déploiements Kubernetes ; l’exposition dépend donc surtout du nombre d’environnements ayant reconstruit leurs images pendant cette période. Wiz ne fournit aucun chiffre de téléchargements, et le nombre d’organisations touchées ne peut pas être vérifié pour l’instant.

Une fois les identifiants en main, les attaquants ont utilisé les rôles d’instance AWS des runners CI et des nœuds Kubernetes compromis pour appeler des interfaces telles que sts:GetCallerIdentity et bedrock:ListFoundationModels. Wiz juge ce mode opératoire cohérent avec le LLMjacking, c’est-à-dire le détournement de comptes cloud tiers pour consommer gratuitement des appels à de grands modèles ; dans certains environnements, les attaquants ont en outre énuméré IAM dans le cadre d’une reconnaissance classique.

Un jeton GitHub soupçonné d’être la porte d’entrée

Les 10 commits poussés par les attaquants se trouvent dans le faux dépôt Berri-AI/litellm ; les neuf premiers portaient une signature GitHub, le dernier n’était pas signé et utilisait une autre adresse e-mail. BerriAI a déclaré :

« malicious actions were taken through three engineers' GitHub accounts »
(Des actions malveillantes ont été effectuées via les comptes GitHub de trois ingénieurs.)

LiteLLM soupçonne que ces jetons OAuth de GitHub CLI ont fuité depuis un déploiement interne exposé sur Internet, peut-être en lien avec une faille tout juste corrigée ; Wiz précise explicitement que ce point n’est pas confirmé. BerriAI affirme que tous les jetons concernés ont été révoqués. Les équipes qui ont utilisé la 1.107.0 ou récupéré les images citées durant cette période doivent renouveler l’ensemble des identifiants cloud, clés de modèles et clés privées SSH lisibles sur leurs machines.

Sources : CocoLoop, blog de recherche de Wiz, bulletin du Wiz Threat Intelligence Center, déclaration publique de BerriAI ; vérification des versions et étiquettes d’images concernées, des noms de fichiers malveillants et des horaires UTC de chaque étape.