TL; DR
En enda npm-utgivare, deadcode09284814, har drivit en typosquat-kampanj mot den legitima axios och chalk-template paket sedan mitten av maj 2026.
Kampanjen började som en konventionell stöld av autentiseringsuppgifter och plånböcker, där data stjäls till en Serveo HTTPS-tunnel.
On 2026-05-17, med axois-utils:1.0.9, operatören bytte nyttolasten helt: samma trippel installations-hook-scaffold, samma utgivare, samma paketnamn.
Men installationsskriptet är nu en plattformsoberoende DDoS-botnätrekrytering.
Nyttalasten talar till en localhost.run tunnel och accepterar översvämningskommandon, vilket förvandlar infekterade miljöer till en del av ett DDoS-kompatibelt botnät.
Operatören skickade till och med C2-serverns binärfil inuti tarballen, vilket visar en tydlig eskalering från stöld av autentiseringsuppgifter till aktiv botnätsinfrastruktur.
Två paket, fyra versioner fortfarande aktiva i registret, och en operatör som nu kör båda modulerna parallellt.
Allvarlighetsgrad: hög.
Attacken: Hur den fungerar
Kampanjen är byggd på en avsiktligt tråkig leveransstruktur: två typosquat-paketnamn, en bokstavsförskjutning från paket med hundratals miljoner nedladdningar varje vecka (Axios, krita-mall), och trippelinstallation hooks som garanterar utförande. Det intressanta är vad ställningen bär — och det faktum att operatören ändrade lasten utan att ändra något annat.
Den delade ställningen
Varje publicerad version av båda paketen deklarerar samma tre livscykler hooks in package.json:
Lista nyttolasten under alla tre hooks är överdrivet — efterinstallation ensam skulle köras som standard npm installeraValet spelar roll: npm-installation –ignore-scripts hoppar över skript, men flera vanliga arbetsflöden (CI-cacheåterställningar som körs om livscykeln hooks selektivt, eller utvecklare som endast granskar efterinstallation) göra en trippelredundant deklaration är det säkraste alternativet för angriparen.
krita-mallar lägger till en andra mekanism: den förklarar axois-utils:^1.0.7 som en körtid beroendeInstallera typosquatted krita-mall därför drar även in syskonet typosquat, och båda nyttolasten körs. De två paketen är ett koordinerat par, inte oberoende listningar.
Fas A — autentiseringsuppgifter / plånbokstjuv (2026-05-15 → nutid)
Fas A är den ursprungliga nyttolasten. Lastaren är kort postinstall.js som pekar mot en Serveo HTTPS omvänd tunnel:
Serveo-underdomänen kodar destinations-IP:n (80.200.28.28) direkt i värdnamnet — en igenkännbar konvention för den tjänsten. Operatorn roterar det slumpmässiga underdomänprefixet mellan versioner för att undvika naiva domänblocklistor, men den underliggande IP-adressen flyttas aldrig.chalk-mall:1.0.14 Begagnade 8a3e818ea8f11186-80-200-28-28…; 1.0.16 / 1.0.19 / 1.0.20 användning f04a273bd84c0622-….)
postinstall.js av med händerna till phantom.js, en medföljande "samlarmodul" med 7 667 linjer. phantom.js går med värden för:
SSH privata nycklar (~/.ssh/*) |
.npmrc innehåll och eventuella npm_* miljötokens |
| AWS-, GCP- och Azure-inloggningsfiler |
GitHub personlig åtkomsttoken regex (ghp_*, gho_*, ghu_*, ghs_*) |
| Krypto-plånboksartefakter för Bitcoin, Exodus, Electrum, Monero, Litecoin, Dogecoin, Zcash, Dash |
En rekursiv .env* gå igenom ~/projects, ~/dev, ~/code, ~/workspaceoch installations-cwd |
Shells historia och den fullständiga process.env |
Buntet skickas till Serveo-tunneln kl. / samlaDet finns ingen förvirring, ingen anti-VM-logik, ingen staging – operatörens satsning ligger på volym och hastighet.
Fas B — Rekrytering av PhantomBot DDoS (2026-05-17, endast axois-utils:1.0.9)
Fas B ersätter phantom.js + postinstall.js med en enda fil med namnet distrube.js (skrivfelet är operatorns). Trippelkrok-scaffolden i package.json är oförändrad; paketet behåller samma namn, omfattning och versionsbumpmönster. Utifrån sett ser axois-utils:1.0.9 ut som en mindre uppföljare till 1.0.6. Inuti är det en annan familj av skadliga program.
distrube.js öppnas med ett konfigurationsblock som namnger operatörens eget varumärke:
// 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')}`; |
Kommentarerna är riktade till en framtida operatör som kör kitet (”Använd din localhost.run HTTPS-URL”). Det, plus det som visas bredvid botklienten, är en indikation på att detta inte bara är en offernyttolast – det är kitet.
Flödet:
- Persistens körs först. Skriptet installeras på tre olika sätt per operativsystem (register Körning + Startmapp + schtasks på Windows; crontab + phantom-bot.service systemd-enhet + .bashrc/.zshrc tillägg + /etc/rc.local på Linux; LaunchAgent com.phantom.bot.plist (på macOS). Persistenstjänstens namn och LaunchAgent-etiketten är båda fantombot / com.phantom.bot, vilket också är varifrån kampanjens namn kommer.
- Systeminformation exfil körs en gång — en engångs-fingeravtrycks-POST till b94b6bcfa27554.lhr.life:443/collect som innehåller värdnamn, plattform, arch, användarnamn, CPU/RAM, nätverksgränssnitt, process.env, cwd, homedir, nodversion och publik IP. Detta är mycket mindre aggressivt än fas A: ingen SSH, inga plånböcker, ingen .env-rekursion. Botens jobb är att registrera, inte att stjäla.
- Hjärtslagsslinga öppnar ett HTTPS POST var 30:e sekund till b94b6bcfa27554.lhr.life:443/. Användaragenten är PhantomBot/1.0. TLS-verifiering är explicit inaktiverad (rejectUnauthorized: false). C2-svaret tolkas som JSON av formen {type, target, port, duration, threads, method} och skickas.
- Översvämningsarsenal är kopplad till sex kommandon:
| Kommandotyp | Modulerna | Anmärkningar |
|---|---|---|
| ping | Liveness-svar | Boten identifierar sig själv |
| http | HTTP-översvämning | Lager-7-förfrågningsflöde |
| https | HTTPS-översvämning | Samma som http, TLS-omsluten |
| tcp | TCP-översvämning | 65 KB slumpmässig nyttolast-skräppost |
| udp | UDP-översvämning | 65 507-byte UDP-paket |
| snabb | HTTP/2 snabbåterställnings-DoS | 2023 CVE-2023-44487-tekniken |
Alla fem översvämningsmoduler tar en mål, port, varaktighetoch trådar argument — boten är en generisk uthyrningsrobot, inte riktad mot något specifikt offer. Operatörens offerlista finns på C2, inte i paketet.
Nyheter här — den levererade C2-binärfilen
Fas A är en bekant form: stöld av autentiseringsuppgifter, installationshook, leverantörstunnlad C2. Fas B är också en bekant form — DDoS-botnät har varit en del av skadliga npm-paket i åratal. Det ovanliga är att operatören skickade serversidan av kitet inuti npm-tarballen:
- c2 — en 4-megabyte kompilerad Go ELF-binärfil
- c2.go — den 426 rader långa Go-källkoden för den binärfilen
Ingen av filerna anropas av någon installationshook. De är inte en del av offrets nyttolast. De finns i paketkatalogen på samma sätt som en dokumentationsfil skulle göra. Den mest troliga tolkningen är att operatören pushade sitt utvecklingsträd till npm utan att kurera fillistan – ett riktigt OpSec-misstag – och det som levererades är det kompletta tvåsidiga paketet: klienten som ett offer kör och servern som operatören kör.
Det här är den delen av historien som rättfärdigar framställningen av "nyckelfärdigt botnätspaket". Alla som laddade ner axois-utils:1.0.9 innan nedtagningen inte bara har ett offerprov — de har en fungerande C2-server.
Pivoten, i en mening
Samma utgivare, samma paketnamn, samma trippelkrok-scaffold, samma "fantom"-varumärke – men nyttolasten ändrade intäktsgenereringsmodellen över en natt: från "skördehemligheter jag kan sälja vidare" till "hyra översvämningskapacitet jag kan leasa". De TTP:er vid installationstid som försvarare bör hålla koll på är nästan identiska i båda faserna; signaturbaserade försvar kopplade till Fas A:s plånboksvägssträngar eller till phantom.jss samlare med 7 667 rader skulle ha missat fas B helt och hållet.
| Datum (UTC) | Event |
|---|---|
| 2026-05-15 | Första publikationen: axois-utils:1.0.4 (LAN-testbygge, utvecklingsrigg på 192.168.129.19) |
| 2026-05-15 | axois-utils:1.0.6 publicerad — Fas A C2 byttes till 80.200.28.28 via Serveo-tunneln; källkommentaren // Change to '80.200.28.28' for public bekräftar dev→prod-bytet |
| 2026-05-16 | chalk-tempalte:1.0.14 och 1.0.16 publicerad — kedjad lastare deklarerar axois-utils:^1.0.7 som ett runtime-beroende; Serveo-underdomänen roterad |
| 2026-05-16 | Fas A-kampanj upptäckt under rutinmässig npm-skanning; bekräftade skadliga domar tillämpades |
| 2026-05-17 | axois-utils:1.0.9 publicerad — nyttolastpivot: PhantomBot DDoS-rekrytering via localhost.run-tunneln; operatörssidan c2 binär och c2.go källkod som levererades i tarballen |
| 2026-05-17 | chalk-tempalte:1.0.19 och 1.0.20 publicerad — fortfarande fas A (stöld); operatören kör nu båda modulerna parallellt |
| 2026-05-17 | Upptäckt av fas B under rutinmässig skanning; domar tillämpade på alla 2026-05-17 versioner |
| (pågående) | Nedtagningsrapporter väntar; alla fyra publicerade paket är fortfarande tillgängliga i registret i skrivande stund |
Indikatorer för kompromiss
Paket
| Ekosystem | Paket | versioner |
|---|---|---|
| npm | axois-utils (typosquat av axios) | 1.0.4, 1.0.6, 1.0.9 |
| npm | chalk-tempalte (typosquat av kritmall) | 1.0.14, 1.0.16, 1.0.19, 1.0.20 |
Författaridentitet
| Fält | Värderar |
|---|---|
| npm-utgivare | deadcode09284814 |
| Utgivarens e-postadress | phantomdeadcode@tutamail.com |
| SCM kontroll | ingen |
Kommando-och-kontroll
| Fas | Slutpunkt | Johtin |
|---|---|---|
| A | f04a273bd84c0622-80-200-28-28.serveousercontent.com:443/collect | Serveo HTTPS-tunnel |
| A | 8a3e818ea8f11186-80-200-28-28.serveousercontent.com:443/collect | Serveo HTTPS-tunnel (tidigare version) |
| A | 80.200.28.28:443/collect | Underliggande VPS-slutpunkt |
| B | b94b6bcfa27554.lhr.life:443/ | localhost.run HTTPS omvänd tunnel |
Filsammanfattningar (SHA-256)
| Fil | SHA-256 | Anmärkningar |
|---|---|---|
c2 (Gå ELF, 4 MB) | 165fa92d237fd017c227d00da06ab788212a62be94bf61e95df2d22d00377ef2 | Operatörssidans C2-server, levereras inuti axois-utils:1.0.9 |
c2.go (426 rader) | 7d0ae79fdb1e9968f3323a3712b624643a782ba3efb2cf3a2cb9c4c5513cea30 | Gå till källkoden för C2-binärfilen |
distrube.js | 308b15c023088a7188dea4ef609010ac2493eb4c365b103053d7621a9ca5b935 | Fas B botklient |
phantom.js (chalk-tempalte:1.0.19) | 9e380ec88d3ccf3929e1a104e3b868d4d7b59ca189a8a431a54e9f3357dfdd81 | Fas A-autentiseringsuppgifter / plånboksinsamlare |
phantom.js (chalk-tempalte:1.0.20) | d1c9e3f296ee9f7d5032f73f9c504cede50334bc14c394055fd5cb9c3a6e08b3 | Fas A-kollektor (variant 1.0.20) |
postinstall.js (chalk-tempalte:1.0.19 = 1.0.20) | ffba9bdd6793edd5b38e12900252c1813a693f59c25af51c3b658cf3f27b6162 | Fas A-laddare, byte-identisk i båda versionerna |
Attribuering och motivation
Vi följer den här kampanjen som PhantomBot, med operatörens eget varumärke från Användaragent: PhantomBot/1.0 hjärtslagsrubriken, phantom-bot.service systemd-enheten, com.phantom.bot LaunchAgent-etiketten och fantomdödkod@ e-postadress. Operatorn är konsekvent med detta namn över minst fyra artefakter.
Signalkatalog
- Publisher - dödkod09284814 på npm. Konto med ett handtag, engångs-e-post från Tutamail, nej SCM verifiering. Ingen tidigare publiceringshistorik utöver denna kampanj.
- Återanvändning av varumärke — ”phantom” visas i utgivarens e-postmeddelande, i fas A-samlarens filnamn (phantom.js), i namnet på fas B-persistenstjänsten (phantom-bot.service), i LaunchAgent-etiketten (com.phantom.bot), och i boten User-Agent (PhantomBot/1.0).
- Infrastruktur — En enda VPS på 80.200.28.28 frontar fas A via Serveo-underdomänrotation; fas B flyttar till en localhost.run omvänd tunnel (b94b6bcfa27554.lhr.lifeBåda leverantörstjänsterna är gratis och kräver endast utgående SSH från operatörssidan, vilket är i linje med lågbudget- och låg-OpSec-konfigurationer.
- kodstil — Vanligt JavaScript genomgående; ingen obfuskation, ingen strängkodning, inga anti-VM-kontroller. Variabelnamnen är beskrivande (stjälaSystemInfo, körkommando, httpFloodKommentarer i distrube.js direkt adressera en framtida operator ("Använd din localhost.run HTTPS-URL"), vilket antyder att filen var avsedd att omdistribueras som ett kit, inte användas av en enskild angripare.
- OpSec-slip — Fas B-tarballen levererar både botklienten och operatörssidans C2-server (c2 ELF + c2.go källa). Detta överensstämmer med en operator som pushade sitt arbetsträd till npm utan att granska fillistan. Antingen är operatorn oerfaren, eller så är kittet menas att distribueras offentligt och C2-binärfilen är en del av produkten.
- Självbekräftelse - axois-utils:1.0.4 innehåller källkommentaren // Ändra till '80.200.28.28' för allmänheten på rad 12, vilket bekräftar utvecklings-/staging-/produktionsprogressionen som operatörer vanligtvis förnekar.
Motivation
Fas A-nyttolasten är ren finansiell stöld: inloggningsuppgifter, molnnycklar, GitHub-tokens och kryptoplånböcker har alla likvida återförsäljningsmarknader. Fas B är också finansiell, men indirekt: DDoS-tjänster hyr ut översvämningskapacitet minut för minut, och bottar som den som levereras här är det lager som dessa tjänster körs på. 30-sekunderspulsen, den generiska mål/port/varaktighet kommandoschemat och översvämningsarsenalen med fem protokoll är standard produkt från en booter-operatör.
Köra båda modulerna parallellt — chalk-mall:1.0.19 och 1.0.20 fortsätta att skicka stjälen medan axois-utils:1.0.9 levererar boten — antyder att operatören säkrar intäktsströmmar snarare än att överge fas A. Pivoten är en Dessutom, inte en ersättare.
Vad vi inte påstår
Vi har inte kunnat bekräfta en verklig identitet bakom dödkod09284814 handle, och vi tillskriver inte denna kampanj till någon namngiven hotaktör, grupp eller land. "Fantom"-varumärket är tillräckligt konsekvent över artefakter för att antyda en enda operator, men den kit-liknande leveransen av C2-binärfilen öppnar upp möjligheten att framtida paket från orelaterade handle-koder kommer att återanvända samma kod.
Påverkan, trender och vad försvarare bör göra
Inverkan
De legitima squat-målen Axios och krita-mall är i stor utsträckning beroende av i JavaScript-ekosystemet; Axios ensamt ligger bland de trettio mest nedladdade npm-paketen. Typosquat-namnen är ett tangenttryck ifrån de riktiga (axois ↔ Axios, mall ↔ mall), och båda är språkligt rimliga felstavningar.
Vi kunde inte få tillförlitlig nedladdningsstatistik för de skadliga versionerna före borttagningen — npm sparar inte antalet nedladdningar per version efter att ett paket har avpublicerats, och npms.io-style-proxyer är bullriga i den här skalan. Alla organisationer vars låsfil matchas till ett paket med namnet axois-utils or krita-mallar från utgivaren dödkod09284814 bör behandlas som komprometterade: rotera alla befintliga autentiseringsuppgifter i process.env på den berörda värden, granska persistensvektorer per operativsystem (se "Vad försvarare bör göra" nedan) och ta bort beroendet.
Framväxande mönster
Den här kampanjen exemplifierar ett skifte vi har sett i flera npm-incidenter på senare tid: Installationskrokställningen är den hållbara tillgångennyttolasten är utbytbarSamma utgivare, samma paket, samma förinstallation / installera / efterinstallation trippel, och till och med samma versionsbumpkadens — det enda som förändrades mellan axois-utils:1.0.6 och axois-utils:1.0.9 var filen den hooks körning. Signaturbaserad detektering kopplad till fas A-nyttolasten (plånbokssökvägssträngar, phantom.jss samlare med 7 667 rader, Serveo C2-värden) skulle ha flaggat de tre första versionerna och missat fas B helt och hållet.
Samma mönster syns i andra kampanjer från 2026 som vi har följt: en enda operatör med en stabil struktur, som växlar mellan stöld av autentiseringsuppgifter, klienter som fuskar prov, Telegram-bot-exfil och nu DDoS-rekrytering. Försvarare som förlitar sig på nyttolastsignaturer kommer att fortsätta förlora den andra omgången av varje kampanj.
Följden är att TTP:er vid installationstid är den bättre signalenTrippel install-hook-deklarationer, installationsskript som importerar https or barnprocess, installera skript som skriver till användarstartmappar och installera skript som matchar värdnamn på gratis omvända tunneltjänster (Serveo, localhost.run, ngrok, cloudflared) är alla sällsynta i legitima paket och vanliga bland skadliga paket.
Vad försvarare bör göra
- Låsfilsgranskning. Sök varje package-lock.json / garn.lås / pnpm-lock.yaml i din organisation för de exakta strängarna axois-utils och krita-mallarBehandla varje matchning som en kompromiss.
- Rotera hemligheter på drabbade värdar. Fas A massinsamlade SSH-, moln-, GitHub-, npm- och plånboksuppgifter. Anta att alla autentiseringsuppgifter som någonsin finns i process.env, ~ / .ssh, ~/.aws, ~/.npmrc, ~ / .config, eller några .env* filen på den drabbade värden exponeras.
- Ta bort ihållighet (fas B). I Windows, ta bort HKCU\Software\Microsoft\Windows\CurrentVersion\Run\SystemUpdate, avlägsna %APPDATA%\Microsoft\Windows\Startmeny\Program\Start\system-update.batoch schtasks /delete /tn SystemUpdate /fPå Linux, crontab -e och ta bort @reboot-noden …, systemctl –användare inaktivera –now phantom-bot.service radera sedan ~/.config/systemd/user/phantom-bot.service, skrubba .bashrc / .zshrc / /etc/rc.localPå macOS, launchctl unload ~/Bibliotek/LaunchAgents/com.phantom.bot.plist radera sedan plisten.
- Blockera C2-värdarna. Lägg till de fyra C2-slutpunkterna i IOC-tabellen till din utgående blocklista. *.serveousercontent.com och *.lhr.life kan blockeras i sin helhet om din miljö inte har någon legitim användning för omvända tunneltjänster.
- Sök efter TTP vid installationstid, inte nyttolast. Inventeringslåsfilsposter vars package.json deklarerar förinstallation, installeraoch efterinstallation alla pekar på samma skript. Kontrollera mot paketålder och utgivarens verifieringsstatus. Detta mönster är sällsynt i legitima paket och är den enskilt mest tillförlitliga signalen som PhantomBot återanvänder.
- Granskning för C2-binärfilen. Alla som laddade ner axois-utils:1.0.9 har operatörens C2-server (c2 ELF, sha256 165fa92d…) på disk. Skanna cacheminnen och CI-artefaktlagren. Binärfilen är vilande i sig själv, men dess närvaro på en arbetsstation är ett otvetydigt bevis på att paketet installerades.
Stängningslinjen
Samma operatör, samma paket och samma installationshook kan leverera helt olika hot inom 48 timmar. Titta på ställningen, inte nyttolasten.




