Autorisation d'utilisation : Le package npm masque les menaces pour le cloud et le système

Autorisation d'utilisation : Un article de couverture de npm sur la « recherche autorisée » dissimulant des sondes de métadonnées cloud et la persistance du système

TL; DR

Entre le 15 et le 16 juin 2026, un seul éditeur npm a poussé six paquets — 26 versions au total — qui exécutent un script d'installation sur chaque npm installChaque paquet contient un fichier README déclarant qu'il s'agit d'un artefact de recherche « bénin » du programme de primes aux bogues HackerOne/GitHub qui « ne touche jamais » aux valeurs d'identification et « n'effectue aucune persistance ». Le code ne correspond pas à l'avertissement. Sur les exécuteurs CI Linux, le hook d'installation identifie l'environnement et interroge un point de terminaison de métadonnées d'instance cloud ; sous Windows, il demande une élévation de privilèges et s'exécute en tant que SYSTEMet ouvre un canal de commande vers un hôte externe. Le seul indicateur à rechercher actuellement est l'hôte C2. 173.255.233[.]239Gravité : ÉlevéeÉcosystème touché : NPMLes noms se fondent dans le bruit de dépendance de l'intégration continue (metrics-pipeline-d8k2, event-metrics-q3x7, pkg-telemetry-r4f9, et trois frères et sœurs).

L'attaque : comment elle fonctionne

Chaque paquet du cluster est construit de la même manière. package.json relie la même commande à deux cycles de vie hooks:

{   "scripts": {     "preinstall": "node run.js",     "postinstall": "node run.js"   } }

Fonctionnant sur les deux préinstallation et post-installation Cela signifie que la charge utile est exécutée, que les étapes d'installation ultérieures échouent ou non. exécuter.js Il s'agit lui-même d'un répartiteur de plateforme à dix lignes :

// Platform dispatcher — runs beaconNN.js on Windows, beacon_linux.js on Linux. // GitHub Bug Bounty authorized research. Contact: nicholas@curran.tech 'use strict'; const { execFileSync } = require('child_process'); const path = require('path'); const node = process.execPath; const script = process.platform === 'win32'   ? path.join(__dirname, 'beacon34.js')   : path.join(__dirname, 'beacon_linux.js'); try { execFileSync(node, [script], { stdio: 'inherit', timeout: 90000 }); } catch (e) {}

Le comportement varie ensuite selon le système d'exploitation. Les six paquets contiennent les mêmes deux éléments : exécuter.js et les balises de la plateforme — ce sont donc des programmes d’installation interchangeables plutôt que six outils distincts. La seule différence notable réside dans la fréquence de publication : quatre noms ont été distribués une seule fois, tandis que deux ont été republiés toutes les 30 à 60 minutes pendant plusieurs heures, ce qui permet de maintenir une version à jour disponible pour les installateurs et les résolveurs, même lorsque les versions plus anciennes sont retirées.

