PhantomSync: npm krypto balíčky, skrývá zloděje peněženek

PhantomSync: osm npm balíčků pro vývojáře kryptoměn skrývá zpožděný, samovolně se ukládající dropper

TL, DR

Jeden vydavatel NPM vydal osm malých balíčků, jejichž názvy znějí jako každodenní stavební kameny pro vývoj blockchainu a peněženek. base58-utils, abi-encode, eth-dev, arb-kit, layer2-sdk, solana-key-utils, eth-wallet-helpers, a crypto-validate-libKaždý z nich obsahuje funkční utilitu. Za touto utilitou je však připojen samovolný blok kódu, který se spustí v okamžiku importu modulu.

Zhruba 37 sekund po importu, tento blok dekóduje datovou část, která se dodává uvnitř balíčku maskovaná jako testovací zařízení, zapíše ji do skrytého souboru v domovském adresáři uživatele a zaregistruje se k restartu při každém login ve Windows, macOS a Linuxu a spouští dekódovaný skript jako oddělený proces. Během instalace npm se nic nespustí; čeká se na import a spuštění kódu, což je klidnější okamžik než samotná instalace.

Užitečná zátěž není neprůhledná. Dodává se jako prostý base64, takže dekódování „testovacího zařízení“ obnoví druhou fázi v plném rozsahu: a krypto peněženka a zloděj tajemství který čeká, až bude stroj nečinný, shromažďuje soukromé klíče a seed fráze, šifruje každý nalezený klíč pevně zakódovaným klíčem RSA-4096 a exfiltruje jej jeho připnutím k veřejnému úložišti IPFS, přičemž se každých 12 hodin odesílá zpět.

Sledujeme shluk jako PhantomSyncVšech osm balíčků bylo v době analýzy aktivních v registru npm a publikovaných pod jedním účtem.

EkosystémNpm
Balíčkybase58-utils, abi-encode, eth-dev, arb-kit, layer2-sdk, solana-key-utils, eth-wallet-helpers, crypto-validate-lib
Cílové platformyWindows, MacOS, Linux
Základní chováníZpožděný dropper v době importu skrytý jako testovací přípravek; instaluje perzistenci napříč platformami
Užitné zatíženíKrypto peněženka a zrádce tajných dat, šifrování RSA-4096, exfiltrace přes veřejné pinování IPFS

Anatomie útoku

Každý balíček na první pohled vypadá nenápadně. base58-utilityje například několik kilobajtů pomocného kódu Base58 / Bitcoin-WIF s nulovou závislostí – přesně to, co název slibuje. Příslušný kód se nachází po modulu modul.exports, kam se čtenář prohlížející začátek souboru pravděpodobně nepodívá: samovolající funkce, která se sama plánuje pomocí časovače.

Řetězec operací, rekonstruovaný ze zdrojového kódu balíčku, probíhá takto:

1. Package is required() by the host project
2. A self-invoking function schedules a callback ~37,000 ms later (setTimeout)
3. On fire, the callback reads test/fixtures/keypairs.dat (a base64 blob)
4. It base64-decodes that blob into a Node.js script
5. It writes the script to ~/.cache-db/.node-sync/syncd.js (mode 0o700)
6. It installs login-persistence for that script (see below)
7. It spawns "node syncd.js" as a detached process

Vynikají dvě designové možnosti.

Užitečné zatížení se pohybuje jako testovací přípravek. Druhá fáze není napsána jako zřejmý kód. Je v ní obsažena test/fixtures/keypairs.dat, soubor base64, jehož název se splývá s balíčkem, který tvrdí, že zvládá páry klíčů. Pro člověka prohlížejícího tarball to vypadá jako vzorová data; pro připojený kód je to skript k dekódování a spuštění. Samotný dropper neobsahuje žádnou síťovou adresu – ty se nacházejí ve druhé fázi – ale neexistuje žádné další zmatkování: fixture je jedna vrstva base64, takže jeho dekódování (base64 -d) obnoví celou syncd.js a jeho chování v síti. Následující část se zabývá tím, co tato obnovená fáze dělá.

