TL; DR
In inkele npm-útjouwer, deadcode09284814, hat in typosquat-kampanje fierd tsjin de legitime axios en chalk-template pakketten sûnt mids maaie 2026.
De kampanje begon as in konvinsjonele stellerij fan ynloggegevens en wallets, wêrby't gegevens waarden stellen nei in Serveo HTTPS-tunnel.
On 2026-05-17, mei axois-utils:1.0.9, de operator hat de lading folslein omwiksele: deselde triple install-hook scaffold, deselde útjouwer, deselde pakketnamme.
Mar it ynstallaasjeskript is no in cross-platform DDoS botnet rekrutearing.
De lading sprekt ta in localhost.run tunnel en akseptearret oerstreamingskommando's, wêrtroch ynfekteare omjouwings wurde feroare yn ûnderdiel fan in DDoS-kompatibel botnet.
De operator ferstjoerde sels de C2-tsjinner binêr binnen de tarball, dy't in dúdlike eskalaasje sjen lit fan diefstal fan ynloggegevens nei aktive botnet-ynfrastruktuer.
Twa pakketten, fjouwer ferzjes noch aktyf yn it register, en ien operator dy't no beide modules parallel útfiert.
Ernst: heech.
De oanfal: Hoe't it wurket
De kampanje is boud op in bewust saaie leveringssteiger: twa typosquat-pakketnammen, ien letter ôf fan pakketten mei hûnderten miljoenen wyklikse downloads (axios, krijt-sjabloan), en trijefâldige ynstallaasje hooks dy't útfiering garandearje. Wat nijsgjirrich is, is wat de steiger draacht — en it feit dat de operator de lading feroare hat sûnder wat oars te feroarjen.
De dielde steiger
Elke publisearre ferzje fan beide pakketten ferklearret deselde trije libbenssyklusen hooks in pakket.json:
"scripts": { "preinstall": "node <payload>.js", "install": "node <payload>.js", "postinstall": "node <payload>.js" } De lading ûnder alle trije listje hooks is oerdreaun - nei ynstallaasje allinnich soe standert rinne npm ynstallearjeDe kar is wichtich: npm ynstallearje –ignore-skripts slaat skripts oer, mar ferskate gewoane workflows (CI-cache herstelt dy't de libbenssyklus opnij útfiere hooks selektyf, of ûntwikkelders dy't allinich kontrolearje nei ynstallaasje) in trijefâldich redundante ferklearring meitsje is de feilichste weddenskip foar de oanfaller.
krijt-sjabloan foeget in twadde meganisme ta: it ferklearret axois-utils:^1.0.7 as in runtime ôfhinklikensYnstallearjen fan de typosquatted krijt-sjabloan lûkt dêrom ek de sibling typosquat yn, en beide payloads rinne. De twa pakketten binne in koördinearre pear, gjin ûnôfhinklike listings.
Faze A — bewiisbrieven / portefeuillediever (2026-05-15 → hjoed)
Faze A is de orizjinele lading. De lader is in koarte postinstall.js dat wiist nei in Serveo HTTPS reverse-tunnel:
// chalk-tempalte/postinstall.js:11-13 const C2_HOST = "f04a273bd84c0622-80-200-28-28.serveousercontent.com"; const C2_PORT = 443; const C2_PATH = '/collect'; It Serveo-subdomein kodearret it bestimmings-IP (80.200.28.28) direkt yn 'e hostnamme - in werkenbere konvinsje foar dy tsjinst. De operator rotearret it willekeurige subdomeinprefiks tusken ferzjes om naive domeinblokkearlisten te ûntkommen, mar it ûnderlizzende IP-adres ferpleatst nea. (krijt-sjabloan: 1.0.14 used 8a3e818ea8f11186-80-200-28-28…; 1.0.16 / 1.0.19 / 1.0.20 gebrûk f04a273bd84c0622-….)
postinstall.js hannen ôf foar fantoom.js, in bondele "kollektor"-module fan 7,667 rigels. fantoom.js rint de gasthear foar:
SSH privee kaaien (~/.ssh/*) |
.npmrc ynhâld en alle npm_* env-tokens |
| AWS-, GCP- en Azure-gegevensbestannen |
GitHub persoanlike-tagongstoken regex (ghp_*, gho_*, ghu_*, ghs_*) |
| Krypto-wallet-artefakten foar Bitcoin, Exodus, Electrum, Monero, Litecoin, Dogecoin, Zcash, Dash |
In rekursive .env* trochrinne ~/projects, ~/dev, ~/code, ~/workspace, en de ynstallaasje cwd |
Shell-skiednis en de folsleine process.env |
De bondel wurdt nei de Serveo-tunnel POST om /sammeljeDer is gjin fertsjustering, gjin anty-VM-logika, gjin staging - de operator weddenskip giet oer folume en snelheid.
Faze B — PhantomBot DDoS-rekrutearring (2026-05-17, allinich axois-utils: 1.0.9)
Faze B ferfangt phantom.js + postinstall.js mei ien bestân mei de namme distrube.js (de typfout is dy fan 'e operator). De triple-hook scaffold yn package.json is net feroare; it pakket hâldt deselde namme, omfang en ferzje-bump patroan. Fan 'e bûtenkant liket axois-utils:1.0.9 in lytse opfolger fan 1.0.6. Binnenyn is it in oare malwarefamylje.
distrube.js iepenet mei in konfiguraasjeblok dat de eigen branding fan 'e operator neamt:
// 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')}`; |
De opmerkings binne rjochte oan in takomstige operator dy't de kit útfiert ("Brûk jo localhost.run HTTPS URL"). Dat, plus wat neist de botkliïnt komt, is it teken dat dit net allinich in slachtofferlading is - it is de kit.
De stream:
- Persistence rint earst. It skript ynstallearret himsels op trije ferskillende manieren per OS (register run + Opstartmap + sktasks op Windows; crontab + fantoom-bot.tsjinst systemd-ienheid + .bashrc/.zshrc taheakje + /etc/rc.local op Linux; LaunchAgent com.phantom.bot.plist op macOS). De namme fan 'e persistinsjetsjinst en it LaunchAgent-label binne beide fantoombot / com.phantom.bot, dêr't ek de namme fan 'e kampanje weikomt.
- Systeemynformaasje exfil rint ien kear - in ienmalige fingerprint POST nei b94b6bcfa27554.lhr.life:443/collect mei hostnamme, platfoarm, arch, brûkersnamme, CPU/RAM, netwurkynterfaces, process.env, cwd, homedir, nodeferzje en iepenbier IP. Dit is folle minder agressyf as Fase A: gjin SSH, gjin wallets, gjin .env-rekursje. De taak fan 'e bot is om yn te skriuwen, net om te stellen.
- Hertslachlus iepenet elke 30 sekonden in HTTPS POST nei b94b6bcfa27554.lhr.life:443/. De brûkersagent is PhantomBot/1.0. TLS-ferifikaasje is eksplisyt útskeakele (rejectUnauthorized: false). It C2-antwurd wurdt parsearre as JSON fan 'e foarm {type, target, port, duration, threads, method} en ferstjoerd.
- Oerstreamingsarsenaal is ferbûn mei seis kommando's:
| Kommando type | module | Notes |
|---|---|---|
| ping | Liveness antwurd | Bot identifisearret himsels |
| http | HTTP-oerstreaming | Laach-7 fersyk oerstreaming |
| https | HTTPS-oerstreaming | Itselde as http, TLS-ynpakt |
| tcp | TCP-oerstreaming | 65 KB willekeurige-payload spam |
| pud | UDP-oerstreaming | UDP-pakketten fan 65,507 bytes |
| fluch | HTTP/2 rappe-reset DoS | De 2023 CVE-2023-44487 technyk |
Alle fiif oerstreamingsmodules nimme in doel, haven, doer, en threads argumint - de bot is in generike hierde flooder, net rjochte op in bepaald slachtoffer. De slachtofferlist fan 'e operator stiet op 'e C2, net yn it pakket.
Wat is hjir nij - it ferstjoerde C2-binêre bestân
Faze A is in bekende foarm: diefstal fan ynloggegevens, ynstallaasjeheak, troch leveransiers tunnele C2. Faze B is ek in bekende foarm - DDoS-botnetten binne al jierren in fêst ûnderdiel fan kweade npm-pakketten. Wat ûngewoan is, is dat de operator de server kant fan 'e kit yn 'e npm tarball:
- c2 — in 4-megabyte kompilearre Go ELF binêre triem
- c2.go — de 426-regelige Go-boarne foar dat binêre bestân
Gjin fan beide triemmen wurdt oanroppen troch in ynstallaasjehook. Se binne gjin ûnderdiel fan 'e payload fan it slachtoffer. Se sitte yn 'e pakketmap op deselde wize as in dokumintaasjebestân soe dwaan. De meast oannimlike lêzing is dat de operator syn ûntwikkelingswurkbeam nei npm skood hat sûnder de triemlist te behearjen - in echte OpSec-slip - en wat levere is de folsleine twasidige kit: de kliïnt dy't in slachtoffer útfiert, en de server dy't de operator útfiert.
Dit is it diel fan it ferhaal dat it frame fan "turnkey botnet kit" rjochtfeardiget. Elkenien dy't it ynladen hat axois-utils:1.0.9 foar takedown hat net allinich in slachtoffermonster - se hawwe in wurkjende C2-tsjinner.
De draaipunt, yn ien sin
Deselde útjouwer, deselde pakketnammen, deselde triple-hook scaffold, deselde "phantom" branding - mar de lading feroare it monetarisaasjemodel oernachtich: fan "rispinge-geheimen dy't ik trochferkeapje kin" oant "hiere oerstreamingskapasiteit dy't ik lease kin". De TTP's foar ynstallaasjetiid dy't ferdigeners yn 'e gaten moatte hâlde binne hast identyk yn beide fazen; hantekening-basearre ferdigeningswurken dy't keppele binne oan 'e wallet-padstrings fan Fase A of oan fantoom.js's 7,667-rigels tellende samler soe Fase B folslein mist hawwe.
| Datum (UTC) | Barren |
|---|---|
| 2026-05-15 | Earste publikaasje: axois-utils:1.0.4 (LAN-testbou, ûntwikkelingsrig by 192.168.129.19) |
| 2026-05-15 | axois-utils:1.0.6 publisearre — Fase A C2 omwiksele nei 80.200.28.28 fia de Serveo-tunnel; de boarnekommentaar // Change to '80.200.28.28' for public befêstiget de dev→prod-wikseling |
| 2026-05-16 | chalk-tempalte:1.0.14 en 1.0.16 publisearre - keatlinglader ferklearje axois-utils:^1.0.7 as in runtime-ôfhinklikens; Serveo-subdomein rotearre |
| 2026-05-16 | Fase A-kampanje ûntdutsen tidens routine npm-scannen; befêstige-kwaadwillige útspraken tapast |
| 2026-05-17 | axois-utils:1.0.9 publisearre — payload pivot: PhantomBot DDoS rekrutearret fia localhost.run tunnel; operator-side c2 binêre en c2.go boarne ferstjoerd yn tarball |
| 2026-05-17 | chalk-tempalte:1.0.19 en 1.0.20 publisearre — noch altyd Fase A (steller); operator rint no beide modules parallel út |
| 2026-05-17 | Untdekking fan Fase B tidens routine scanning; útspraken tapast op alle 2026-05-17 ferzjes |
| (oanhâldend) | Ferwideringsrapporten yn ôfwachting; alle fjouwer publisearre pakketten bliuwe op it momint fan skriuwen beskikber yn it register |
Yndikatoaren fan kompromis
Packages
| Ekosysteem | Pakket | versions |
|---|---|---|
| npm | axois-utils (typosquat fan axios) | 1.0.4, 1.0.6, 1.0.9 |
| npm | chalk-tempalte (typosquat fan krytsjabloan) | 1.0.14, 1.0.16, 1.0.19, 1.0.20 |
Auteuridentiteit
| Fjild | Wearde |
|---|---|
| npm-útjouwer | deadcode09284814 |
| E-postadres fan 'e útjouwer | phantomdeadcode@tutamail.com |
| SCM ferifikaasje | gjin |
Kommando-en-kontrôle
| Faze | Endpoint | ferfier |
|---|---|---|
| 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 (eardere ferzje) |
| A | 80.200.28.28:443/collect | Underlizzende VPS-eindpunt |
| B | b94b6bcfa27554.lhr.life:443/ | localhost.run HTTPS reverse-tunnel |
Triemferdielingen (SHA-256)
| file | SHA-256 | Notes |
|---|---|---|
c2 (Gean ELF, 4 MB) | 165fa92d237fd017c227d00da06ab788212a62be94bf61e95df2d22d00377ef2 | Operator-side C2-tsjinner, binnen ferstjoerd axois-utils:1.0.9 |
c2.go (426 rigels) | 7d0ae79fdb1e9968f3323a3712b624643a782ba3efb2cf3a2cb9c4c5513cea30 | Gean nei de boarne foar de C2-binêre |
distrube.js | 308b15c023088a7188dea4ef609010ac2493eb4c365b103053d7621a9ca5b935 | Faze B botkliïnt |
phantom.js (chalk-tempalte:1.0.19) | 9e380ec88d3ccf3929e1a104e3b868d4d7b59ca189a8a431a54e9f3357dfdd81 | Fase A-akkreditaasje / walletkollektor |
phantom.js (chalk-tempalte:1.0.20) | d1c9e3f296ee9f7d5032f73f9c504cede50334bc14c394055fd5cb9c3a6e08b3 | Fase A-kollektor (fariant 1.0.20) |
postinstall.js (chalk-tempalte:1.0.19 = 1.0.20) | ffba9bdd6793edd5b38e12900252c1813a693f59c25af51c3b658cf3f27b6162 | Fase A lader, byte-identyk oer beide ferzjes |
Attribúsje en motivaasje
Wy folgje dizze kampanje as PhantomBot, it eigen branding fan 'e operator oernimmend fan 'e Brûker-Agent: PhantomBot/1.0 hertslachkoptekst, de fantoom-bot.tsjinst systemd-ienheid, de com.phantom.bot LaunchAgent-label, en de fantomdeadkoade@ e-postadres. De operator is konsekwint oer dizze namme oer teminsten fjouwer artefakten.
Sinjalenkatalogus
- Útjouwer - deadekoade09284814 op npm. Akkoant mei ien handgreep, Tutamail wegwerp-e-post, nee SCM ferifikaasje. Gjin eardere publikaasjeskiednis neist dizze kampanje.
- Werbrûk fan branding — “phantom” ferskynt yn 'e e-post fan 'e útjouwer, yn 'e bestânsnamme fan 'e samler fan Fase A (fantoom.js), yn 'e namme fan 'e persistinsjetsjinst fan Fase B (fantoom-bot.tsjinst), yn it LaunchAgent-label (com.phantom.bot), en yn 'e bot Brûkersagent (PhantomBot/1.0).
- ynfrastruktuer — Ien VPS by 80.200.28.28 frontet Fase A fia Serveo subdomeinrotaasje; Fase B ferpleatst nei in lokalehost.run omkearde tunnel (b94b6bcfa27554.lhr.libbenBeide leveransierstsjinsten binne fergees en fereaskje allinich útgeande SSH oan 'e kant fan' e operator, yn oerienstimming mei leechbudzjet- en leech-OpSec-ynstellingen.
- koade styl — Gewoane JavaScript troch it hiele systeem; gjin obfuskaasje, gjin tekenrigekodearring, gjin anti-VM-kontrôles. Fariabelenammen binne beskriuwend (stealSysteemYnfo, útfiereKommando, httpFlood). Reaksjes yn distrube.js direkt in takomstige operator oansprekke ("Brûk jo localhost.run HTTPS URL"), wat suggerearret dat it bestân bedoeld wie om opnij ferspraat te wurden as in kit, net brûkt troch ien oanfaller.
- OpSec-slip — De Fase B tarball ferstjoert sawol de botkliïnt as de C2-tsjinner oan 'e operatorkant (c2 ELF + c2.go boarne). Dit komt oerien mei in operator dy't syn wurkbeam nei npm hat skood sûnder de triemlist te kontrolearjen. Of de operator is ûnerfaren, of de kit is betsjutte om iepenbier ferspraat te wurden en de C2-binêre is ûnderdiel fan it produkt.
- Selsbefêstiging - axois-utils:1.0.4 befettet de boarnekommentaar // Wizigje nei '80.200.28.28' foar it publyk op rigel 12, en befêstiget de ûntwikkelings-/staging-/produksjeprogresje dy't operators typysk ûntkenne.
Motivaasje
De lading fan Fase A is ienfâldige finansjele diefstal: ynloggegevens, wolksleutels, GitHub-tokens en krypto-wallets hawwe allegear floeibere werferkeapmerken. Fase B is ek finansjeel, mar yndirekt: DDoS-te-hier ("booter") tsjinsten hiere oerstreamingskapasiteit per minút, en bots lykas dy hjir ferstjoerd binne de ynventaris wêrop dy tsjinsten rinne. De hertslach fan 30 sekonden, de generike doel/haven/doer kommandoskema, en it fiif-protokollen oerstreamingsarsenaal binne de standard produkt fan in booter-operator.
Beide modules parallel útfiere - krijt-sjabloan: 1.0.19 en 1.0.20 trochgean mei it ferstjoeren fan 'e stealer wylst axois-utils:1.0.9 ferstjoert de bot - suggerearret dat de operator ynkomstenstreamen ôfdekt ynstee fan Fase A te ferlitten. De pivot is in Dêrneist, gjin ferfanging.
Wat wy net beweare
Wy hawwe gjin echte identiteit efter de befêstigje kinnen deadekoade09284814 handle, en wy skriuwe dizze kampanje net ta oan in neamde bedrigingsakteur, groep of lân. De "fantoom"-branding is konsekwint genôch oer artefakten om ien operator te suggerearjen, mar de kit-styl ferstjoering fan 'e C2-binêre lit de mooglikheid iepen dat takomstige pakketten fan net-relatearre handles deselde koade opnij brûke sille.
Ynfloed, trends en wat ferdigeners dwaan moatte
Impact
De legitime squat-doelen axios en krijt-sjabloan binne breed ôfhinklik fan yn it JavaScript-ekosysteem; axios allinnich al stiet ûnder de tritich meast downloade npm-pakketten. De typosquat-nammen binne ien toetsoanslach fuort fan 'e echte (axois ↔ axios, sjabloan ↔ template), en beide binne taalkundich oannimlike spellingsflaters.
Wy koenen gjin betroubere downloadstatistiken krije foar de kweade ferzjes foar it fuortheljen - npm hâldt gjin downloadtellingen per ferzje by nei't in pakket net publisearre is, en npms.io-styl proxy's binne lawaaierich op dizze skaal. Elke organisaasje waans lockfile oplost nei in pakket mei de namme axois-utils or krijt-sjabloan fan útjouwer deadekoade09284814 moat behannele wurde as kompromittearre: rotearje elke oanwêzige ynloggegevens yn proses.omjouwing op 'e troffen host, kontrolearje persistinsjefektorren per OS (sjoch "Wat ferdigeners moatte dwaan" hjirûnder), en ferwiderje de ôfhinklikens.
Opkommende patroanen
Dizze kampanje is in foarbyld fan in ferskowing dy't wy sjoen hawwe yn ferskate resinte npm-ynsidinten: de ynstallaasje-haak steiger is it duorsume asset; de lading is útwikselberDeselde útjouwer, itselde pakket, itselde foarôf ynstallearje / ynstallearje / nei ynstallaasje trijefâldich, en sels deselde ferzje-bump kadens - it ienige ding dat feroare tusken axois-utils:1.0.6 en axois-utils:1.0.9 wie it bestân de hooks rinne. Deteksje basearre op hantekeningen dy't tawiisd is oan de lading fan Fase A (strings fan it wallet-pad, fantoom.js's 7,667-rigels tellende samler, de Serveo C2-host) soe de earste trije ferzjes markearre hawwe en Fase B folslein mist hawwe.
Itselde patroan is sichtber yn oare kampanjes fan 2026 dy't wy folge hawwe: ien operator mei in stabile steiger, wikseljend tusken diefstal fan ynloggegevens, kliïnten dy't eksamens bedrochje, Telegram-bot exfil, en no DDoS-rekrutearring. Ferdigeners dy't fertrouwe op payload-hântekeningen sille de twadde ronde fan elke kampanje ferlieze.
De gefolch is dat TTP's op ynstallaasjetiid binne it bettere sinjaalTrijefâldige ynstallaasje-hook-ferklearrings, ynstallaasjeskripts dy't ymportearje https or bern_proses, ynstallearje skripts dy't skriuwe nei brûkersopstartmappen, en ynstallearje skripts dy't hostnammen oplosse op fergese reverse-tunnel-tsjinsten (Serveo, lokalehost.run, ngrok, cloudflared) binne allegear seldsum yn legitime pakketten en gewoan by kweade pakketten.
Wat ferdigeners dwaan moatte
- Kontrôle fan Lockfile. Sykje elke package-lock.json / garen.slot / pnpm-lock.yaml yn jo organisaasje foar de krekte strings axois-utils en krijt-sjabloanBehannelje elke wedstriid as in kompromis.
- Geheimen draaie op troffen hosts. Faze A bulk-rispte SSH-, wolk-, GitHub-, npm- en wallet-gegevens. Nim oan dat alle gegevens dy't ea oanwêzich binne yn proses.omjouwing, ~ / .ssh, ~/.aws, ~/.npmrc, ~/.config, as ien .omjouwing* bestân op 'e troffen host wurdt bleatsteld.
- Ferwiderje persistinsje (Faze B). Op Windows, wiskje HKCU\Software\Microsoft\Windows\Aktuele ferzje\Run\SystemUpdate, weinimme %APPDATA%\Microsoft\Windows\Startmenu\Programma's\Opstart\system-update.bat, en schtasks /wiskje /tn Systeemfernijing /fOp Linux, crontab -e en fuortsmite @reboot-knooppunt …, systemctl –brûker útskeakelje –no phantom-bot.service dan wiskje ~/.config/systemd/brûker/phantom-bot.tsjinst, scrubje .bashrc / .zshrc / /etc/rc.localOp macOS, launchctl ûntladen ~/Biblioteek/LaunchAgents/com.phantom.bot.plist wiskje dan de plist.
- Blokkearje de C2-hosts. Foegje de fjouwer C2-einpunten yn 'e IOC-tabel ta oan jo útgongsblokkearlist. *.serveousercontent.com en *.lhr.libben kin yn grutte getallen blokkearre wurde as jo omjouwing gjin legitime gebrûk hat foar reverse-tunnel-tsjinsten.
- Sykje op ynstallaasjetiid TTP, gjin lading. Ynventaris lockfile-yngongen waans pakket.json ferklearre foarôf ynstallearje, ynstallearje, en nei ynstallaasje allegear wizend nei itselde skript. Kontrolearje tsjin pakketleeftyd en ferifikaasjestatus fan útjouwer. Dit patroan is seldsum yn legitime pakketten en is it ienige meast betroubere sinjaal dat PhantomBot opnij brûkt.
- Audit foar it C2-binêre. Elkenien dy't downloade hat axois-utils:1.0.9 hat de C2-tsjinner fan 'e operator (c2 ELF, sha256 165fa92d…) op skiif. Scan caches en CI-artefaktopslaggen. De binêre funksje is op himsels sliepend, mar syn oanwêzigens op in wurkstasjon is ûndûbelsinnich bewiis dat it pakket ynstalleare is.
Slutline
Deselde operator, itselde pakket, en deselde ynstallaasjehook kinne binnen 48 oeren folslein ferskillende bedrigingen leverje. Let op it scaffold, net op de lading.




