Attaque de la chaîne d’approvisionnement d’Ultralytics AI via Pwn Request
11 décembre 2024
0 minutes de lectureL’attaque de la chaîne d’approvisionnement de ultralytics s’est déroulée en deux phases distinctes, du 4 au 7 décembre 2024. Lors de la première phase, deux versions malveillantes ont été publiées sur PyPI : la version 8.3.41, publiée le 4 décembre à 20:51 UTC, est restée disponible pendant environ 12 heures, jusqu’à son retrait le 5 décembre à 09:15 UTC. La version 8.3.42 a été publiée peu après, le 5 décembre à 12:47 UTC, et est restée disponible environ une heure, avant son retrait à 13:47 UTC.
La deuxième phase a eu lieu le 7 décembre, lorsque l’attaquant a publié directement deux autres versions malveillantes sur PyPI, en contournant entièrement GitHub Actions. La version 8.3.45 a été publiée à 01:41 UTC et est restée disponible environ 8 heures, jusqu’à 10:08 UTC. La version 8.3.46 a été publiée à 02:27 UTC et est restée disponible environ 7,5 heures, jusqu’à son retrait à 10:09 UTC.
L’attaque a d’abord été détectée par plusieurs moyens, notamment par le système automatisé de détection des abus de Google Colab, qui a commencé à signaler une activité suspecte quelques heures après la première publication malveillante. Des utilisateurs de divers projets ont signalé une utilisation inhabituelle du processeur, et des responsables de packages ont relevé des divergences entre le dépôt GitHub et les versions sur PyPI.
Chronologie de l’exploitation
2024-06-04 Premier commit du scanner GitHub Actions de Snyk
Lien : https://github.com/snyk-labs/github-actions-scanner
2024-08-14 Adnan Khan signale GHSA-7x29-qqmq-v6qc aux responsables d’Ultralytics : vulnérabilité d’injection de modèle
Lien : https://github.com/ultralytics/actions/security/advisories/GHSA-7x29-qqmq-v6q
2024-08-14 Publication de ultralytics/actions v0.0.3, avec un correctif pour GHSA-7x29-qqmq-v6qc
Lien : https://github.com/ultralytics/actions/security/advisories/GHSA-7x29-qqmq-v6qc
2024-08-24 ultralytics/actions v0.0.24 réintroduit la vulnérabilité dans le commit c1365ce
2024-12-03 22:28:49 @jiwuwgknvm commence à préparer une attaque malveillante
2024-12-03 22:33:47 @jiwuwgknvm soumet la PR #17984 (supprimée depuis), qui contient un voleur de jetons run.sh
2024-12-04 19:33:00 @openimbot soumet la PR #18018 avec une injection de modèle
Lien : https://github.com/ultralytics/ultralytics/pull/18018
2024-12-04 19:57:00 @openimbot soumet la PR #18020 avec une autre injection de modèle
Lien : https://github.com/ultralytics/ultralytics/pull/18020
2024-12-04 20:50:00 Publication de v8.3.41 déclenchée par @UltralyticsAssistant
2024-12-04 20:51:12 Publication de v8.3.41 sur PyPI
2024-12-04 23:46:00 Signalement du problème #4979 de Google Colab : compte bloqué à cause du cryptominage
Lien : https://github.com/googlecolab/colabtools/issues/4979
2024-12-05 05:34:00 Ouverture du problème #18027 : signalement d’une divergence sur PyPI
Lien : https://github.com/ultralytics/ultralytics/issues/18027
2024-12-05 05:35:00 Ouverture du problème #843 de ComfyUI : signalement de cryptominage
Lien : https://github.com/ltdrdata/ComfyUI-Impact-Pack/issues/843
2024-12-05 07:50:00 Ouverture du problème #18030 : utilisation du processeur à 100 %
Lien : https://github.com/ultralytics/ultralytics/issues/18030
2024-12-05 09:15:06 Retrait de v8.3.41 de PyPI (après environ 12 heures)
2024-12-05 09:39:00 Ouverture du problème #184 de Comic-translate : signalement de minage
Lien : https://github.com/ogkalu2/comic-translate/issues/184
2024-12-05 12:46:00 Publication de v8.3.42 déclenchée par @glenn-jocher
2024-12-05 12:47:29 Publication de v8.3.42 sur PyPI
2024-12-05 13:47:30 Retrait de v8.3.42 de PyPI (après environ 1 heure)
2024-12-05 15:17:00 @glenn-jocher annonce l’exclusion de @openimbot d’Ultralytics
2024-12-06 19:51:00 Ouverture du problème #19 d’AdvancedLivePortrait-WebUI : alerte de sécurité
Lien : https://github.com/jhj0517/AdvancedLivePortrait-WebUI/issues/19
2024-12-07 01:41:45 Publication directe de v8.3.45 sur PyPI (sans CI/CD)
2024-12-07 02:27:14 Publication directe de v8.3.46 sur PyPI (sans CI/CD)
2024-12-07 04:00:00 Adnan Khan annonce que v8.3.45 et v8.3.46 sont malveillantes
2024-12-07 10:08:32 Retrait de v8.3.45 de PyPI (après environ 8 heures)
2024-12-07 10:09:08 Retrait de v8.3.46 de PyPI (après environ 7,5 heures)
Une attaque au cryptominage de Monero
Les versions malveillantes de ultralytics contenaient une charge utile de cryptominage conçue pour fonctionner discrètement en arrière-plan tout en consommant d’importantes ressources système. Le mineur était une implémentation de XMRig, configurée spécifiquement pour miner la cryptomonnaie Monero. Le malware était suffisamment sophistiqué pour déclencher les systèmes automatisés de détection des abus de Google Colab. Certains utilisateurs ont ainsi vu leur compte suspendu temporairement en raison de la forte utilisation du processeur caractéristique du minage.
Le mineur a été injecté dans le package en modifiant deux fonctions clés : safe_download et safe_run. La première étape consistait à intégrer un téléchargeur côté client dans la fonction safe_download, afin de récupérer la charge utile de minage. La fonction safe_run a été modifiée pour exécuter le mineur en arrière-plan et tenter de dissimuler sa consommation de ressources. Toutefois, la forte utilisation du processeur nécessaire au minage de cryptomonnaies a rendu la présence du malware évidente pour de nombreux utilisateurs.
Comment préparer la remédiation d’Ultralytics
Évaluez votre exposition à cette dépendance Python
Plages temporelles des versions concernées :
v8.3.41 : du 2024-12-04 20:51 UTC au 2024-12-05 09:15 UTC (environ 12 heures)
v8.3.42 : du 2024-12-05 12:47 UTC au 2024-12-05 13:47 UTC (environ 1 heure)
v8.3.45 : du 2024-12-07 01:41 UTC au 2024-12-07 10:08 UTC (environ 8 heures)
v8.3.46 : du 2024-12-07 02:27 UTC au 2024-12-07 10:09 UTC (environ 7,5 heures)
Pour vérifier si vous êtes concerné :
Examinez les journaux de
pip installpour ces périodesVérifiez votre version actuelle :
pip show ultralyticsExaminez les journaux système pour repérer toute activité inhabituelle du processeur pendant ces périodes
Vérifiez si des compilations automatisées ou des exécutions CI/CD ont eu lieu pendant ces périodes
Projets connus pour dépendre d’Ultralytics
Ultralytics est une bibliothèque d’IA très utilisée dans l’écosystème Python de l’IA et du machine learning, notamment pour les tâches de vision par ordinateur. Parmi les projets notables :
ComfyUI : utilise YOLOv8 pour la détection d’objets dans de nombreux nœuds personnalisés populaires. L’équipe a publié une déclaration sur la situation ici.
Comic-Translate : utilise les modèles YOLO pour la détection de texte
Roboflow : intégration de YOLOv8 pour la détection d’objets
De nombreux autres outils Stable Diffusion et interfaces Web
Explication de l’attaque de la chaîne d’approvisionnement ultralytics/actions
L’attaque a exploité une chaîne sophistiquée de vulnérabilités dans GitHub Actions. Elle visait directement le système d’automatisation des workflows à l’aide d’une technique appelée injection de modèle via le nom d’une branche. Voici le détail de l’attaque :
La compromission initiale a eu lieu par le biais de deux pull requests (PR #18018 et #18020) malveillantes soumises depuis le compte @openimbot. Ces PR ont exploité une vulnérabilité dans le workflow format.yml, qui utilisait un déclencheur pull_request_target dangereux associé à des expressions de modèle non échappées.
L’attaque s’est déroulée en plusieurs étapes :
L’attaquant a créé une branche dont le nom soigneusement conçu contenait des commandes shell :
Lorsque le workflow a traité ce nom de branche, l’expression de modèle a été développée directement dans le contexte du shell à cause de cette ligne vulnérable :
La commande développée a téléchargé et exécuté un script shell malveillant qui :
a exfiltré des jetons et des secrets GitHub
a contaminé le cache pip utilisé par setup-python
a modifié les distributions publiées pour y inclure le mineur de cryptomonnaie
a potentiellement dérobé des identifiants d’API PyPI
Cette vulnérabilité était particulièrement efficace, car elle exploitait une action personnalisée dans ultralytics/actions qui avait réintroduit un problème de sécurité déjà corrigé.
Analyse avec Snyk Open Source
La base de données de vulnérabilités et les outils CLI de Snyk peuvent vous aider à déterminer si vous utilisez une version compromise du package Ultralytics. Vous pouvez également les utiliser pour analyser des projets open source de manière plus générale. Pour analyser votre projet :
1. Installez la CLI Snyk :
2. Authentifiez-vous auprès de Snyk :
3. Analysez votre projet Python :
Vous saurez ainsi si vous utilisez l’une des versions malveillantes connues (8.3.41, 8.3.42, 8.3.45 ou 8.3.46) du package Ultralytics. L’analyse recherchera également d’autres vulnérabilités potentielles dans vos dépendances.
Intégrez Snyk GitHub Actions Scanner à votre boîte à outils DevSecOps
Snyk GitHub Actions Scanner est un outil open source qui peut vous aider à détecter les configurations GitHub Actions vulnérables, comme celles exploitées lors de cet incident. Il ne s’agit pas d’un produit officiel de Snyk, mais c’est un outil précieux pour votre boîte à outils DevSecOps.
Pour utiliser le scanner :
1. Clonez le dépôt et installez les dépendances :
2. Configurez votre jeton GitHub :
3. Analysez un dépôt :
Le scanner recherche plusieurs problèmes critiques, notamment :
PWN_REQUEST : détecte les workflows qui utilisent pull_request_target et extraient également les branches des pull requests — exactement la vulnérabilité exploitée lors de cet incident. Cette pratique est dangereuse, car pull_request_target s’exécute avec les secrets du dépôt, tout en pouvant être déclenché par des contributeurs externes non fiables.
CMD_EXEC : détecte les expressions de modèle non échappées comme
${{ }}dans les directives run, susceptibles de provoquer une injection de commandes.
Pour une analyse plus approfondie qui vérifie les actions référencées :
Cette vérification analyse les actions référencées jusqu’à 5 niveaux de profondeur et peut ainsi détecter des vulnérabilités dans l’ensemble de votre chaîne d’actions.
Risques liés à la sécurité de l’IA et sécurité de la chaîne d’approvisionnement
L’incident ultralytics s’ajoute à la longue liste des attaques visant la sécurité de la chaîne d’approvisionnement open source. Les registres npm et PyPI sont tous deux la cible d’attaques par malware axées sur les cryptomonnaies, qui mettent souvent en lumière des pratiques de sécurité insuffisantes de la part des responsables de packages et une configuration non sécurisée des projets. Cette attaque contre GitHub Actions montre combien il est crucial de respecter rigoureusement les bonnes pratiques de sécurité.
Les risques liés à la sécurité de l’IA ne se limitent pas aux incidents touchant la chaîne d’approvisionnement open source : ils s’étendent également au machine learning et aux registres d’échange de modèles. Des attaques imminentes, comme l’exécution de code à distance, peuvent toucher les développeurs en exploitant des vulnérabilités dans les formats de fichiers de deep learning et du code non sécurisé généré par l’IA, que les développeurs utilisent couramment via les LLM.
Découvrez comment utiliser Snyk pour sécuriser le code généré par l’IA.
Anticipez l’avenir des assistants de programmation avec Snyk
Découvrez les assistants de programmation et comment intégrer ces outils aux workflows de développement.