Detonace je zpožděná a vázána na dovoz, nikoli na instalaci. Protože spouštěčem je vyžadovat() plus ~37sekundový časovač namísto instalačního hooku, toto chování obchází kontroly, které sledují pouze npm install krok a zpoždění trvá déle než mnoho krátkodobých běhů v sandboxu a CI. Než se cokoli spustí, instalace, která balíček stáhla, je už dávno dokončena.

Jakmile je dekódovaný skript na disku v ~/.cache-db/.node-sync/syncd.js — cesta zvolená tak, aby se četla jako běžný adresář mezipaměti — dropper umožňuje přežít restartování na všech třech hlavních platformách:

  • Linux: položka cron, která restartuje skript. Položka se nainstaluje filtrováním existujícího crontabu přes grep -v syncd, což má vedlejší účinek, že se nová položka vynechá z prostého výpisu, který grepuje pro stejný název.
  • Windows: naplánovaný úkol s názvem WinNodeSync, nastavené na reprízu v 12minutovém intervalu.
  • MacOS: úloha launchd s označením com.apple.syncd, přítomný v několika balíčcích – označení, které napodobuje legitimní systémovou službu Apple.

Skript se poté okamžitě spustí jako oddělený proces, takže po ukončení importujícího programu pokračuje v běhu.

Co dělá druhá fáze

Protože zařízení má jednu vrstvu base64, druhý stupeň dekóduje čistě a lze jej přečíst v plném rozsahu. Všech osm balíčků obsahuje jednu ze tří variant stejného skriptu, který se v komentáři záhlaví identifikuje jako phantom syncd v3 — topo durmiente („spící krtek“). Jeho úkolem je krást materiály kryptoměnové peněženky a vývojářská tajemství a odesílat je ze stroje. Probíhá v těchto krocích:

  • 1. Počkejte, dokud se stroj nepřepne do klidového stavu. Než cokoli uděláte, syncd.js kontroluje, jak dlouho je uživatel neaktivní, a pokračuje až po určité prahové hodnotě (kolem 15 minut) – xprintidle na Linuxu, ioreg HIDIdleTime v systému macOS a dotaz PowerShellu v době nečinnosti ve Windows. Sběr dat proto obvykle probíhá, když nikdo není u klávesnice.
  • 2. Přineste dálkově ovládaný aktivační spínačSkript si před provedením akce stáhne malou konfiguraci z deaddropu. Primárním zdrojem je nezpracovaná URL adresa souboru Gist z GitHubu (gist.githubusercontent.com/juang55/…/cfg.txt); skript se aktivuje pouze tehdy, pokud tato konfigurace přečte aktivní=1Pokud není obsah dostupný, vrátí se zpět ke třem pevně zakódovaným identifikátorům obsahu IPFS, které jsou načteny prostřednictvím veřejných bran. gateway.pinata.cloud, ipfs.io, a cloudflare-ipfs.comTo dává operátorovi možnost dodatečného ovládání/odepnutí a záložní možnost odolnou proti zneškodnění. (Nejmenší varianta, dodávaná v crypto-validate-lib, pomocníci s eth-peněženkami, a solana-key-utils, má odstraněnou vrstvu GIST a spoléhá se pouze na identifikátory IPFS.)
  • 3. Sbírejte materiál a tajemství peněženky. Skript prochází domovský adresář uživatele — ~/.config/solana, ~/.ethereum/úložiště klíčů, ~/.foundry, ~/.ochranná přilba, ~ / .ssh, a Desktop/Dokumenty/Počet stažení (včetně názvů složek ve španělštině) a navíc ~/.env a soubory rc prostředí Shell a ekvivalentní AppData umístění ve Windows. Zaměřuje se na soukromé klíče Etherea, klíče Bitcoinu WIF, seed fráze BIP-39, páry klíčů Solana, JSON úložiště klíčů Etherea, klíče SSH a proměnné prostředí s tajnými kódy. Větší varianta (v abi-kódování, base58-utility, eth-dev) obsahuje kompletní slovník BIP-39 s 2048 slovy a používá regulární výrazy k extrakt jednotlivé klíče a ověřené základní fráze z jakéhokoli textu, který přečte; dvě menší varianty místo toho porovnávají soubory podle klíčového slova (semínko, mnemotechnická pomůcka, peněženka, metamask, přízrak, účetní kniha, trezor, …) a nahrávat celé soubory.
  • 4. Zašifrujte a exfiltrujte pomocí veřejné služby pro připínání. Každý nález je spojen s otiskem hostitele (uživatelské_uživatel@název_hostitele, platforma, časové razítko) a zašifrovaný pomocí pevně zakódovaného veřejného klíče RSA-4096 vloženého do skriptu. Zašifrovaný záznam je poté nahrán jeho připnutím k IPFS prostřednictvím api.pinata.cloud/pinning/pinJSONToIPFS, ověřeno pomocí pevně zakódovaných přihlašovacích údajů Pinata API. Neexistuje žádný speciální server C2, který by bylo možné zabavit: ukradená data jsou uložena ve veřejném decentralizovaném úložišti, odkud je operátor může získat pomocí výsledných hashů obsahu. Nahrávání je rozloženo s několika sekundami náhodného chvění a lokální protokol časové razítko | typ klíče | vrácený hash je uchováván v ~/.cache-db/.node-sync/.sl.
  • 5. Vytrvejte a vysílájte signály v 12hodinovém cyklu. Druhá fáze obnovuje vlastní perzistenci – položku cron v Linuxu, com.apple.syncd úloha launchd v systému macOS a naplánovaná úloha s názvem WindowsNodeSync ve Windows – nastaveno na opětovné spuštění každých 12 hodin. Upozorňujeme, že se jedná o odlišný Název úlohy systému Windows z té, kterou instaluje dropper (WinNodeSync); obojí stojí za to hledat.

