PhantomBot Od kradzieży danych uwierzytelniających do botnetu

PhantomBot: kampania typu typosquat, która przeszła od kradzieży danych uwierzytelniających do gotowego zestawu botnetów

TL; DR

Pojedynczy wydawca npm, deadcode09284814, przeprowadził kampanię typosquatową przeciwko legalnym axios oraz chalk-template pakiety od połowy maja 2026 r.

Kampania rozpoczęła się od konwencjonalnego złodzieja danych uwierzytelniających i portfeli, który wykradał dane do Tunel HTTPS Serveo.

On 2026-05-17Z axois-utils:1.0.9operator całkowicie zamienił ładunek: ten sam potrójny szkielet instalacyjny, ten sam wydawca, ta sama nazwa pakietu.

Jednak skrypt instalacyjny jest teraz rekrutem botnetu DDoS międzyplatformowego.

Ładunek mówi do localhost.run tuneluje i akceptuje polecenia „flood”, zmieniając zainfekowane środowiska w część botnetu zdolnego do przeprowadzania ataków DDoS.

Operator nawet wysłał Serwer C2 w wersji binarnej w archiwum tarball, wyraźnie pokazującym eskalację od kradzieży danych uwierzytelniających do aktywnej infrastruktury botnetu.

Dwa pakiety, cztery wersje nadal aktywne w rejestrze i jeden operator uruchamiający oba moduły równolegle.

Stopień zagrożenia: wysoki.

Nagłówek MKOl Jakakolwiek wersja axois-utils lub chalk-temalte od wydawcy deadcode09284814

Atak: Jak to działa

Kampania opiera się na celowo nudnym schemacie dostawy: dwie błędne nazwy paczek, jedna litera odbiega od nazw paczek z setkami milionów pobrań tygodniowo (aksjos, szablon kredowy), i potrójna instalacja hooks które gwarantują wykonanie. Ciekawe jest to, co stanowi rusztowanie niesie — oraz fakt, że operator zmienił ładunek nie zmieniając niczego innego.

Wspólny rusztowanie

Każda opublikowana wersja obu pakietów deklaruje ten sam trzycykl życia hooks in pakiet.json:

"scripts": {    "preinstall":  "node <payload>.js",    "install":     "node <payload>.js",    "postinstall": "node <payload>.js"  } 

Wymienienie ładunku pod wszystkimi trzema hooks to przesada — po instalacji sam by działał domyślnie npm zainstalowaćWybór ma znaczenie: npm install –ignore-scripts pomija skrypty, ale kilka typowych przepływów pracy (przywracanie pamięci podręcznej CI, które ponownie uruchamia cykl życia) hooks selektywnie lub deweloperzy, którzy tylko audytują po instalacji) zrób potrójnie redundantną deklarację, co będzie najbezpieczniejszym rozwiązaniem dla atakującego.

szablon kredowy dodaje drugi mechanizm: deklaruje axois-utils:^1.0.7 jako środowisko wykonawcze zależność. Instalacja typosquatted szablon kredowy W związku z tym wciąga również siostrzanego typosquata i oba ładunki są uruchamiane. Te dwa pakiety stanowią skoordynowaną parę, a nie niezależne listy.

Faza A — złodziej danych uwierzytelniających/portfela (2026-05-15 → obecnie)

Faza A to oryginalny ładunek. Ładowarka to krótki postinstall.js który wskazuje na odwrotny tunel HTTPS Serveo:

// chalk-tempalte/postinstall.js:11-13  const C2_HOST = "f04a273bd84c0622-80-200-28-28.serveousercontent.com";  const C2_PORT = 443;  const C2_PATH = '/collect'; 

Poddomena Serveo koduje adres IP docelowy (80.200.28.28) bezpośrednio w nazwie hosta — rozpoznawalna konwencja dla tej usługi. Operator zmienia losowy prefiks subdomeny między wersjami, aby ominąć naiwne listy blokowania domen, ale podstawowy adres IP nigdy się nie zmienia.chalk-temalte:1.0.14 używany 8a3e818ea8f11186-80-200-28-28…; 1.0.16 / 1.0.19 / 1.0.20 użycie f04a273bd84c0622-….)

postinstall.js ręce precz phantom.js, moduł „kolekcjonerski” składający się z 7,667 linii. phantom.js spaceruje po gospodarzu:

