Ces paquets n’étaient pas de simples coquilles vides. Kaspersky précise qu’ils implémentaient bien les fonctionnalités annoncées sur leurs pages PyPI, tout en ayant pour objectif réel de livrer des fichiers malveillants en arrière-plan. The Hacker News rapporte la même conclusion de Kaspersky : les paquets semblaient fonctionnels, mais servaient à installer furtivement ZiChatBot sur Windows et Linux.
uuid32-utilscolorinaltermncolorSur l’attribution, la nuance est importante. Le billet Securelist explique que les échantillons ont été soumis au Kaspersky Threat Attribution Engine et que les paquets pourraient être liés à un malware évoqué dans un rapport de renseignement sur OceanLotus. L’index de recherche de Kaspersky est plus affirmatif, indiquant que l’entreprise attribue l’activité PyPI liée à ZiChatBot à OceanLotus APT.
Un résumé public parle, lui, d’une attribution avec confiance modérée.
Le scénario public décrit une chaîne d’infection multiplateforme. L’index de recherche de Kaspersky indique que les paquets wheel malveillants sur PyPI visaient Windows et Linux, et contenaient un dropper chargé de livrer le malware baptisé ZiChatBot.
Un résumé public décrit ensuite l’extraction, depuis le paquet wheel, d’un dropper sous forme de DLL ou de fichier .SO, puis la mise en place d’une persistance via le Registre Windows ou crontab sous Linux, avant le déploiement de ZiChatBot. C’est ce qui rend la campagne pertinente au-delà des seuls serveurs applicatifs : postes de développeurs, environnements virtuels, runners CI/CD et images de conteneurs peuvent tous entrer dans le périmètre si les paquets concernés ont été installés.
L’affaire rappelle aussi qu’un paquet qui « marche » n’est pas forcément un paquet sûr. Dans cette campagne, les wheels malveillants auraient fourni les fonctionnalités promises tout en livrant des fichiers cachés à finalité malveillante.
La singularité de ZiChatBot tient à son usage d’une plateforme de collaboration légitime. Selon les rapports consacrés aux découvertes de Kaspersky, ZiChatBot ne communiquait pas avec un serveur C2 dédié : il utilisait une série d’API REST de Zulip, application publique de messagerie d’équipe, comme infrastructure de commande et contrôle.
Les API documentées de Zulip prennent en charge des opérations utiles à une logique de C2 par messagerie : envoyer et récupérer des messages, téléverser des fichiers, modifier ou supprimer des messages, construire des filtres de messages — les « narrows » dans la terminologie Zulip — et travailler avec des sujets de canaux. La documentation des bots Zulip décrit aussi des bots capables d’intercepter, consulter et traiter des messages envoyés par des utilisateurs, puis de publier de nouveaux messages en réponse.
En pratique, cela signifie qu’à haut niveau, des instructions d’opérateur peuvent être représentées comme des messages ou des messages rattachés à un sujet, tandis que le malware peut récupérer les messages pertinents et renvoyer des résultats via le même service. Les sources publiques fournies ici ne détaillent pas l’espace Zulip exact, les identifiants de bot, la séquence d’API ni le jeu de commandes utilisé par ZiChatBot. La formulation la plus prudente est donc que ZiChatBot a abusé de fonctionnalités REST légitimes de Zulip pour son C2, plutôt que de s’appuyer sur une infrastructure C2 directement opérée par les attaquants.
Le rôle de Zulip dans cette affaire ne signifie pas que Zulip aurait été piraté. Les informations citées décrivent l’abus de fonctionnalités normales d’API REST et de messagerie de type bot, pas une compromission du service de chat.
De la même façon, cela ne signifie pas que l’infrastructure de PyPI aurait été compromise. Kaspersky décrit des paquets wheel malveillants téléversés sur PyPI, puis retirés du dépôt.
Pour les défenseurs, la leçon est plus opérationnelle : du trafic vers un service collaboratif légitime peut tout de même être suspect lorsqu’il provient d’une machine, d’un processus, d’un job CI ou d’un compte de service qui n’a aucune raison métier de contacter ce service. Une détection fondée uniquement sur des domaines contrôlés par les attaquants risque de passer à côté de ce modèle ; l’analyse doit donc tenir compte du contexte du processus et de l’usage attendu, pas seulement de la réputation de la destination.
La première étape consiste à faire l’inventaire des dépendances. Recherchez uuid32-utils, colorinal et termncolor sur les postes de développement, runners de build, environnements virtuels, fichiers de verrouillage de dépendances et images de conteneurs.
Il faut ensuite examiner les chronologies d’installation à partir de juillet 2025, période à laquelle Kaspersky situe le début des téléversements malveillants de paquets wheel. Si l’un des paquets nommés apparaît dans les journaux ou les artefacts, mieux vaut préserver l’environnement pour investigation plutôt que supprimer simplement le paquet et considérer l’incident clos.
Sur Windows, recherchez des mécanismes de persistance inattendus dans le Registre ; sur Linux, inspectez les entrées crontab suspectes. Cela correspond à la chaîne d’infection décrite publiquement pour cette campagne.
Côté réseau et EDR, vérifiez les appels aux API Zulip depuis des interpréteurs Python, des processus d’installation de paquets, des workers CI, des serveurs ou des comptes de service qui n’utilisent normalement pas Zulip. La question n’est pas de savoir si Zulip est légitime en général, mais si cet hôte précis et ce processus précis ont une raison légitime d’appeler ces API.
Enfin, ne considérez pas le comportement fonctionnel d’un paquet comme une preuve de confiance. Dans cette campagne, les paquets auraient rempli leur promesse apparente tout en agissant comme droppers de fichiers malveillants.
La campagne PyPI liée à OceanLotus repose sur des paquets wheel malveillants mis en ligne à partir de juillet 2025, avec des noms publiquement cités comme uuid32-utils, colorinal et termncolor. Ces paquets livraient ZiChatBot sur Windows et Linux, et le choix opérationnel le plus distinctif de ZiChatBot était d’utiliser les API REST de Zulip pour la commande et le contrôle, plutôt qu’un serveur C2 dédié aux attaquants.