Timeline

Osm balíčků bylo publikováno v krátkém čase 13. a 14. 7. 2026. Některé z nich obsahují více než jednu verzi; dropper je ve všech verzích identický, pouze offsety řádků se mění s tím, jak se mění velikost neškodného utility kódu nad ním.

Datumudálost
2026-07-13První balíčky v clusteru se objeví pod jedním vydavatelem (solana-key-utils, eth-wallet-helpers, crypto-validate-lib a rané verze zbytku)
2026-07-13 → 07-14Zbývající názvy a následné verze zveřejněny; stejné připojené dropper lodě v každém
2026-07-14Všech osm označeno a analyzováno; každý balíček je stále nainstalovatelný z registru

Během celého období se reputace vydavatele v registru změnila z přibližně neutrální na začátku clusteru na silně negativní s postupným narůstáním detekcí – což byl pozorovatelný vedlejší účinek označování balíčků, nikoli záměrná funkce.

Ukazatele kompromisu

Všechny níže uvedené indikátory byly v době analýzy potvrzeny jako přítomné – ty v tabulkách „Druhé fáze“ – dekódováním test/fixtures/keypairs.dat a čtení získaných dat syncd.js.

Soubory a cesty

IndikátorRole
~/.cache-db/.node-sync/syncd.jsDekódovaný druhý stupeň, zapsaný v módu 0o700
~/.cache-db/.node-sync/.slLokální protokol exfiltrace (časové razítko | typ klíče | hash IPFS)
test/fixtures/keypairs.datDatové zatížení kódované v Base64 je uloženo uvnitř tarballu jako „testovací zařízení“

Síťová infrastruktura druhé fáze (obnovená ze syncd.js)

IndikátorRole
gist.githubusercontent.com/juang55/b298754cb72942b1cdcf02ccd45cde2f/raw/cfg.txtAktivační deaddrop; skript se spustí pouze v případě, že konfigurace přečte active=1
Qmcqz3w8j4qFQXDAXAxnrdc2oSX3nzBT4NqtpTqL8mr1gaZáložní konfigurace IPFS (CID)
QmdTXoqVmTHY1i4ZWLdLkoQ9YChp5TXPh5cWXwnAYZt5iFZáložní konfigurace IPFS (CID)
QmfJkLU5gdCpqbbqEjWYC2anXW9FmuEeSLLeLiHVJKYUjpZáložní konfigurace IPFS (CID)
gateway.pinata.cloud, ipfs.io, cloudflare-ipfs.comBrány IPFS používané k načtení záložní konfigurace
api.pinata.cloud/pinning/pinJSONToIPFSKoncový bod exfiltrace, ukradená data připnutá na veřejný IPFS
Klíč API Pinata13c766575b9270a9825d, pevně zakódované pověření pro exfiltraci

