Le framework d'apprentissage automatique PyTorch ciblé par une attaque de confusion de dépendance,
permettant à une dépendance contrefaite "torchtriton" d'être téléchargée des milliers de fois

PyTorch a identifié une dépendance malveillante portant le même nom que la bibliothèque "torchtriton" du framework. Cela a conduit à une compromission réussie via le vecteur d'attaque de confusion de dépendance. Les administrateurs de PyTorch ont prévenu les utilisateurs qui ont installé PyTorch-nightly pendant les vacances de désinstaller le framework et la dépendance "torchtriton" contrefaite. L'individu derrière cette bibliothèque prétend être un hacker éthique.

PyTorch est l'une des boîtes à outils d'apprentissage automatique les plus populaires et les plus utilisées. Initialement développé et publié en tant que projet open source par Facebook (qui s'appelle désormais Meta), PyTorch a été remis à la Fondation Linux fin 2022, qui le gère désormais sous l'égide de la Fondation PyTorch.

PyTorch permet d'effectuer les calculs tensoriels nécessaires notamment pour l'apprentissage profond (deep learning). Ces calculs sont optimisés et effectués soit par le processeur (CPU) soit, lorsque c'est possible, par un processeur graphique (GPU) supportant CUDA. PyTorch se présente sous les traits d'un dérivé d'un logiciel antérieur, Torch, dont l'utilisation nécessitait la maîtrise du langage Lua. PyTorch est désormais indépendant de Lua et se programme en Python.

Le programme suivant montre la fonctionnalité de la bibliothèque avec un exemple simple :

Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import torch
dtype = torch.float
device = torch.device("cpu") # Tous les calculs seront exécutés sur le processeur
# device = torch.device("cuda:0") # Tous les calculs seront exécutés sur la carte graphique
 
# Création d'un tenseur rempli avec des nombres aléatoires
a = torch.randn(2, 3, device=device, dtype=dtype)
print(a) # Affichage du tenseur a
# Output: tensor([[-1.1884,  0.8498, -1.7129],
#                  [-0.8816,  0.1944,  0.5847]])
 
# Création d'un tenseur rempli avec des nombres aléatoires
b = torch.randn(2, 3, device=device, dtype=dtype)
print(b) # Affichage du tenseur b
# Output: tensor([[ 0.7178, -0.8453, -1.3403],
#                  [ 1.3262,  1.1512, -1.7070]])
 
print(a*b) # Affichage du produit (terme à terme) des deux tenseurs
# Output: tensor([[-0.8530, -0.7183,  2.58],
#                  [-1.1692,  0.2238, -0.9981]])
 
print(a.sum()) # Affichage de la somme de tous les éléments du tenseur a
# Output: tensor(-2.1540)
 
print(a[1,2]) # Affichage de l'élément de la 2e rangée et de la 3e colonne de a
# Output: tensor(0.5847)
 
print(a.min()) # Affichage de la valeur minimale du tenseur a
# Output: tensor(-1.7129)

De la vision par ordinateur au traitement du langage naturel, le framework d'apprentissage automatique open source PyTorch a gagné en importance dans les domaines commerciaux et universitaires.

Une bibliothèque malveillante cible les utilisateurs nocturnes de PyTorch

Vendredi dernier, les développeurs de PyTorch ont identifié une faille de sécurité. La violation n'a pas affecté la base de code PyTorch, mais plutôt un service appelé PyPI qui héberge des extensions tierces de l'outil de développement d'IA. Un hacker a téléchargé une extension malveillante sur PyPI qui aurait été téléchargée plus de 2 300 fois par les utilisateurs.

La dépendance malveillante "torchtriton" sur PyPI partage son nom avec la bibliothèque officielle publiée sur le dépôt de PyTorch-nightly. Mais, lors de la récupération des dépendances dans l'écosystème Python, PyPI a normalement la priorité, provoquant l'extraction du package malveillant sur votre machine au lieu de celui légitime de PyTorch.

« Étant donné que l'index PyPI a priorité, ce package malveillant a été installé à la place de la version de notre référentiel officiel. Cette conception permet à quelqu'un d'enregistrer un package du même nom que celui qui existe dans un index tiers, et pip installera sa version par défaut », a expliqué l'équipe PyTorch.

Pour empêcher des téléchargements supplémentaires, les développeurs de PyTorch ont renommé l'extension légitime imitée par le programme malveillant.

« Ce package malveillant a été installé à la place de la version de notre référentiel officiel », ont expliqué les développeurs dans un billet de blog. « Ce paquet malveillant porte le même nom torchtriton mais ajouté dans le code qui télécharge les données sensibles de la machine ». Il est d'ailleurs recommandé de désinstaller PyTorch-nightly si le téléchargement a été fait via pip entre le 25 et 30 décembre 2022 sur Linux :

Citation Envoyé par équipe PyTorch
Si vous avez installé PyTorch-nightly sur Linux via pip entre le 25 décembre 2022 et le 30 décembre 2022, veuillez le désinstaller ainsi que torchtriton immédiatement, et utilisez les derniers binaires nightly (plus récents que le 30 décembre 2022).
Nom : desinstaller.png
Affichages : 101707
Taille : 16,0 Ko

Ce type d'attaque de la chaîne d'approvisionnement est connu sous le nom de « confusion de dépendance » et ce vecteur d'attaque a été popularisé par le hacker éthique Alex Birsan. PyTorch déclare que les utilisateurs des packages stables PyTorch ne sont pas affectés par ce problème.

Un hacker vole des fichiers sensibles, et prétend être un hacker éthique

L'équipe de PyTorch explique que non seulement le "torchtriton" malveillant surveille votre système pour obtenir des informations de fingerprinting de base (telles que l'adresse IP, le nom d'utilisateur et le répertoire de travail actuel), mais il vole en outre des données sensibles :

  • Obtient des informations système :
    • le nom des serveurs de /etc/resolv.conf
    • le nom de l'hôte de gethostname()
    • le nom de l'utilisateur actuel de getlogin()
    • le nom du répertoire de travail actuel de getcwd()
    • les variables d'environnement
  • Peut lire les fichiers suivants :
    • /etc/hosts
    • /etc/passwd
    • les 1000 premiers fichiers dans $HOME/*
    • $HOME/.gitconfig
    • $HOME/.ssh/*

Il télécharge ensuite toutes ces données, y compris le contenu des fichiers, sur le domaine h4ck.cfd via des requêtes DNS chiffrées à l'aide du serveur DNS wheezy.io. PyTorch explique que le binaire « triton » malveillant contenu dans le « torchtriton » contrefait n'est exécuté que lorsque l'utilisateur importe le package « triton » de leur build. Cela nécessiterait un code explicite et n'est pas le comportement par défaut de PyTorch.

L'avis sur le domaine h4ck.cfd implique que toute l'opération est une recherche éthique, même si l'analyse indique le contraire.

Citation Envoyé par Avis
Bonjour, si vous êtes tombé dessus dans vos journaux, c'est probablement parce que votre Python était mal configuré et était vulnérable à une attaque de confusion de dépendance. Pour identifier les entreprises vulnérables, le script envoie les métadonnées sur l'hôte (telles que son nom d'hôte et répertoire de travail actuel). Une fois que j'ai identifié qui est vulnérable et [signalé] la découverte, toutes les métadonnées concernant votre serveur seront supprimées.
Contrairement au libellé de l'avis, le binaire non seulement collecte des « métadonnées », mais vole les secrets susmentionnés, y compris vos clés SSH, ,gitconfig, hosts et fichiers passwd, ainsi que le contenu des 1 000 premiers fichiers de votre répertoire HOME.

Il y a quelques jours, selon VirusTotal, une copie du binaire malveillant affichait une réputation propre. Mais il ne faut pas être dupe : contrairement à plusieurs packages de recherche et exploits PoC qui se distinguent par leur intention et leur comportement, "torchtriton" utilise des techniques anti-VM connues pour échapper à la détection. Plus important encore, la charge utile malveillante est obscurcie et entièrement contenue dans le format binaire, c'est-à-dire les fichiers Linux ELF, ce qui fait de la bibliothèque une valeur aberrante lorsqu'elle est juxtaposée à des exploits de confusion de dépendance éthique du passé livrés en texte clair.

Il faut également remarquer l'échantillon .bash_history qui liste des commandes et des entrées que l'utilisateur a tapées dans le terminal, ce qui est encore un autre caractère présenté par les logiciels malveillants.

Ce ne sera pas non plus la première fois qu'un hacker affirme que ses actions constituent une recherche éthique, juste au moment où il est pris en flagrant délit d'exfiltration de secrets : à la mi-2022, les bibliothèques Python et PHP extrêmement populaires, respectivement, "ctx" et "PHPass", ont été piratées et modifiées pour voler des clés AWS. Le chercheur à l'origine de l'attaque a ensuite affirmé qu'il s'agissait d'une recherche éthique.

Les archives publiques montrent que le domaine h4ck.cfd a été enregistré auprès de Namecheap le 21 décembre, quelques jours seulement avant cet incident. Vous trouverez ci-dessous la déclaration complète du propriétaire du domaine, qui semble également être derrière le domaine wheezy.io :

Hé, c'est moi qui ai réclamé le paquet torchtriton sur PyPi. Notez que cela n'était pas destiné à être malveillant !

Je comprends que j'aurais pu faire un meilleur travail en n'envoyant pas toutes les données de l'utilisateur. La raison pour laquelle j'ai envoyé plus de métadonnées est que dans le passé, lors d'enquêtes sur des problèmes de confusion de dépendance, dans de nombreux cas, il n'était pas possible d'identifier les victimes par leur nom d'hôte, leur nom d'utilisateur et leur CWD. C'est la raison pour laquelle cette fois j'ai décidé d'envoyer plus de données, mais avec le recul, c'était une mauvaise décision et j'aurais dû être plus prudent.

J'accepte le blâme pour cela et je m'en excuse. En même temps, je veux assurer que ce n'était pas mon intention de voler les secrets de quelqu'un. J'ai déjà signalé cette vulnérabilité à Facebook le 29 décembre (presque trois jours avant l'annonce) après avoir vérifié que la vulnérabilité est bien là. J'ai également fait de nombreux rapports à d'autres entreprises qui ont été touchées via leurs programmes HackerOne. Si mes intentions avaient été malveillantes, je n'aurais jamais rempli de rapport de prime de bogue et j'aurais juste vendu les données au plus offrant.

Je m'excuse encore une fois d'avoir causé des perturbations, j'assure que toutes les données que j'ai reçues ont été supprimées.

Au fait, dans mon rapport de bogue à Facebook, j'ai déjà proposé de leur transférer le package PyPi, mais jusqu'à présent, je n'ai reçu aucune réponse de leur part.
Quoi qu'il en soit, selon VirusTotal, 10 fournisseurs de sécurité ont désormais signalé le même fichier comme malveillant :

Nom : VT.png
Affichages : 1560
Taille : 31,7 Ko

Les mesures prises par l'équipe PyTorch pour atténuer le problème

L'équipe PyTorch a renommé la dépendance "torchtriton" en "pytorch-triton" et a réservé un paquet factice sur PyPI pour empêcher des attaques similaires. Le groupe cherche à revendiquer la propriété du "torchtriton" existant sur PyPI pour désamorcer l'attaque actuelle.

Nom : renomme.png
Affichages : 1562
Taille : 23,3 Ko

L'équipe a également pris deux autres mesures, notamment :
  • Tous les packages nightly qui dépendent de torchtriton ont été supprimés de nos index de packages sur https://download.pytorch.org jusqu'à nouvel ordre
  • Nous avons contacté l'équipe de sécurité PyPI pour obtenir la propriété appropriée du paquet torchtriton sur PyPI et pour supprimer la version malveillante

Confusion de dépendance : une attaque qui ne nécessite aucune action de la victime

En février 2021, un chercheur a réussi à briser les systèmes internes de plus de 35 grandes entreprises, notamment Microsoft, Apple, PayPal, Shopify, Netflix, Yelp, Tesla et Uber, dans le cadre d'une nouvelle attaque de la chaîne logistique logicielle. L'attaque comprenait le téléchargement de logiciels malveillants dans des référentiels open source, notamment PyPI, npm et RubyGems, qui ont ensuite été distribués automatiquement en aval dans les applications internes de l'entreprise.

Contrairement aux attaques de typosquatting traditionnelles qui reposent sur des tactiques d'ingénierie sociale ou qui s’appuient sur le fait que la victime ait mal orthographié un nom de paquet, cette attaque de chaîne d'approvisionnement particulière est plus sophistiquée, car elle n'a nécessité aucune action de la victime, qui a automatiquement reçu les paquets malveillants.

En effet, l'attaque a exploité une faille de conception unique des écosystèmes open source appelée confusion de dépendance.

Pour ses efforts de recherche éthique, le chercheur a gagné plus de 130 000 $ en primes de bogues.

Tout commence en 2020 lorsque le chercheur en sécurité Alex Birsan s’est montré curieux suite à la situation qu’il a vécue en travaillant avec Justin Gardner, un autre chercheur en sécurité. Gardner avait partagé avec Birsan un fichier manifeste, package.json, à partir d'un package npm utilisé en interne par PayPal. Birsan a remarqué que certains des packages de fichiers manifestes n'étaient pas présents sur le référentiel public npm, mais étaient plutôt des packages npm créés en privé par PayPal, utilisés et stockés en interne par la société.

En voyant cela, le chercheur s'est demandé : « si un paquet du même nom devait exister dans le référentiel public npm, en plus d'un référentiel NodeJS privé, lequel aurait la priorité ? »

Pour répondre à cette interrogation, Birsan a commencé à rechercher des noms de packages internes privés qu'il pouvait trouver dans des fichiers manifestes sur des référentiels GitHub ou dans des CDN d'entreprises de premier plan, mais qui n'existaient pas dans un référentiel public open source. Le chercheur a ensuite commencé à créer des projets factices en utilisant les mêmes noms sur des référentiels open source tels que npm, PyPI et RubyGems.

Chaque paquet publié par Birsan l'a été sous son compte réel et avait clairement une clause de non-responsabilité en place, indiquant que « ce paquet est destiné à des fins de recherche de sécurité et ne contient aucun code utile ».

Birsan s'est vite rendu compte que si un package de dépendances utilisé par une application existait à la fois dans un référentiel open source public et dans votre build privé, le package public aurait la priorité et serait extrait à la place - sans aucune action du développeur.

Dans certains cas, comme avec les packages PyPI, le chercheur a remarqué que le package avec la version supérieure serait priorisé quel que soit l'endroit où il se trouve.

En utilisant cette technique, Birsan a exécuté une attaque réussie de la chaîne d'approvisionnement contre Microsoft, Apple, PayPal, Shopify, Netflix, Tesla, Yelp et Uber simplement en publiant des packages publics utilisant le même nom que les packages internes de l'entreprise.

« Je crois que la confusion de dépendance est très différente du typosquatting ou du brandjacking, car elle ne nécessite pas nécessairement une quelconque intervention manuelle de la victime ». « Au contraire, des vulnérabilités ou des défauts de conception dans les outils de build ou d'installation automatisés peuvent faire en sorte que les dépendances publiques soient confondues avec des dépendances internes portant exactement le même nom », a déclaré Birsan.

Grâce à cette recherche couvrant de grandes organisations, Birsan a déclaré qu'il avait déjà sensibilisé les grandes entreprises technologiques à ce type d'attaque qui ont maintenant mis en œuvre une sorte d'atténuation dans leur infrastructure. Cependant, le chercheur pense qu'il y a plus à découvrir. Il reste la possibilité que de telles attaques refassent surface et se développent, en particulier sur les plates-formes open source sans solution facile à la confusion des dépendances.

« Plus précisément, je pense que trouver de nouveaux moyens intelligents de divulguer des noms de paquetages internes exposera des systèmes encore plus vulnérables, et rechercher d'autres langages de programmation et référentiels à cibler révélera une surface d'attaque supplémentaire pour les bogues de confusion de dépendance », a conclu le chercheur dans son billet de blog en février 2021.

Sources : PyTorch, VirusTotal, sauvegarde de h4ck.cfd, billet Alex Birsan, Twitter PyTorch

Et vous ?

Utilisez-vous Python en général ou PyTorch en particulier ? Si oui, qu'en pensez-vous ?
Qu'en pensez-vous ? Un hacker éthique qui a simplement commis une bourde ou un hacker pris la main dans le sac qui joue sur plusieurs tableaux pour en tirer un bénéfice ? Pourquoi ?
Que pensez-vous de l'attaque par confusion de dépendance ?
Quels pourraient être, selon vous, les moyens pour s'en protéger (du point de vue de l'utilisateur final et/ou du point de vue de la plate-forme) ?