TL; DR
W okresie od 15.06.2026 do 16.06.2026 jeden wydawca npm przesłał sześć pakietów — łącznie 26 wersji — które uruchamiają skrypt w czasie instalacji przy każdym npm installKażdy pakiet zawiera plik README, w którym deklaruje się, że jest to „nieszkodliwy” artefakt badawczy HackerOne / GitHub Bug Bounty, który „nigdy” nie zmienia wartości poświadczeń i „nie wykonuje żadnego utrwalania”. Kod nie zgadza się z klauzulą wyłączającą odpowiedzialność. W przypadku programów uruchamiających CI w systemie Linux hak instalacyjny odciska odcisk palca środowiska i bada punkt końcowy metadanych instancji chmury; w systemie Windows żąda podniesienia uprawnień, działa jako SYSTEMi otwiera kanał poleceń do hosta zewnętrznego. Jedynym wskaźnikiem, którego należy teraz szukać, jest host C2. 173.255.233[.]239. Powaga: wysoka. Dotknięty ekosystem: Npm. Nazwy wtapiają się w szum zależności ciągłej integracji (metrics-pipeline-d8k2, event-metrics-q3x7, pkg-telemetry-r4f9i troje rodzeństwa).
Atak: Jak to działa
Każdy pakiet w klastrze jest zbudowany w ten sam sposób. pakiet.json łączy to samo polecenie w dwa cykle życia hooks:
{
"scripts": {
"preinstall": "node run.js",
"postinstall": "node run.js"
}
}Działa na obu przed instalacją i po instalacji oznacza, że ładunek zostanie uruchomiony niezależnie od tego, czy późniejsze kroki instalacji zakończą się niepowodzeniem. uruchom.js sam w sobie jest dziesięcioliniowym dyspozytorem platformowym:
// 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) {}Następnie zachowanie jest rozdzielane według systemu operacyjnego. Wszystkie sześć pakietów zawiera te same dwie części — uruchom.js i sygnalizatory platformy — są więc wymiennymi dropperami, a nie sześcioma odrębnymi narzędziami. Jedyną znaczącą różnicą między nimi jest częstotliwość publikacji: cztery nazwy zostały wydane jednorazowo, a dwie były ponownie publikowane co 30–60 minut przez wiele godzin, co pozwala na utrzymanie świeżo opublikowanej wersji przed instalatorami i resolverami, nawet gdy starsze są usuwane.
W systemie Linux (beacon_linux.js) profile skryptu, w których jest uruchomiony. Wylicza nazwy zmiennych środowiskowych, odczytuje pliki w / proc, sprawdza docker.socki biegnie hosta oraz whoamiNastępnie wysyła żądanie HTTP do punktu końcowego metadanych instancji kontenera AWS 169.254.170[.]2 — adres lokalny łącza, który zadanie ECS odpytuje, aby uzyskać własną konfigurację i krótkotrwałe dane uwierzytelniające roli (IMDS, usługa metadanych instancji). Wyniki są wysyłane do kolektora kampanii na adres 173.255.233[.]239.
W systemie Windows (beacon34.js / beacon18.js) pakiet robi znacznie więcej niż tylko profiluje swojego hosta. Oznaczony kod dodaje klucz rejestru pod ms-ustawienia opiekun z DelegateExecute wartość — znane obejście kontroli konta użytkownika, które pozwala uruchomionemu procesowi działać z uprawnieniami podwyższonymi bez monitu. Wywołuje program PowerShell za pomocą -Ominięcie zasad wykonania oraz Wywołanie-wyrażenie, wykonuje się w ZARZĄDZANIE NT\SYSTEM kontekst i odpytuje zewnętrznego hosta o polecenia. Kanał poleceń systemu Windows działa przez Tunel Cloudflare, ograniczenia-średnicy-monet-rodzice.trycloudflare[.]com:443, wracając do 173.255.233[.]239:443, używając trzech punktów końcowych: /c2/ankieta pobrać polecenie, /c2/wyjście aby zwrócić dane wyjściowe, /c2/eof zamknąć.
Co nowego: zastrzeżenie jako kamuflaż
Nowością nie jest sam ładunek — rozpoznanie hooka instalacyjnego i podniesienie uprawnień systemu Windows są dobrze udokumentowane. To historia z okładki. Każdy pakiet zawiera plik README, który można odczytać jako artefakt odpowiedzialnego ujawnienia:
# @ncurran/sandbox-recon-880538 — authorized npm-sandbox security researchTo jest łagodny pakiet opublikowany w ramach własnego zakresu autora `@ncurran` jako część autoryzowane zaangażowanie w program HackerOne/GitHub Bug Bounty (npm jest w zakresie).
Podczas instalacji przeprowadzana jest kontrola własne środowisko wykonawcze … zmienna środowiskowa
tylko nazwy kluczy … sprawdza, czy znane punkty końcowe metadanych w chmurze jest osiągalny … Raportuje tylko kody statusu, długości odpowiedzi i hasze — nigdy żadnych danych uwierzytelniających, wartości tokenów ani danych stron trzecich. Nie wykonuje żadnych wytrwałość, brak ruchów bocznych i brak działań destrukcyjnych.
Trzy twierdzenia w tym tekście są sprzeczne z dostarczonym kodem. Plik README zawiera informację „brak trwałości”, ale sygnał Windows zapisuje klucz podniesienia uprawnień oparty na rejestrze. Zawiera informację „nigdy żadnych poświadczeń, wartości tokena”, ale ścieżka Windows uruchamia dowolne pobrane polecenia jako SYSTEM, który nie nakłada żadnych ograniczeń na to, co jest odczytywane lub zwracane. Podaje nawet nazwę pakietu — @ncurran/sandbox-recon-880538 — to nie jest ten, w którym jest dostarczany, co wskazuje, że plik README jest szablonem wielokrotnego użytku, a nie opisem posiadanego artefaktu. Zastrzeżenie o zgodzie w pakiecie, którego instalacja przez ofiarę nigdy nie była akceptowana, nie udziela zgody. Klasyfikacja w tym przypadku jest złośliwa, niezależnie od sformułowania. Zastrzeżenie ma również bardziej dyskretny cel: zautomatyzowany etap selekcji, który odczytuje tekst pakietu w celu uzyskania uspokajających sygnałów — „nieszkodliwy”, „autoryzowany”, nazwany program, adres e-mail kontaktowy — może zostać nakłoniony do wydania bezpiecznego werdyktu za pomocą prozy, której treść jest sprzeczna. Lekcja ta dotyczy zarówno recenzentów, jak i maszyn: należy brać pod uwagę zachowanie podczas instalacji, a nie opis zawarty w pliku README.
Oś czasu
Wszystkie pakiety pojawiły się w ciągu 24 godzin. Cztery nazwy pojedynczej wersji pojawiły się jako pierwsze, a następnie dwa pakiety, które były ponownie publikowane co 30–60 minut.
| Data (UTC) | wydarzenie |
|---|---|
| 2026-06-15 18:32 | Pierwszy pakiet opublikowany — npm:pkg-telemetry-r4f9@1.0.0 |
| 2026-06-15 19:50 | npm:runtime-metrics-w7k2@1.0.0 opublikowany |
| 2026-06-15 20:14 | npm:build-tracker-n5p1@1.0.0 opublikowany |
| 2026-06-15 20:35 | npm:npm-sandbox-ping-r9t2@1.0.0 opublikowany |
| 2026-06-15 21:09–22:42 | npm:event-metrics-q3x7 opublikowany 1.0.0 → 1.0.8 (9 wersji) |
| 2026-06-15 23:40 → 2026-06-16 04:40 | npm:metrics-pipeline-d8k2 opublikowany 1.0.0 → 1.0.10 (11 wersji) |
| 2026-06-16 | Zidentyfikowano klaster i sklasyfikowano go jako złośliwy; kilka plików tarball już zwraca błąd 404 w rejestrze (w toku) |
Kampania jest niedawna, a usunięcie wciąż trwa: w momencie analizy niektóre wersje zostały usunięte z rejestru, a inne nie. Traktuj wszystkie 26 wersji jako zainfekowane.
Wskaźniki kompromisu
Pakiety
| ekosystem | Pakiet | wersje | Status |
|---|---|---|---|
| Npm | metrics-pipeline-d8k2 | 1.0.0 – 1.0.10 | złośliwy |
| Npm | event-metrics-q3x7 | 1.0.0 – 1.0.8 | złośliwy |
| Npm | runtime-metrics-w7k2 | 1.0.0 | złośliwy |
| Npm | build-tracker-n5p1 | 1.0.0 | złośliwy |
| Npm | npm-sandbox-ping-r9t2 | 1.0.0 | złośliwy |
| Npm | pkg-telemetry-r4f9 | 1.0.0 | złośliwy |
Sieć
| Typ | Wskaźnik | Komentarz |
|---|---|---|
| IP | 173.255.233[.]239 | Kolektor C2; rekonstrukcja POST Linuksa i powrót do systemu Windows:443 |
| Domena | diameter-coins-limitations-parents.trycloudflare[.]com | Kanał poleceń systemu Windows przez tunel Cloudflare, :443 |
| Ścieżka URI | /c2/poll, /c2/out, /c2/eof | Polecenie systemu Windows: sondowanie/wyjście/zamknięcie |
| IP | 169.254.170[.]2 | Punkt końcowy metadanych instancji AWS ECS zbadany z haka instalacyjnego |
Behawioralny
| Signal | OPIS |
|---|---|
| Zainstalować hooks | preinstall oraz postinstall oba działają node run.js |
| Wysyłka platformy | run.js działa beacon_linux.js na Linuksie, beacon34.js / beacon18.js w systemie Windows |
| Rekonesans Linuksa | Wylicza nazwy kluczy env-var, odczytuje /proc, czeki docker.sock, biegnie hostname / whoami, sondy IMDS |
| Podniesienie okien | ms-settings DelegateExecute ominięcie kontroli konta użytkownika w rejestrze; PowerShell -ExecutionPolicy Bypass + Invoke-Expression; działa jako SYSTEM |
| Przebranie | W pliku README podano, że badania są „łagodne”, „autoryzowane” i „niezgodne z oczekiwaniami”; odniesiono się do nazwy pakietu, w którym nie są dostarczane |
Atrybucja i obserwowane zachowanie
Opisujemy wydawcę wyłącznie na podstawie jego sygnałów i nie potwierdzamy tożsamości żadnej osoby stojącej za kontem.
- Katalog sygnałów. Wszystkie sześć pakietów zostało opublikowanych na tym samym koncie npm, npmresearch8847z podanym adresem e-mail npmresearch8847@web-library.net (e-mail i SCM brak weryfikacji obu; nie zweryfikowaliśmy własności). Pliki README są publikowane na podstawie @ncurran zakres i podaj kontakt nicholas@curran.tech, uruchom.js punkty w repozytorium github.com/ncurran/npm-sandbox-research`. Sześć pakietów ma identyczny uruchom.js dyspozytor, wspólny beacon_linux.js etap rozpoznawczy i pojedynczy host kolektora 173.255.233[.]239`. Schemat nazewnictwa jest spójny: ogólny rdzeń brzmiący jak CI (metryka, telemetria, śledzenie kompilacji, sandbox-ping) plus krótki losowy sufiks.
- Pewność siebie. Sześć pakietów wydaje się stanowić jedną kampanię, opartą na współdzielonym dyspozytorze, etapie rozpoznania i hoście C2. Sformułowanie „autoryzowane badania” wydaje się spójne we wszystkich sześciu plikach README. Nie udało nam się potwierdzić, aby jakikolwiek program bug-bounty autoryzował tę aktywność, a twierdzenia zawarte w zastrzeżeniu nie pokrywają się z dostarczonym kodem.
- Obserwowana zdolność. Ćwiczenie ładunkuciscztery klasy możliwości: wykonywanie kodu install-hook na obu preinstalacja oraz po instalacji; rozpoznanie hosta i środowiska CI z wyjściem do zewnętrznego kolektora; sondowanie dostępności metadanych instancji w chmurze z kontekstu instalacji; a w systemie Windows lokalna eskalacja uprawnień, wykonywanie jako SYSTEMoraz pętlę poleceń „pobierz i uruchom” przez kanał zewnętrzny. Pętla poleceń systemu Windows to funkcja zdalnego sterowania: sprawdza instrukcje i zwraca ich wyniki.
Wpływ, trendy i co powinni zrobić obrońcy
Wpływ
Narażenie jest najwyższe w przypadku zautomatyzowanych środowisk kompilacji. Instalacja npm w CI uruchamia cykl życia. hooks z dowolną tożsamością, którą posiada użytkownik; w przypadku serwera w chmurze tożsamość ta często obejmuje osiągalny punkt końcowy metadanych i poświadczenia roli. Adres, który sonduje Linux Beacon, 169.254.170[.]2, to punkt końcowy metadanych zadania AWS ECS: zadanie, które może do niego dotrzeć, zazwyczaj może również pobrać tymczasowe dane uwierzytelniające swojej roli zadania z tej samej usługi łącza lokalnego. Sprawdzenie dostępności w skrypcie instalacyjnym to krok poprzedzający pobranie tych danych uwierzytelniających, dlatego każdy program uruchamiający, który uruchomił hak i mógł dotrzeć do tego punktu końcowego, powinien być traktowany tak, jakby jego rola zadania została ujawniona. Na hoście deweloperskim lub kompilacji systemu Windows ładunek żąda podniesienia uprawnień i otwiera kanał poleceń, co rozszerza zakres ujawnienia z pojedynczego profilu i wyjścia na interaktywne zdalne sterowanie.
Nie udało nam się uzyskać wiarygodnych danych o liczbie pobrań złośliwych wersji przed ich usunięciem, dlatego nie szacujemy liczby ofiar. Szybkie ponowne opublikowanie dwóch pakietów – jedenastu i dziewięciu wersji w ciągu kilku godzin – sprawiło, że instalatory i resolvery wciąż miały dostęp do nowych artefaktów, podczas gdy starsze wersje były usuwane.
Nowe wzorce
Ten klaster jest przykładem etykiety używanej jako przykrywka. „Autoryzowane badania”, „nagroda za wykrycie błędów” i „testowanie w piaskownicy” są coraz częściej przypisywane pakietom, których skrypty instalacyjne robią coś więcej niż tylko profilują hosta. Takie podejście wykorzystuje wahanie recenzenta przed działaniem przeciwko czemuś, co ogłasza się jako zatwierdzone. Wiąże się to z drugą znaną taktyką: nazwami pakietów zaprojektowanymi tak, aby wyglądały na wewnętrzne narzędzia CI, dzięki czemu nie rzucają się w oczy na pierwszy rzut oka w drzewie zależności. To właśnie ta kombinacja sprawia, że warto obserwować ten schemat — nazwa, która brzmi jak infrastruktura hydrauliczna, ujęta w prozę, która brzmi jak zatwierdzony test, poprzedzająca hak instalacyjny, który eskaluje w jednym systemie operacyjnym i sprawdza dane uwierzytelniające w chmurze w drugim. Ani zastrzeżenie, ani nijaka nazwa nie zmieniają tego, co kod robi podczas instalacji, a proces selekcji, który traktuje którykolwiek z nich jako dowód łagodzący, doprowadzi do błędnego werdyktu.
Co powinni zrobić obrońcy
- Przeszukaj pliki blokad i dzienniki instalacji pod kątem sześciu nazw pakietów; traktuj każde dopasowanie jako incydent, a nie ostrzeżenie.
- Blokuj i powiadamiaj o ruchu wychodzącym 173.255.233[.]239 i *.trycloudflare[.]com gospodarze z infrastruktury budowlanej.
- Poszukiwanie żądań HTTP w czasie instalacji do adresów metadanych instancji (169.254.170.2, 169.254.169.254) pochodzące z menedżerów pakietów w CI.
- Dokonaj rotacji wszystkich poświadczeń ról w chmurze i tokenów, do których można było uzyskać dostęp z poziomu programu uruchamiającego, który zainstalował zagrożoną wersję.
- Audyt preinstalacja/po instalacji skrypty w twoim zestaw zależności; warto przeczytać hak cyklu życia, który uruchamia drugi plik skryptu.
- Na punktach końcowych systemu Windows poszukaj nowych DelegateExecute wartości zapisane pod ms-ustawienia klucz shell-handler — prymityw podniesienia uprawnień używany przez ten ładunek i niezawodny sygnał niezależny od nazwy pakietu.
- Przypnij i przejrzyj pliki blokady oraz wyłącz skrypty instalacyjne (npm install –ignore-scripts) w środowisku CI, w którym Twoja kompilacja ich nie wymaga.
- Traktuj informacje o „autoryzowanych badaniach” lub „łagodnych” zastrzeżeniach wewnątrz skryptu instalacyjnego jako tekst niegodny zaufania, a nie jako powód do zezwolenia na wykonanie skryptu.
Pakiet, który ogłasza dobre intencje w prozie i prośbach SYSTEM w kodzie powinno się oceniać na podstawie kodu.