Prywatne klucze SSH (~/.ssh/*)
.npmrc zawartość i wszelkie npm_* tokeny środowiskowe
Pliki poświadczeń AWS, GCP i Azure
GitHub personal-access-token regex (ghp_*, gho_*, ghu_*, ghs_*)
Artefakty portfeli kryptowalutowych dla Bitcoin, Exodus, Electrum, Monero, Litecoin, Dogecoin, Zcash, Dash
Rekurencyjny .env* przejść przez ~/projects, ~/dev, ~/code, ~/workspacei instalacja cwd
Historie muszli i pełna wersja process.env

Pakiet jest wysyłany pocztą do tunelu Serveo pod adresem / zbieraćNie ma tu żadnego zaciemniania, żadnej logiki anty-VM, żadnego przygotowania — operator stawia na głośność i szybkość.

Faza B — rekrutacja PhantomBot DDoS (2026-05-17, axois-utils: tylko 1.0.9)

Faza B zastępuje pliki phantom.js + postinstall.js pojedynczym plikiem o nazwie distrube.js (literówka pochodzi od operatora). Rusztowanie z potrójnym hakiem w pliku package.json pozostaje niezmienione; pakiet zachowuje tę samą nazwę, zakres i wzorzec zmiany wersji. Z zewnątrz axois-utils:1.0.9 wygląda jak pomniejsza kontynuacja wersji 1.0.6. Wewnątrz to zupełnie inna rodzina złośliwego oprogramowania.

distrube.js otwiera się blokiem konfiguracyjnym, który nadaje nazwę własnej marce operatora:

// axois-utils-1.0.9/distrube.js:11-15
// Use your localhost.run HTTPS URL (the tunnel handles HTTP internally)
const C2_HOST = 'b94b6bcfa27554.lhr.life'; // Your localhost.run tunnel
const C2_PORT = 443; // HTTPS port - tunnel handles SSL
const BOT_ID = `${os.hostname()}_${Date.now()}_${crypto.randomBytes(4).toString('hex')}`;

Komentarze są skierowane do przyszłego operatora, który będzie obsługiwał zestaw („Użyj adresu URL HTTPS localhost.run”). To, a także to, co jest przesyłane do klienta bota, wskazuje, że to nie jest po prostu ładunek ofiary, ale cały zestaw.

Przepływ:

  1. Uporczywość uruchamia się jako pierwszy. Skrypt instaluje się na trzy różne sposoby w zależności od systemu operacyjnego (rejestr Uruchom + Folder startowy + schtasks w systemie Windows; crontab + usługa phantom-bot jednostka systemd + .bashrc/.zshrc dołącz + /etc/rc.local na Linuksie; LaunchAgent com.phantom.bot.plist (w systemie macOS). Nazwa usługi trwałości i etykieta LaunchAgent są zarówno bot-widmo / com.phantom.bot, skąd też wzięła się nazwa kampanii.
  2. Wyciek informacji o systemie uruchamia się raz — jednorazowy odcisk palca POST do b94b6bcfa27554.lhr.life:443/collect zawierający nazwę hosta, platformę, architekturę, nazwę użytkownika, procesor/pamięć RAM, interfejsy sieciowe, process.env, cwd, homedir, wersję węzła i publiczny adres IP. To znacznie mniej agresywne rozwiązanie niż faza A: brak SSH, brak portfeli, brak rekurencji .env. Zadaniem bota jest rejestracja, a nie kradzież.
  3. Pętla bicia serca co 30 sekund otwiera żądanie HTTPS POST do b94b6bcfa27554.lhr.life:443/. User-Agent to PhantomBot/1.0. Weryfikacja TLS jest jawnie wyłączona (rejectUnauthorized: false). Odpowiedź C2 jest analizowana jako JSON w formacie {typ, cel, port, czas trwania, wątki, metoda} i wysyłana.
  4. Arsenał powodziowy jest powiązany z sześcioma poleceniami:
Typ polecenia Moduł Komentarz
świst Odpowiedź na żywość Bot identyfikuje się
http Powódź HTTP Powódź żądań warstwy 7
https Powódź HTTPS Tak samo jak http, w opakowaniu TLS
tcp Powódź TCP 65 KB losowego spamu
udp powódź UDP Pakiety UDP o rozmiarze 65 507 bajtów
szybki HTTP/2 – szybki reset DoS Technika CVE-2023-44487 z 2023 r.

Wszystkie pięć modułów przeciwpowodziowych zajmuje cel, Port, czas trwania, threads Argument — bot to generyczny, płatny flooder, nieskierowany do żadnej konkretnej ofiary. Lista ofiar operatora znajduje się w C2, a nie w pakiecie.

Co nowego — dostarczony plik binarny C2

Faza A to znany schemat: kradzież danych uwierzytelniających, instalacja haka, tunelowanie C2 przez dostawcę. Faza B to również Znajomy kształt — botnety DDoS są od lat nieodłącznym elementem złośliwych pakietów npm. Nietypowe jest to, że operator wysłał strona serwera zestawu znajdującego się w archiwum npm:

  • c2 — skompilowany plik binarny Go ELF o rozmiarze 4 megabajtów
  • c2.go — 426-liniowe źródło Go dla tego kodu binarnego

Żaden z plików nie jest wywoływany przez żaden hak instalacyjny. Nie są one częścią ładunku ofiary. Znajdują się w katalogu pakietów, tak jak plik dokumentacji. Najbardziej prawdopodobna interpretacja jest taka, że ​​operator przesłał swoje drzewo robocze do npm bez porządkowania listy plików – co stanowi prawdziwą pomyłkę w zakresie bezpieczeństwa operacyjnego – a dostarczony zestaw zawiera kompletny, dwustronny zestaw: klienta uruchamianego przez ofiarę i serwer uruchamiany przez operatora.

To właśnie ta część historii uzasadnia określenie „gotowy zestaw do botnetu”. Każdy, kto pobrał axois-utils:1.0.9 przed usunięciem mają nie tylko próbkę ofiary — mają także działający serwer C2.

Punkt obrotu w jednym zdaniu

Ten sam wydawca, te same nazwy pakietów, ta sama potrójna konstrukcja, ta sama „widmowa” marka — ale ładunek zmienił model monetyzacji z dnia na dzień: od „zbieraj sekrety, które mogę odsprzedać” do „wynajmuj pojemność powodziową, którą mogę wydzierżawić”. Procedury TTP w czasie instalacji, które obrońcy powinni obserwować, są niemal identyczne w obu fazach; obrona oparta na sygnaturach, oparta na ciągach ścieżek portfela fazy A lub phantom.jsKolektor 7,667 linii całkowicie ominąłby fazę B.

Data (UTC) wydarzenie
2026-05-15 Pierwsza publikacja: axois-utils:1.0.4 (wersja testowa LAN, platforma deweloperska na 192.168.129.19)
2026-05-15 axois-utils:1.0.6 opublikowano — faza A C2 zamieniona na 80.200.28.28 przez tunel Serveo; komentarz źródłowy // Change to '80.200.28.28' for public potwierdza zamianę dev→prod
2026-05-16 chalk-tempalte:1.0.14 oraz 1.0.16 opublikowany — ładowarka łańcuchowa deklarująca axois-utils:^1.0.7 jako zależność środowiska wykonawczego; poddomena Serveo została obrócona
2026-05-16 Kampania fazy A odkryta podczas rutynowego skanowania npm; zastosowano werdykty potwierdzające złośliwość
2026-05-17 axois-utils:1.0.9 opublikowano — obrót ładunku: rekrutacja PhantomBot DDoS przez tunel localhost.run; po stronie operatora c2 binarny i c2.go źródło wysłane w archiwum tarball
2026-05-17 chalk-tempalte:1.0.19 oraz 1.0.20 opublikowano — nadal faza A (złodziej); operator teraz uruchamia oba moduły równolegle
2026-05-17 Odkrycie fazy B podczas rutynowego skanowania; werdykty zastosowane we wszystkich 2026-05-17 Wersje
(trwający) Raporty o usunięciu są w trakcie rozpatrywania; wszystkie cztery opublikowane pakiety są nadal dostępne w rejestrze w momencie pisania tego tekstu

Wskaźniki kompromisu

Pakiety

ekosystem Pakiet wersje
Npm axois-utils (literatura aksjosa) 1.0.4, 1.0.6, 1.0.9
Npm chalk-tempalte (typosquat kredowego szablonu) 1.0.14, 1.0.16, 1.0.19, 1.0.20

Tożsamość autora

Pole Wartość:
wydawca npm deadcode09284814
Adres e-mail wydawcy phantomdeadcode@tutamail.com
SCM weryfikacja Żaden

Dowodzenie i kontrola

Faza Punkt końcowy Transport
A f04a273bd84c0622-80-200-28-28.serveousercontent.com:443/collect Tunel HTTPS Serveo
A 8a3e818ea8f11186-80-200-28-28.serveousercontent.com:443/collect Tunel HTTPS Serveo (wcześniejsza wersja)
A 80.200.28.28:443/collect Podstawowy punkt końcowy VPS
B b94b6bcfa27554.lhr.life:443/ localhost.run odwrotny tunel HTTPS

Podsumowania plików (SHA-256)

filet SHA-256 Komentarz
c2 (Przejdź do ELF, 4 MB) 165fa92d237fd017c227d00da06ab788212a62be94bf61e95df2d22d00377ef2 Serwer C2 po stronie operatora, dostarczany wewnątrz axois-utils:1.0.9
c2.go (426 wierszy) 7d0ae79fdb1e9968f3323a3712b624643a782ba3efb2cf3a2cb9c4c5513cea30 Przejdź do źródła pliku binarnego C2
distrube.js 308b15c023088a7188dea4ef609010ac2493eb4c365b103053d7621a9ca5b935 Klient bota fazy B
phantom.js (chalk-tempalte:1.0.19) 9e380ec88d3ccf3929e1a104e3b868d4d7b59ca189a8a431a54e9f3357dfdd81 Kolekcjoner danych uwierzytelniających/portfela fazy A
phantom.js (chalk-tempalte:1.0.20) d1c9e3f296ee9f7d5032f73f9c504cede50334bc14c394055fd5cb9c3a6e08b3 Kolektor fazy A (wariant 1.0.20)
postinstall.js (chalk-tempalte:1.0.19 = 1.0.20) ffba9bdd6793edd5b38e12900252c1813a693f59c25af51c3b658cf3f27b6162 Ładowarka fazy A, identyczna bajtowo w obu wersjach

Atrybucja i motywacja

Śledzimy tę kampanię jako PhantomBot, przejmując własną markę operatora User-Agent: PhantomBot/1.0 nagłówek bicia serca, usługa phantom-bot jednostka systemd, com.phantom.bot Etykieta LaunchAgent i phantomdeadcode@ Adres e-mail. Operator jest konsekwentny w odniesieniu do tej nazwy w co najmniej czterech artefaktach.

Katalog sygnałów

  • wydawca Do kod martwy09284814 na npm. Konto z jednym uchwytem, ​​jednorazowy adres e-mail Tutamail, brak SCM weryfikacja. Brak wcześniejszych publikacji poza tą kampanią.
  • Ponowne wykorzystanie marki — „phantom” pojawia się w e-mailu wydawcy w nazwie pliku kolekcjonera fazy A (phantom.js), w nazwie usługi trwałości fazy B (usługa phantom-bot), w etykiecie LaunchAgent (com.phantom.bot), a w bota User-Agent (PhantomBot/1.0).
  • Infrastruktura — Pojedynczy VPS w 80.200.28.28 fronty Faza A poprzez rotację poddomeny Serveo; Faza B przesuwa się do localhost.run tunel odwrotny (b94b6bcfa27554.lhr.życieObie usługi tego dostawcy są bezpłatne i wymagają jedynie połączenia wychodzącego SSH po stronie operatora, co jest zgodne z konfiguracjami o niskim budżecie i niskim poziomie bezpieczeństwa operacyjnego.
  • Styl kodu — Czysty JavaScript w całym tekście; bez zaciemniania, bez kodowania ciągów znaków, bez kontroli anty-VM. Nazwy zmiennych są opisowe (stealSystemInfo, wykonaj polecenie, httpFlood). Komentarze w distrube.js bezpośrednio zwraca się do przyszłego operatora („Użyj adresu URL HTTPS localhost.run”), co sugeruje, że plik miał być rozpowszechniany jako zestaw, a nie używany przez pojedynczego atakującego.
  • Błąd w zabezpieczeniach operacyjnych — Archiwum tarball fazy B zawiera zarówno klienta bota, jak i serwer C2 po stronie operatora (c2 ELF + c2.go (źródło). Jest to zgodne z operatorem, który przesłał swoje drzewo robocze do npm bez audytu listy plików. Albo operator jest niedoświadczony, albo zestaw jest Oznaczało ma być rozpowszechniany publicznie, a plik binarny C2 jest częścią produktu.
  • Samopotwierdzenie Do axois-utils:1.0.4 zawiera komentarz źródłowy // Zmień na „80.200.28.28” dla adresu publicznego w wierszu 12, potwierdzając postęp prac rozwojowych/przygotowawczych/produkcyjnych, który operatorzy zazwyczaj negują.

Motywacja

Ładunek Fazy A to prosta kradzież finansowa: dane uwierzytelniające, klucze w chmurze, tokeny GitHub i portfele kryptowalutowe mają płynne rynki odsprzedaży. Faza B to również kradzież finansowa, ale pośrednia: usługi DDoS na zlecenie („booter”) wynajmują przepustowość na minuty, a boty takie jak ten przedstawiony tutaj stanowią zasoby, na których działają te usługi. 30-sekundowe bicie serca, ogólny cel/Port/czas trwania schemat poleceń i arsenał pięciu protokołów powodziowych to standard produkt operatora bootera.

Uruchamianie obu modułów równolegle — chalk-temalte:1.0.19 oraz 1.0.20 nadal wysyłaj złodzieja, podczas gdy axois-utils:1.0.9 wysyła bota — sugeruje, że operator zabezpiecza strumienie przychodów, zamiast porzucać fazę A. Punktem zwrotnym jest dodatek, nie zamiennik.

Czego nie twierdzimy

Nie udało nam się potwierdzić prawdziwej tożsamości osoby, która się za nią kryje. kod martwy09284814 handle i nie przypisujemy tej kampanii żadnemu konkretnemu podmiotowi, grupie ani państwu, które mogłyby stanowić zagrożenie. „Fantomowa” marka jest na tyle spójna w przypadku artefaktów, że sugeruje jednego operatora, ale sposób dostarczania pliku binarnego C2 w formie zestawu pozostawia otwartą możliwość, że przyszłe pakiety z niepowiązanych uchwytów będą ponownie wykorzystywać ten sam kod.

Wpływ

Uzasadnione cele przysiadów aksjos oraz szablon kredowy są szeroko stosowane w ekosystemie JavaScript; aksjos Sam znajduje się w czołówce trzydziestu najczęściej pobieranych pakietów npm. Nazwy te są o jedno naciśnięcie klawisza od prawdziwych (aksoziaksjos, szablonyszablon), przy czym oba są błędami ortograficznymi, które są prawdopodobne pod względem językowym.

Nie udało nam się uzyskać wiarygodnych statystyk pobierania złośliwych wersji przed usunięciem — npm nie przechowuje liczby pobrań dla każdej wersji po wycofaniu publikacji pakietu, a npms.ioSerwery proxy w stylu „-” generują zakłócenia w tej skali. Każda organizacja, której plik blokady jest rozwiązywany na pakiet o nazwie axois-utils or szablon kredowy od wydawcy kod martwy09284814 należy traktować jako zagrożone: wymień wszystkie obecne dane uwierzytelniające proces.env na dotkniętym hoście przeprowadź audyt wektorów trwałości dla każdego systemu operacyjnego (zobacz „Co powinni zrobić obrońcy” poniżej) i usuń zależność.

Nowe wzorce

Kampania ta jest przykładem zmiany, którą zaobserwowaliśmy w kilku ostatnich incydentach npm: rusztowanie instalacyjne jest trwałym atutem; ładunek jest wymiennyTen sam wydawca, ten sam pakiet, ten sam preinstalacja / zainstalować / po instalacji potrójne, a nawet ta sama wersja – rytm podbicia – jedyna rzecz, która się zmieniła axois-utils:1.0.6 oraz axois-utils:1.0.9 był ten plik hooks uruchom. Wykrywanie oparte na sygnaturach, oparte na ładunku fazy A (ciągi ścieżek portfela, phantom.jsKolektor 7,667 linii, host Serveo C2, oznaczyłby pierwsze trzy wersje i całkowicie pominąłby fazę B.

Ten sam schemat widoczny jest w innych kampaniach z 2026 roku, które śledziliśmy: jeden operator ze stabilnym systemem, na zmianę kradnący dane uwierzytelniające, oszukujący na egzaminach, wyprowadzający boty Telegramu, a teraz werbujący ofiary ataków DDoS. Obrońcy, którzy polegają na sygnaturach danych, będą przegrywać drugą rundę każdej kampanii.

Wniosek jest taki, że TTP w czasie instalacji to lepszy sygnał. Potrójne deklaracje hooków instalacyjnych, skrypty instalacyjne importujące https or proces_potomny, zainstaluj skrypty, które zapisują w folderach startowych użytkownika i zainstaluj skrypty, które rozwiązują nazwy hostów w bezpłatnych usługach odwrotnego tunelowania (Serveo, localhost.run, ngrok, cloudflared) zdarzają się rzadko w legalnych pakietach, ale często w pakietach złośliwych.

Co powinni zrobić obrońcy

  • Audyt pliku blokady. Przeszukaj każdy pakiet-lock.json / yarn.lock / pnpm-lock.yaml w Twojej organizacji, aby uzyskać dokładne ciągi znaków axois-utils oraz szablon kredowy. Traktuj każde spotkanie jako kompromis.
  • Obróć sekrety na zainfekowanych hostach. Faza A – zbiorcze dane uwierzytelniające SSH, chmurę, GitHub, npm i portfel. Załóżmy, że wszystkie dane uwierzytelniające są obecne. proces.env, ~ / .ssh, ~/.aws, ~/.npmrc, ~ / .configlub dowolny .env* plik na zainfekowanym hoście zostanie ujawniony.
  • Usuń trwałość (faza B). W systemie Windows usuń HKCU\Software\Microsoft\Windows\CurrentVersion\Run\SystemUpdate, usuń %APPDATA%\Microsoft\Windows\Menu Start\Programy\Uruchamianie\system-update.bat, schtasks /delete /tn SystemUpdate /f. W systemie Linux, crontab -e i usuń @reboot węzeł …, systemctl –user disable –now phantom-bot.service następnie usuń ~/.config/systemd/user/phantom-bot.service, szorować .bashrc / .zshrc / /etc/rc.local. Na macOS, launchctl unload ~/Library/LaunchAgents/com.phantom.bot.plist następnie usuń plik plist.
  • Zablokuj hosty C2. Dodaj cztery punkty końcowe C2 z tabeli IOC do listy blokowanych wyjść. *.serveousercontent.com oraz *.lhr.life mogą zostać zablokowane hurtowo, jeśli w twoim środowisku nie ma uzasadnionego zastosowania dla usług odwrotnego tunelu.
  • Polowanie według czasu instalacji TTP, nie ładunek. Wpisy pliku blokady inwentarza, których pakiet.json deklaruje preinstalacja, zainstalować, po instalacji Wszystkie wskazują na ten sam skrypt. Sprawdź wiek pakietu i status weryfikacji wydawcy. Ten wzorzec jest rzadki w przypadku legalnych pakietów i jest najbardziej wiarygodnym sygnałem, że PhantomBot ponownie wykorzystuje.
  • Audyt binarny C2. Każdy, kto pobrał axois-utils:1.0.9 posiada serwer C2 operatora (c2 ELF, sha256 165fa92d…) na dysku. Przeskanuj pamięć podręczną i magazyny artefaktów CI. Plik binarny sam w sobie jest uśpiony, ale jego obecność na stacji roboczej stanowi jednoznaczny dowód na to, że pakiet został zainstalowany.

Linia zamykająca

Ten sam operator, ten sam pakiet i ten sam hak instalacyjny mogą dostarczyć zupełnie innych zagrożeń w ciągu 48 godzin. Uważaj na rusztowanie, a nie na ładunek.

sca-tools-oprogramowanie-narzędzia-analizy-kompozycji
Określ priorytety, rozwiąż problemy i zabezpiecz zagrożenia związane z oprogramowaniem
Załóż darmowe konto.
Nie wymagamy karty kredytowej.

Zabezpiecz swoje oprogramowanie i dostarczanie

z pakietem produktów Xygeni