Sous Linux (beacon_linux.jsLe script analyse le répertoire dans lequel il s'exécute. Il énumère les noms des variables d'environnement et lit les fichiers situés sous / proc, vérifie docker.sock, et court nom d'hôte et whoamiIl envoie ensuite une requête HTTP au point de terminaison AWS container instance-metadata 169.254.170[.]2 — l'adresse locale de liaison qu'une tâche ECS interroge pour obtenir sa propre configuration et des informations d'identification de rôle éphémères (IMDS, le service de métadonnées d'instance). Les résultats sont envoyés par la méthode POST au collecteur de la campagne à l'adresse suivante : 173.255.233[.]239.

Sur Windows (beacon34.js / beacon18.jsLe paquet fait bien plus que simplement profiler son hôte. Le code signalé ajoute une clé de registre sous le ms-paramètres gestionnaire avec un DelegateExecute valeur — une faille connue du contrôle de compte d'utilisateur qui permet à un processus lancé de s'exécuter avec des privilèges élevés sans invite. Elle invoque PowerShell avec -ExécutionPolicy Bypass et Invocation-Expression, s'exécute dans le AUTORITÉ NT \ SYSTÈME Le canal de commandes Windows s'exécute sur un contexte et interroge un hôte externe pour obtenir des commandes. Tunnel de Cloudflare, diameter-coins-limitations-parents.trycloudflare[.]com:443, retombant sur 173.255.233[.]239:443, en utilisant trois points d'extrémité : /c2/sondage pour récupérer une commande, /c2/out pour renvoyer une sortie, /c2/eof fermer.

La nouveauté ici : la clause de non-responsabilité comme camouflage

L'élément novateur ne réside pas dans la charge utile elle-même — la reconnaissance par crochet d'installation et l'élévation de privilèges Windows sont toutes deux bien documentées. C'est la couverture qui prime. Chaque paquet contient un fichier README qui se présente comme un élément de divulgation responsable :

# @ncurran/sandbox-recon-880538 — authorized npm-sandbox security research

Il s'agit d'un bénin package publié sous le nom d'utilisateur `@ncurran` de l'auteur dans le cadre d'un Engagement autorisé dans le cadre du programme de primes aux bogues HackerOne / GitHub (npm est inclus).

Lors de l'installation, il effectue une inspection son propre environnement d'exécution … variable environnementale

noms de clés uniquement … vérifie si bien connu points de terminaison de métadonnées cloud Ces joignable… Il ne signale que les codes d’état, les durées de réponse et hachages — jamais aucune information d'identification, valeur de jeton ou donnée tierce. Il n'effectue aucune opération. persistance, absence de mouvement latéral et absence d'action destructive.

Trois affirmations de ce texte sont contredites par le code fourni. Le fichier README indique « aucune persistance », mais la balise Windows écrit une clé d'élévation de privilèges dans le registre. Il indique « jamais d'informations d'identification ni de valeur de jeton », mais le chemin d'accès Windows exécute des commandes arbitraires récupérées. SYSTÈME, qui n'impose aucune limite de ce type à ce qui est lu ou renvoyé. Il nomme même un paquet — @ncurran/sandbox-recon-880538 — Ce n'est pas le fichier README fourni, ce qui indique qu'il s'agit d'un modèle réutilisé plutôt que d'une description du logiciel. Une clause de non-responsabilité relative au consentement dans un paquet qu'une victime n'a jamais accepté d'installer ne vaut pas consentement. Dans ce cas, le logiciel est considéré comme malveillant, indépendamment de sa formulation. Cette clause de non-responsabilité a également une cible plus discrète : une étape de triage automatisée, qui analyse le texte du paquet à la recherche de signaux rassurants — « bénin », « autorisé », un programme nommé, une adresse e-mail de contact — peut être influencée par un texte que le contenu du paquet contredit. La leçon est valable pour les examinateurs humains et les machines : il faut se baser sur le comportement lors de l'installation, et non sur la description du fichier README.

Forum

Tous les paquets sont apparus dans un intervalle de 24 heures. Les quatre paquets à version unique ont été déployés en premier, suivis de deux paquets republiés toutes les 30 à 60 minutes.

Date (UTC)Espaces
2026-06-15 18:32Premier colis publié — npm:pkg-telemetry-r4f9@1.0.0
2026-06-15 19:50npm:runtime-metrics-w7k2@1.0.0 publié
2026-06-15 20:14npm:build-tracker-n5p1@1.0.0 publié
2026-06-15 20:35npm:npm-sandbox-ping-r9t2@1.0.0 publié
2026-06-15 21:09–22:42npm:event-metrics-q3x7 publié 1.0.0 → 1.0.8 (9 versions)
2026-06-15 23:40 → 2026-06-16 04:40npm:metrics-pipeline-d8k2 publié 1.0.0 → 1.0.10 (11 versions)
2026-06-16Un groupe de fichiers malveillants a été identifié et classé comme tel ; plusieurs archives tar renvoient déjà une erreur 404 au niveau du registre (opération en cours).

La campagne est récente et le démantèlement est toujours en cours : au moment de l’analyse, certaines versions ont été prises en compte par le registre, d’autres non. Considérez les 26 versions comme compromises.

Indicateurs de compromis

Forfaits

ÉcosystèmeForfaitversionsStatut
NPMmetrics-pipeline-d8k21.0.0 – 1.0.10malveillant
NPMevent-metrics-q3x71.0.0 – 1.0.8malveillant
NPMruntime-metrics-w7k21.0.0malveillant
NPMbuild-tracker-n5p11.0.0malveillant
NPMnpm-sandbox-ping-r9t21.0.0malveillant
NPMpkg-telemetry-r4f91.0.0malveillant

Réseau

TypeIndicateurRemarques
IP173.255.233[.]239Collecteur C2 ; POST de reconnaissance Linux et repli Windows :443
Domainediameter-coins-limitations-parents.trycloudflare[.]comCanal de commande Windows via un tunnel Cloudflare, :443
chemin URI/c2/poll, /c2/out, /c2/eofInterroger/sortir/fermer la commande Windows
IP169.254.170[.]2Point de terminaison des métadonnées d'instance AWS ECS sondé depuis le hook d'installation

Comportementale

SignalDescription
Installer hookspreinstall et postinstall Les deux courent node run.js
Expédition de la plateformerun.js fonctionne beacon_linux.js sous Linux, beacon34.js / beacon18.js sous Windows
Reconnaissance LinuxÉnumère les noms de clés des variables d'environnement, lit /proc, chèques docker.sock, s'exécute hostname / whoami, sondes IMDS
Élévation des fenêtresms-settings DelegateExecute Contournement du contrôle de compte d'utilisateur (UAC) du registre ; PowerShell -ExecutionPolicy Bypass + Invoke-Expression; s'exécute comme SYSTEM
CacherLe fichier README affirme qu'il s'agit d'une recherche « bénigne » et « autorisée », sans « persistance » ; il fait référence à un nom de paquet qui n'est pas inclus dans le colis.

Attribution et comportement observé

Nous décrivons l'éditeur uniquement par ses signaux et n'affirmons pas l'identité de la personne derrière le compte.

  • Catalogue des signaux. Les six paquets ont tous été publiés par le même compte npm. npmresearch8847, avec l'e-mail indiqué npmresearch8847@web-library.net (courriel et SCM Vérification absente (nous n'avons pas vérifié la propriété). Les fichiers README sont publiés sous une licence @ncurran portée et donner un contact de nicholas@curran.tech et exécuter.js pointe vers le dépôt github.com/ncurran/npm-sandbox-research`. Les six packages partagent un même exécuter.js répartiteur, un commun beacon_linux.js phase de reconnaissance et hôte collecteur unique 173.255.233[.]239`. Le schéma de nommage est cohérent : une racine générique à consonance CI (métrique, télémétrie, suivi de construction, sandbox-ping) plus un court suffixe aléatoire.
  • Confiance. Les six paquets semblent constituer une seule et même campagne, compte tenu du partage du répartiteur, de la plateforme de reconnaissance et du serveur de commande et de contrôle. La mention « recherche autorisée » apparaît systématiquement dans les six fichiers README. Nous n'avons pas pu confirmer qu'un programme de primes aux bogues ait autorisé cette activité, et les affirmations de l'avertissement ne correspondent pas au code distribué.
  • Capacité observée. L'exercice de charge utilecisquatre classes de capacités : exécution de code install-hook sur les deux préinstaller et post-installation; reconnaissance de l'hôte et de l'environnement CI avec sortie vers un collecteur externe ; sondage de l'accessibilité des métadonnées des instances cloud depuis le contexte d'installation ; et, sous Windows, élévation de privilèges locale, exécution en tant que SYSTÈMEet une boucle de commandes de type « récupérer et exécuter » via un canal externe. La boucle de commandes Windows est une fonctionnalité de contrôle à distance : elle interroge le système pour obtenir des instructions et renvoie leur résultat.

Impact, tendances et actions que doivent entreprendre les défenseurs

Impact

L'exposition est maximale pour les environnements de compilation automatisés. Une installation npm dans un environnement d'intégration continue exécute le cycle de vie. hooks avec l'identité du runner ; sur un runner cloud, cette identité inclut souvent un point de terminaison de métadonnées accessible et des informations d'identification de rôle. L'adresse que les sondes de balise Linux, 169.254.170[.]2Il s'agit du point de terminaison des métadonnées de tâche AWS ECS : une tâche pouvant l'atteindre peut généralement récupérer les informations d'identification temporaires de son rôle auprès du même service local. Une vérification d'accessibilité effectuée dans un script d'installation précède la récupération de ces informations d'identification. Par conséquent, tout exécuteur ayant lancé le hook et pouvant atteindre ce point de terminaison est considéré comme ayant vu son rôle exposé. Sur un hôte de développement ou de compilation Windows, la charge utile demande une élévation de privilèges et ouvre un canal de commande, ce qui étend l'exposition d'un simple profil et d'une sortie unique à un contrôle à distance interactif.

Nous n'avons pas pu obtenir de chiffres fiables concernant le nombre de téléchargements des versions malveillantes avant leur suppression, et nous ne pouvons donc pas estimer le nombre de victimes. La republication rapide de deux des paquets (onze et neuf versions en quelques heures) a permis de maintenir des versions récentes accessibles aux installateurs et aux résolveurs pendant la suppression des versions plus anciennes.

Modèles émergents

Ce cas illustre l'utilisation abusive d'étiquettes comme prétexte. Les termes « recherche autorisée », « programme de primes aux bogues » et « tests en environnement isolé » sont de plus en plus souvent associés à des paquets dont les scripts d'installation vont bien au-delà du simple profilage d'un système hôte. Cette pratique exploite la réticence des examinateurs à agir contre une action présentée comme autorisée. Elle s'accompagne d'une autre tactique courante : des noms de paquets conçus pour ressembler à des outils d'intégration continue internes, afin de passer inaperçus lors d'un rapide coup d'œil à l'arbre des dépendances. C'est cette combinaison qui rend ce phénomène digne d'intérêt : un nom évoquant l'infrastructure système, enrobé d'un texte le présentant comme un test autorisé, masquant un script d'installation qui élève les privilèges sur un système d'exploitation et vérifie les identifiants cloud sur un autre. Ni la mention légale ni le nom anodin ne modifient le comportement du code lors de l'installation, et un processus de triage qui les prendrait en compte comme preuves atténuantes aboutirait à une conclusion erronée.

Ce que les défenseurs devraient faire

  • Recherchez les fichiers de verrouillage et les journaux d'installation pour les six noms de paquets ; considérez toute correspondance comme un incident, et non comme un avertissement.
  • Bloquer et alerter sur le trafic sortant vers 173.255.233[.]239 et à *.trycloudflare[.]com hôtes issus de la construction de l'infrastructure.
  • Recherchez les requêtes HTTP effectuées lors de l'installation vers les adresses de métadonnées d'instance (169.254.170.2, 169.254.169.254) provenant des gestionnaires de paquets dans l'intégration continue.
  • Renouvelez tous les identifiants et jetons de rôle cloud accessibles depuis un exécuteur ayant installé une version affectée.
  • Audit préinstaller/post-installation scripts dans votre ensemble de dépendances; un hook de cycle de vie qui exécute un deuxième fichier de script mérite d'être lu.
  • Sur les terminaux Windows, recherchez les nouveaux DelegateExecute valeurs écrites sous le ms-paramètres clé shell-handler — la primitive d'élévation utilisée par cette charge utile et un signal fiable indépendant du nom du paquet.
  • Épingler et examiner les fichiers de verrouillage, et désactiver les scripts d'installation (npm install --ignore-scripts) dans l'intégration continue où votre build ne les requiert pas.
  • Considérez les mentions « recherche autorisée » ou « bénigne » figurant dans un script d'installation comme du texte non fiable, et non comme une raison d'autoriser le script.

Un colis qui annonce de bonnes intentions en prose et demande SYSTÈME Le code doit être jugé sur le code lui-même.

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