Après le retrait des premiers comptes, une seconde vague de dépôts malveillants est apparue sur Hugging Face, selon l’analyse de Pluto Security publiée le 29 octobre 2026. La campagne utilisait du code Python lancé au chargement de certains modèles lorsque l’option trust_remote_code=True était activée. Le code s’exécutait avec les privilèges du processus qui chargeait le modèle.
Le 29 octobre, BleepingComputer a rapporté avoir examiné une copie de qwen2-tiny publiée le 25 octobre sous le compte htt0118 et y avoir retrouvé le mineur et une porte dérobée. Pluto Security a recensé 31 dépôts malveillants principaux répartis sur sept comptes et deux vagues. Ces dépôts hébergés sur Hugging Face sont au cœur des constats de l’analyse.
Ce que comptaient les téléchargements
Le relevé de Pluto Security arrêté au 28 octobre 2026 distinguait les dépôts principaux des modèles associés :
| Groupe | Dépôts | Téléchargements | Période ou base |
| Première vague | 12 | 728 | Avant le retrait des comptes |
| Seconde vague | 19 | 29 090 | Au 28 octobre 2026 |
| Modèles associés | 13 | 2 558 | Au 28 octobre 2026 |
Les deux vagues regroupaient 31 dépôts principaux. Les 13 modèles associés portaient le total à 44 dépôts, pour 32 376 téléchargements cumulés au 28 octobre. Ce chiffre compte des téléchargements, pas des machines infectées ni des utilisateurs uniques.
Comment le code s’exécutait au chargement
Avec trust_remote_code=True, le chargeur pouvait importer le module Python indiqué par la configuration du dépôt. Les instructions placées au niveau du module s’exécutaient pendant cet import, avant que la classe du modèle soit renvoyée. La menace venait donc du code Python chargé, pas nécessairement des poids du modèle eux-mêmes. Pluto Security détaille le mécanisme et les variantes de la campagne.
Dans le dépôt MENXIANGYU/qwen2-tiny, Pluto Security a relevé un fichier model.safetensors de 42 octets, sans tenseurs ; le comportement malveillant se trouvait dans le module Python. Le code a installé un mineur, lancé en mémoire et masqué sous le nom de processus [kworker/u20:1] dans la version analysée.
Les traces décrites par Pluto Security
Pour enquêter sur un hôte ayant chargé l’un des modèles concernés, les indices signalés par Pluto Security comprennent :
- le répertoire
/tmp/.cch/et une activité inattendue desvc.py; - des modifications des scripts de démarrage du shell ;
- un processus
[kworker/u20:1]avec des arguments liés au minage ; - des enregistrements encodés de modèles
qwen2-tiny-ouezv-dans Xinference ; - des connexions à l’infrastructure réseau associée à la campagne.
Dans la version décrite, un mécanisme de surveillance relançait le mineur manquant toutes les 120 secondes. Pluto a également associé des shells inversés à certains dépôts précis : les variantes qwen2-tiny-5, qwen2-tiny-6 et qwen2-tiny-9 se connectaient à 212.32.253.3 sur le port 443 ou 9443. Un autre script, dans MENXIANGYU/qa-whl-1021, visait l’hôte depuis un conteneur privilégié. Ces comportements correspondent aux variantes citées, pas à chaque dépôt de la campagne.
Un indicateur absent ne suffit pas à écarter une compromission. Pluto Security conseillait d’examiner les hôtes même si le chargement du modèle avait échoué ou si l’activité du GPU semblait normale.
Que faire après le chargement d’un modèle suspect ?
Pluto Security recommandait de commencer par isoler l’hôte et de préserver les éléments utiles à l’enquête : processus, connexions réseau, journaux, cache et fichiers de démarrage. Il fallait aussi examiner les autres systèmes ayant chargé les mêmes dépôts.
La remise en état ne se limite pas à arrêter le mineur : il faut retirer les mécanismes de persistance et les portes dérobées, puis renouveler depuis une machine saine les identifiants auxquels le processus pouvait accéder. Si l’intégrité de l’hôte ne peut pas être établie, Pluto Security recommande de le reconstruire à partir d’une image de confiance.