Cíle kolekce druhé fáze (obnovené ze syncd.js)

IndikátorRole
~/.config/solana, ~/.ethereum/keystore, ~/.foundry, ~/.hardhat, ~/.ssh, ~/.env, soubory rc shelluAdresáře/soubory prohledávané kvůli klíčům a tajným klíčům
AppData\Roaming\Solana, AppData\Local\ethereum\keystoreVyhledané ekvivalenty ve Windows
Typy získaných artefaktůSoukromé klíče ETH, Bitcoin WIF, seed fráze BIP-39, páry klíčů Solana, JSON úložiště klíčů Ethereum, SSH klíče, tajné proměnné prostředí

Artefakty perzistence

PlošinaIndikátor
Linuxspuštění cronu syncd.js; nainstalováno přes crontab, filtrováno skrz grep -v syncd
Windowsnaplánovaný úkol WinNodeSync (kapatka) a WindowsNodeSync (druhá fáze)
macOSlaunchd štítek com.apple.syncd
Vše Druhá fáze se opakuje v 12hodinovém cyklu.

Behaviorální

  • Samovolná funkce připojená za modul.exports, plánování setTimeout ~37 000 ms při importu.
  • podřízený_proces spawn(„uzel“, ) s oddělenou sadou možností.
  • Aktivace s volnoběhem ve druhé fázi (xprintidle / ioreg Doba nečinnosti HIDIdleTime / PowerShellu; prahová hodnota ~15 minut).
  • Šifrování RSA-4096 na základě nalezení a poté HTTPS POST k veřejnému API pro připínání IPFS.

Balíčky a verze (npm, vydavatel solbuilder_io)

Balíčekverze
base58-utils1.0.0, 1.0.1, 1.0.3
abi-encode1.0.0, 1.0.1, 1.0.2
eth-dev1.0.0, 1.0.1, 1.0.2
arb-kit1.0.0, 1.0.1
layer2-sdk1.0.0, 1.0.1
solana-key-utils1.0.0
eth-wallet-helpers1.0.0
crypto-validate-lib1.0.0

Vydavatel

  • solbuilder_io - angel_lopez89[@]proton[.]já, neověřený e-mail, žádný ověřený účet pro správu zdrojového kódu, žádné propojené repozitář.

Atribuce a pozorované chování

Osm balíčků sdílí jeden účet vydavatele a jeden datový obsah. Každý z nich je triviální balíček – několik kilobajtů skutečného užitného kódu se stejným připojeným dropperem – publikovaný bez propojeného repozitáře a pod neověřeným e-mailem v jednorázovém stylu. Tato jednotnost, sdílená cesta pro dropování, sdílené popisky perzistence a sdílené… keypairs.dat stagingové soubory spojují cluster dohromady.

Balíčky jsou ohledně svého vlastního chování neobvykle upřímné. solana-key-utils obsahuje vložené komentáře, které popisují připojený blok jednoduchým způsobem – označí se FANTOM: neviditelná vytrvalost, další (ve španělštině) zní Vyjmout topografii na pozadí, „spustit krtka na pozadí.“ Toto jsou vlastní anotace kódu k tomu, co dělá; název kampaně v tomto příspěvku je převzat z prvního popisku spolu s falešným uzlem „sync daemon“ (synchronizováno), kterou napodobuje perzistenční mechanismus.

