TL; DR
Mellem 2026-06-15 og 2026-06-16 pressede en enkelt npm-udgiver på seks pakker — i alt 26 versioner — der kører et installationstidsscript på alle npm installHver pakke sender en README-fil, der erklærer den for et "godartet" HackerOne / GitHub Bug Bounty-forskningsartefakt, der "aldrig" rører legitimationsoplysninger og "ikke udfører nogen persistens". Koden stemmer ikke overens med ansvarsfraskrivelsen. På Linux CI-brugere registrerer installationshooken miljøet med fingeraftryk og undersøger et cloud-instans-metadata-slutpunkt; på Windows anmoder den om elevation og kører som SYSTEM, og åbner en kommandokanal til en ekstern vært. Den eneste indikator, man skal søge efter nu, er C2-værten 173.255.233[.]239Sværhedsgrad: højBerørt økosystem: NPMNavne blandes ind i afhængighedsstøj fra kontinuerlig integration (metrics-pipeline-d8k2, event-metrics-q3x7, pkg-telemetry-r4f9og tre søskende).
Angrebet: Sådan fungerer det
Hver pakke i klyngen er bygget på samme måde. pakke.json forbinder den samme kommando til to livscyklusser hooks:
{ "scripts": { "preinstall": "node run.js", "postinstall": "node run.js" } } Kører på begge præinstallation og efterinstallation betyder, at nyttelasten aktiveres, uanset om senere installationstrin mislykkes eller ej. run.js i sig selv er en platformdispatcher med ti linjer:
// 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) {} Adfærden deler sig derefter efter operativsystem. Alle seks pakker indeholder de samme to dele — run.js og platform-beacons – så de er udskiftelige droppere snarere end seks forskellige værktøjer. Den eneste meningsfulde forskel mellem dem er publiceringskadence: fire navne blev sendt én gang, mens to blev genudgivet hvert 30.-60. minut i timevis, hvilket holder en frisk udgivet version foran installatører og resolvere, selvom ældre versioner trækkes tilbage.
På Linux (beacon_linux.js) scriptet profilerer, hvor det kører. Det opregner navnene på miljøvariabler, læser filer under / proc, tjekker for docker.sok, og løber hostname og whoamiDen udsteder derefter en HTTP-anmodning til AWS-containerens instans-metadata-slutpunkt. 169.254.170[.]2 — den link-lokale adresse, som en ECS-opgave forespørger for at få sin egen konfiguration og kortlivede rollelegitimationsoplysninger (IMDS, instansmetadatatjenesten). Resultaterne sendes til kampagnens indsamler på 173.255.233[.]239.
På Windows (beacon34.js / beacon18.js) pakken gør betydeligt mere end at profilere sin vært. Den markerede kode tilføjer en registreringsnøgle under ms-indstillinger håndterer med en DelegateExecute værdi — en kendt omgåelse af brugerkontokontrol, der tillader en startet proces at køre forhøjet uden en prompt. Den kalder PowerShell med -Omgåelse af udførelsespolitik og Invoke-Expression, udføres i NT MYNDIGHED\SYSTEM kontekst og poller en ekstern vært for kommandoer. Windows-kommandokanalen kører over en Cloudflare-tunnel, diameter-mønter-begrænsninger-forældre.trycloudflare[.]com:443, falder tilbage til 173.255.233[.]239:443, ved hjælp af tre slutpunkter: /c2/afstemning at hente en kommando, /c2/ud at returnere output, /c2/eof at lukke.
Hvad er nyt her: ansvarsfraskrivelsen som camouflage
Det nye element er ikke nyttelasten — både install-hook recognition og Windows elevation er veldokumenterede. Det er dækhistorien. Hver pakke indeholder en README, der lyder som en responsible-disclosure artefakt:
# @ncurran/sandbox-recon-880538 — authorized npm-sandbox security research Dette er et godartet pakke udgivet under forfatterens eget `@ncurran`-scope som en del af en Autoriseret HackerOne / GitHub Bug Bounty-engagement (npm er omfattet).
Ved installation inspicerer den sit eget udførelsesmiljø … miljøvariabel
kun nøglenavne … tjekker om velkendte cloud-metadata-slutpunkter er tilgængelig … Den rapporterer kun statuskoder, svarlængder og hashkoder — aldrig nogen legitimationsoplysninger, tokenværdier eller tredjepartsdata. Den udfører ingen vedholdenhed, ingen lateral bevægelse og ingen destruktiv handling.
Tre påstande i den tekst modsiges af den leverede kode. README-filen siger "ingen persistens", men Windows-beaconen skriver en registreringsbaseret elevationsnøgle. Den siger "aldrig nogen legitimationsoplysninger eller tokenværdi", men Windows-stien kører vilkårligt hentede kommandoer som SYSTEM, som ikke sætter nogen sådan grænse for, hvad der læses eller returneres. Den navngiver endda en pakke — @ncurran/sandbox-recon-880538 — det er ikke den, den sendes i, hvilket indikerer, at README-filen er en genbrugt skabelon snarere end en beskrivelse af den aktuelle artefakt. En samtykkeerklæring i en pakke, som et offer aldrig har indvilliget i at installere, giver intet samtykke. Klassificeringen her er ondsindet uanset ordlyden. Ansvarsfraskrivelsen har også et mere stille mål: et automatiseret triage-trin, der læser pakketekst for beroligende signaler — "godartet", "autoriseret", et navngivet program, en kontakt-e-mail — kan skubbes mod en sikker dom ved hjælp af prosa, som nyttelasten modsiger. Lærdommen gælder for både menneskelige og maskinelle korrekturlæsere: vej installationstidspunktets adfærd, ikke README-filens selvbeskrivelse.
Tidslinje
Alle pakker dukkede op inden for et 24-timers vindue. De fire enkeltversionsnavne landede først, efterfulgt af to pakker, der blev genudgivet hvert 30.-60. minut.
| Dato (UTC) | Begivenhed |
|---|---|
| 2026-06-15 18:32 | Første pakke udgivet — npm:pkg-telemetry-r4f9@1.0.0 |
| 2026-06-15 19:50 | npm:runtime-metrics-w7k2@1.0.0 offentliggjort |
| 2026-06-15 20:14 | npm:build-tracker-n5p1@1.0.0 offentliggjort |
| 2026-06-15 20:35 | npm:npm-sandbox-ping-r9t2@1.0.0 offentliggjort |
| 2026-06-15 21:09–22:42 | npm:event-metrics-q3x7 offentliggjort 1.0.0 → 1.0.8 (9 versioner) |
| 2026-06-15 23:40 → 2026-06-16 04:40 | npm:metrics-pipeline-d8k2 offentliggjort 1.0.0 → 1.0.10 (11 versioner) |
| 2026-06-16 | Klynge identificeret og klassificeret som skadelig; flere tarballs returnerer allerede 404 i registreringsdatabasen (igangværende) |
Kampagnen er ny, og fjernelsen er stadig under behandling: på analysetidspunktet blev nogle versioner løst i registreringsdatabasen, og andre ikke. Betragt alle 26 versioner som kompromitterede.
Indikatorer for kompromis
Pakker
| Ecosystem | Pakke | versioner | Status |
|---|---|---|---|
| NPM | metrics-pipeline-d8k2 | 1.0.0 – 1.0.10 | ondsindet |
| NPM | event-metrics-q3x7 | 1.0.0 – 1.0.8 | ondsindet |
| NPM | runtime-metrics-w7k2 | 1.0.0 | ondsindet |
| NPM | build-tracker-n5p1 | 1.0.0 | ondsindet |
| NPM | npm-sandbox-ping-r9t2 | 1.0.0 | ondsindet |
| NPM | pkg-telemetry-r4f9 | 1.0.0 | ondsindet |
Netværk
| Type | Indikator | Noter |
|---|---|---|
| IP | 173.255.233[.]239 | C2-indsamler; Linux-genopretning POST og Windows-fallback: 443 |
| Domæne | diameter-coins-limitations-parents.trycloudflare[.]com | Windows-kommandokanal over en Cloudflare-tunnel, :443 |
| URI-sti | /c2/poll, /c2/out, /c2/eof | Windows-kommando poll / output / luk |
| IP | 169.254.170[.]2 | AWS ECS-instans-metadata-slutpunkt undersøgt fra installationskrogen |
Behavioral
| Signal | Beskrivelse |
|---|---|
| Installer hooks | preinstall og postinstall begge løber node run.js |
| Perronforsendelse | run.js løber beacon_linux.js på Linux, beacon34.js / beacon18.js på Windows |
| Linux rekognoscering | Opregner env-var nøglenavne, læser /proc, checks docker.sock, kører hostname / whoami, sonder IMDS |
| Vinduernes højde | ms-settings DelegateExecute omgåelse af brugerkontrol i registreringsdatabasen; PowerShell -ExecutionPolicy Bypass + Invoke-Expression; kører som SYSTEM |
| Forklædning | README hævder "godartet", "autoriseret" forskning og "ingen persistens"; refererer til et pakkenavn, den ikke sendes i |
Attribuering og observeret adfærd
Vi beskriver udelukkende udgiveren ud fra dens signaler og hævder ikke identiteten af nogen person bag kontoen.
- Signalkatalog. Alle seks pakker blev udgivet af den samme npm-konto, npmresearch8847, med den angivne e-mail npmresearch8847@web-bibliotek.net (e-mail og SCM verifikation begge fraværende; vi har ikke verificeret ejerskab). README-filerne udgives under en @ncurran omfang og give en kontaktperson nicholas@curran.techog run.js punkter på depotet github.com/ncurran/npm-sandbox-research`. De seks pakker deler en identisk run.js koordinator, en almindelig beacon_linux.js rekognosceringsfase og den enkelte samlervært 173.255.233[.]239`. Navngivningsskemaet er konsistent: en generisk CI-klingende stamme (målinger, telemetri, byggesporing, sandkasse-ping) plus et kort tilfældigt suffiks.
- Tillid. De seks pakker ser ud til at være én kampagne baseret på den delte dispatcher, rekognosceringsfase og C2-vært. Indramningen af "autoriseret forskning" synes at være ensartet på tværs af alle seks README-filer. Vi har ikke været i stand til at bekræfte, at noget bug-bounty-program har godkendt denne aktivitet, og ansvarsfraskrivelsens påstande stemmer ikke overens med den leverede kode.
- Observeret kapacitet. Nyttelasten øvelsecisfire funktionsklasser: install-hook-kodeudførelse på begge forudinstallation og efterinstallation; rekognoscering af vært og CI-miljø med udgang til en ekstern indsamler; tilgængelighedsundersøgelse af cloud-instansmetadata fra installationskonteksten; og, på Windows, eskalering af lokale rettigheder, udførelse som SYSTEM, og en hent-og-kør-kommandoløkke over en ekstern kanal. Windows-kommandoløkken er en fjernbetjeningsfunktion: den forespørger om instruktioner og returnerer deres output.
Indvirkning, tendenser og hvad forsvarere bør gøre
Impact
Eksponeringen er højest for automatiserede byggemiljøer. En npm-installation i CI kører livscyklussen hooks med den identitet, som runneren har; på en cloud-runner inkluderer denne identitet ofte et tilgængeligt metadata-slutpunkt og en rollelegitimationsoplysninger. Adressen, som Linux beacon-sonderne foretager, 169.254.170[.]2, er AWS ECS-opgavemetadata-slutpunktet: en opgave, der kan nå det, kan normalt også hente sin opgaverolles midlertidige legitimationsoplysninger fra den samme link-lokale tjeneste. En tilgængelighedskontrol indefra et installationsscript er det trin, der går forud for at trække disse legitimationsoplysninger, så enhver kører, der kørte hook'en og kunne nå dette slutpunkt, bør behandles som havende sin opgaverolle eksponeret. På en Windows-udvikler eller build-vært anmoder nyttelasten om elevation og åbner en kommandokanal, som udvider eksponeringen fra en enkelt profil-og-udgang til interaktiv fjernbetjening.
Vi kunne ikke få pålidelige downloadtællinger for de skadelige versioner før fjernelse, så vi kan ikke estimere antallet af ofre. Den hurtige genudgivelse af to af pakkerne – elleve og ni versioner på få timer – holdt nye artefakter foran installatører og resolvere, mens ældre versioner blev fjernet.
Nye mønstre
Denne klynge er et eksempel på en betegnelse, der bruges som dække. "Autoriseret forskning", "bug bounty" og "sandbox-testning" bliver i stigende grad knyttet til pakker, hvis installationsscripts gør mere end at profilere en vært. Indramningen handler om en anmelders tøven med at handle mod noget, der annoncerer sig selv som sanktioneret. Det parres med en anden velkendt taktik: pakkenavne, der er konstrueret til at ligne interne CI-værktøjer, så de glider forbi et hurtigt blik på et afhængighedstræ. Kombinationen er det, der gør mønsteret værd at holde øje med - et navn, der læses som infrastruktur-VVS, pakket ind i prosa, der læses som en sanktioneret test, og som står foran en installationshook, der eskalerer på det ene operativsystem og undersøger cloud-legitimationsoplysninger på det andet. Hverken ansvarsfraskrivelsen eller det intetsigende navn ændrer, hvad koden gør ved installation, og en triageproces, der vejer en af dem som formildende beviser, vil nå frem til den forkerte dom.
Hvad forsvarere bør gøre
- Søg i låsefiler og installer logfiler for de seks pakkenavne; behandl ethvert match som en hændelse, ikke en advarsel.
- Bloker og advarsel om udgående trafik til 173.255.233[.]239 og at *.trycloudflare[.]com værter fra at bygge infrastruktur.
- Søger efter HTTP-anmodninger til instansmetadataadresser under installation (169.254.170.2, 169.254.169.254) der stammer fra pakkeadministratorer i CI.
- Roter alle legitimationsoplysninger og tokens til cloudroller, der kunne tilgås fra en runner, der installerede en berørt version.
- Revision forudinstallation/efterinstallation scripts i dine afhængighedssæten livscyklus-hook, der kører en anden scriptfil, fortjener at blive læst.
- Søg efter nye på Windows-slutpunkter DelegateExecute værdier skrevet under ms-indstillinger shell-handler-nøgle — den elevationsprimitiv, som denne nyttelast bruger, og et pålideligt signal uafhængigt af pakkenavnet.
- Fastgør og gennemgå låsefiler, og deaktiver installationsscripts (npm install –ignore-scripts) i CI, hvor din build ikke kræver dem.
- Behandl ansvarsfraskrivelser om "autoriseret forskning" eller "godartede" i et installationsscript som upålidelig tekst, ikke som en grund til at tillade scriptet.
En pakke, der bekendtgør gode intentioner i prosa og anmodninger SYSTEM i koden bør bedømmes ud fra koden.