Popisujeme pouze to, co kód dělá pozorovatelně. Pojmenování balíčků – všechny se týkají kryptoměn, peněženek a blockchainových nástrojů – naznačuje, kdo si je s největší pravděpodobností stáhne; samo o sobě to neurčuje, kdo je vydavatelem. Druhá fáze byla plně obnovitelná dekódováním fixture base64 a její chování je popsáno výše: shromažďuje klíče od peněženky, seed fráze a tajné kódy a přesune je, šifrované pomocí RSA, do veřejného úložiště IPFS prostřednictvím služby Pinata. Pozoruhodnou konstrukční volbou je absence soukromého serveru C2 – konfigurace přichází z GitHub Gist a IPFS a ukradená data jsou parkována ve veřejném decentralizovaném úložišti s klíčem hash obsahu, přičemž obojí je obtížnější získat než jeden hostitel ovládaný útočníkem. V době psaní tohoto článku nebyly nalezeny žádné předchozí veřejné zprávy odpovídající tomuto klastru.

Dopad, trendy a pokyny pro obránce

Kdo je odhalen. Každý, kdo přidal jeden z těchto balíčků do projektu Node a poté spustil kód, který jej importuje. Protože detonace probíhá spíše v době importu než instalace, pouhá přítomnost balíčku nestačí – ale jakékoli běžné použití, které načte modul, dosáhne jeho užitečného zatížení. Názvy lákadel cílí na vývojáře, kteří staví na Ethereu, Solaně, Arbitru, Layer-2 a obecných nástrojích pro peněženky/kódování – populaci, která s největší pravděpodobností vlastní přesně ta aktiva, která druhá fáze hledá. Každý, kdo spustil jeden z těchto modulů na počítači s klíči k peněžence, seed frázemi, úložišti klíčů, SSH klíči nebo… .env Tajné údaje by měly s těmito přihlašovacími údaji zacházet jako s kompromitovanými a střídat je.

Dva vzorce, které stojí za to internalizovat. Za prvé, užitečné zatížení jako upínací prvek: odeslání druhé fáze jako base64 uvnitř datového souboru s věrohodným názvem (test/fixtures/keypairs.dat) udržuje viditelný zdroj balíčku v čistotě a škodlivý obsah ukládá do souboru, který kontrolní nástroje a lidské prohledávače často považují za inertní data. Za druhé, zpožděné spuštění importu s perzistencí napříč platformamiPřesunutí spouštěče z instalačního hooku, přidání časovače a jeho následné zachování v cronu, naplánovaných úlohách a launchd je záměrný krok od hlučnějších technik instalačních skriptů, které automatizované skenování registru sleduje nejpečlivěji.

Pokyny pro obránce a správce:

  • Ošetřit připojený kód po modul.exports jako priorita při revizi – logika dropperu se často skrývá pod „skutečným“ povrchem modulu.
  • Nepředpokládejte, že datové soubory jsou inertní. Objekt base64 blob pod test/přípravky/ který je čten za běhu a dekódován, je přilehlý ke spustitelnému souboru; označit běhové čtení souborů fixtures, které poskytují funkce/eval/napiš-pak-potěr řetěz.
  • Hledejte cestu k pádu ~/.cache-db/.node-sync/ a pro jednotky perzistence WinNodeSync (naplánovaný úkol) a com.apple.syncd (launchd) na vývojářských počítačích, které tyto názvy stáhly.
  • Upozornění na procesy Node, které vytvářejí položky cron, naplánované úlohy nebo úlohy launchd – legitimní knihovny to při importu dělají jen zřídka.
  • Upřednostňujte lockfiles a pinned verze a zkontrolujte rozdíly u všech nových malých „utilit“ závislostí, zejména publikované balíčky s nulovou závislostí neověřenými účty bez propojeného repozitáře.

Pro obránce registru je důležité si uvědomit, že monitorování instalačních hook je nezbytné, ale ne postačující: dropper s časovačem zpožděným v době importu, umístěný uvnitř datového souboru, projde kontrolou pouze v době instalace a krok perzistence je často nejhlasitějším pozorovatelným signálem, který je třeba zachytit.

nástroje pro analýzu složení softwaru SCA
Stanovte priority, opravte a zabezpečte svá softwarová rizika
Získejte svůj bezplatný účet.
Nevyžaduje se žádná kreditní karta.

Zajistěte si vývoj a dodávky softwaru

s produktovým balíčkem Xygeni