PhantomSync: npm крипто пакетите го кријат крадецот на паричник

PhantomSync: осум npm пакети за крипто-развивачи кријат одложен, самоупорен dropper

TL; ДР

Еден npm издавач испрати осум мали пакети чии имиња се читаат како секојдневни градежни блокови за развој на блокчејн и паричник, base58-utils, abi-encode, eth-dev, arb-kit, layer2-sdk, solana-key-utils, eth-wallet-helpers, и crypto-validate-libСекоја од нив содржи функционална алатка. Сепак, по таа алатка се додава блок од код што се самоповикува и се извршува во моментот кога модулот е импортиран.

Приближно 37 секунди по увозот, тој блок декодира товар што се испраќа во пакетот преправен како тест-фикс, го запишува во скриена датотека под домашниот директориум на корисникот, се регистрира себеси за рестартирање на секој login низ Windows, macOS и Linux, и ја стартува декодирана скрипта како одвоен процес. Ништо во врска со ова не се активира за време на инсталацијата на npm; чека кодот да се увезе и изврши, што е потивок момент од инсталацијата.

Товарот не е непроѕирен. Се испорачува како обична base64, па декодирањето на „тест фитилот“ го обновува вториот степен во целост: a крипто-паричник и крадец на тајни што чека машината да остане неактивна, собира приватни клучеви и seed фрази, го шифрира секое откритие со тврдокодиран RSA-4096 клуч и го ексфилтрира со прикачување на јавно IPFS складирање, враќајќи се на секои 12 часа.

Го следиме кластерот како ФантомСинкСите осум пакети беа активни во регистарот на npm во времето на анализата, објавени под една сметка.

Екосистемnpm
делот пакетиbase58-utils, abi-encode, eth-dev, arb-kit, layer2-sdk, solana-key-utils, eth-wallet-helpers, crypto-validate-lib
Таргетирани платформиWindows, macOS, Linux
Основно однесувањеОдложен, паѓач на време на увоз скриен како тест уред; инсталации на повеќе платформи кои постојано се одржуваат
Корисни товарКрадец на крипто-паричник и тајни, RSA-4096 енкрипција, ексфилтрација преку јавно IPFS закачување

Анатомија на нападот

Секое пакување изгледа незабележително на прв поглед. base58-utils, на пример, е неколку килобајти помошен код Base58 / Bitcoin-WIF со нулта зависност - токму она што го ветува името. Релевантниот код се наоѓа по модулот модул.извоз, каде што читателот што го прелистува врвот на датотеката веројатно нема да погледне: функција што се повикува сама по себе и се закажува со тајмер.

Синџирот на операции, реконструиран од изворниот код на пакетот, работи вака:

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

Се издвојуваат две опции за дизајн.

Товарот патува како тест-фиксаж. Втората фаза не е напишана како очигледен код. Таа живее во test/fixtures/keypairs.dat, base64 датотека чие име се вклопува во пакет кој тврди дека обработува парови клучеви. За човек кој го прелистува tarball-от, изгледа како примероци на податоци; за додадениот код, тоа е скрипта за декодирање и извршување. Самиот dropper не содржи мрежна адреса - оние што се наоѓаат во втората фаза - но нема дополнително замаглување: фитинг е еден слој од base64, па затоа го декодира (база64 -d) го обновува целосното синхронизирано.js и неговото мрежно однесување. Следниот дел објаснува што прави таа обновена фаза.

Детонацијата е одложена и поврзана со увоз, а не со инсталација. Бидејќи активирачот е бара () плус тајмер од ~37 секунди наместо кука за инсталација, однесувањето ги заобиколува проверките што само го гледаат npm инсталирај чекор, а доцнењето трае подолго од многу краткотрајни sandbox и CI извршувања. Додека нешто се изврши, инсталацијата што го покрена пакетот е одамна завршена.

Откако декодираната скрипта ќе биде на дискот во ~/.cache-db/.node-sync/syncd.js — патека избрана да се чита како рутински кеш директориум — dropper-от го прави да преживее рестартирање на сите три главни платформи:

  • Linux: cron запис што ја рестартира скриптата. Записот се инсталира со филтрирање на постоечкиот crontab преку grep -v синхронизирано, што има несакан ефект на изоставување на новиот запис од обичен список што грепира за истото име.
  • Прозорци: закажана задача со име WinNodeSync, поставено да се повторува на секои 12 минути.
  • MacOS: лансирана работа означена со com.apple.syncd, присутен во неколку од пакетите - етикета што имитира легитимна системска услуга на Apple.

Скриптата потоа се стартува веднаш како одвоен процес, така што продолжува да работи откако ќе заврши програмата за увоз.

Што прави втората фаза

Бидејќи уредот е еден base64 слој, втората фаза се декодира чисто и може да се прочита во целост. Сите осум пакети носат една од трите варијанти на истата скрипта, која се идентификува во коментар во заглавието како фантомска синхронизација v3 — топо дурмиенте („заспан крт“). Неговата задача е да краде материјал од криптовалутен паричник и тајни од програмери и да ги испрати од машината. Работи во овие чекори:

  • 1. Почекајте додека машината не стане мирна. Пред да направите било што, синхронизирано.js проверува колку долго корисникот бил неактивен и продолжува само по одреден праг (околу 15 минути) — xprintidle на Линукс, иорег HIDdleTime на macOS и PowerShell барање во време на мирување на Windows. Затоа, собирањето податоци има тенденција да се случува кога никој не е на тастатурата.
  • 2. Земете прекинувач за активирање со далечинско управувањеСкриптата извлекува мала конфигурација од dead-drop пред да дејствува. Примарниот извор е необработена URL адреса од gist на GitHub (gist.githubusercontent.com/juang55/…/cfg.txt); скриптата се активира само ако таа конфигурација го чита активен=1Ако основната содржина е недостапна, се враќа на три хардкодирани IPFS идентификатори на содржина, преземени преку јавните портали. gateway.pinata.cloud, ipfs.io, и cloudflare-ipfs.comОва му дава на операторот контрола за вклучување/деоактивирање по настанот и резервна копија отпорна на соборување. (Најмалата варијанта, испорачана во крипто-валидација-либ, помошници-на-eth-паричник, и помошни алатки за клучеви-солана, го има отстрането gist слојот и се потпира само на IPFS идентификаторите.)
  • 3. Материјал и тајни за берба на паричник. Скриптата се движи низ домашниот директориум на корисникот — ~/.config/solana, ~/.ethereum/чување на клучеви, ~/.foundry, ~/.hardhat, ~ / .ssh, и Десктоп/Документи/Превземања (вклучувајќи имиња на папки на шпански јазик), плус ~/.env и shell rc датотеки, и еквивалентот Податоци за апликацијата локации на Windows. Целта е на приватни клучеви на Ethereum, WIF клучеви на Bitcoin, фрази за почетници BIP-39, парови клучеви Solana, JSON складиште за клучеви на Ethereum, SSH клучеви и променливи на околина што носат тајни. Поголемата варијанта (во abi-енкодирање, base58-utils, eth-dev) го содржи целиот речник BIP-39 од 2048 зборови и користи регуларни изрази за да екстракт индивидуални клучеви и валидирани почетни фрази од кој било текст што го чита; двете помали варијанти наместо тоа ги споредуваат датотеките по клучни зборови (семе, мнемоничен, паричник, metamask, фантомски, Леџер, trezor, …) и прикачете цели датотеки.
  • 4. Шифрирање и ексфилтрирање преку јавна услуга за прикачување. Секое откритие е спакувано со отпечаток од прст на домаќинот (корисничко име@име на домаќин, платформа, временска ознака) и шифрирани со тврдокодиран јавен клуч RSA-4096 вграден во скриптата. Шифрираниот запис потоа се прикачува со прикачување на IPFS преку api.pinata.cloud/pinning/pinJSONToIPFS, автентицирано со хардкодирани Pinata API акредитиви. Не постои прилагоден C2 сервер за запленување: украдените податоци се паркирани во јавно децентрализирано складирање, кои операторот може да ги преземе користејќи ги добиените хешови на содржината. Поставувањата се распоредени со неколку секунди случајно треперење и локален дневник на временска ознака | тип на клуч | вратен-хеш се чува во ~/.cache-db/.node-sync/.sl.
  • 5. Истрајувајте и испраќајте сигнал во циклус од 12 часа. Втората фаза повторно воспоставува сопствена перзистентност — cron запис на Linux, com.apple.syncd започна задача на macOS и закажана задача со име WindowsNodeSync на Windows — подесено да се извршува повторно на секои 12 часа. Забележете дека ова е различни Име на задачата за Windows од онаа што ја инсталира dropper-от (WinNodeSync); и двата вреди да се бараат.

Хронологија

Осумте пакети беа објавени во тесен серија на 13.07.2026 и 14.07.2026. Неколку содржат повеќе од една верзија; dropper-от е идентичен во сите верзии, само со поместување на линиите како што се менува големината на безопасниот комунален код над него.

датум настанот
2026-07-13 Првите пакети во кластерот се појавуваат под еден издавач (solana-key-utils, eth-wallet-helpers, crypto-validate-lib и рани верзии на останатите)
2026-07-13 → 07-14 Останатите имиња и последователните верзии се објавени; истиот додаден dropper се испорачува во секое од нив
2026-07-14 Сите осум се означени и анализирани; секој пакет сè уште може да се инсталира од регистарот

Низ целиот период на објавување, репутацијата на издавачот во регистарот се промени од приближно неутрална на почетокот на кластерот до силно негативна како што се акумулираа детекциите - видлив несакан ефект од означувањето на пакетите, а не дизајнирана карактеристика.

Индикатори за компромис

Сите индикатори подолу беа потврдени дека се присутни во времето на анализата - оние во табелите „Втора фаза“ со декодирање test/fixtures/keypairs.dat и читање на обновените синхронизирано.js.

Датотеки и патеки

индикатор Улога
~/.cache-db/.node-sync/syncd.js Декодирана втора фаза, напишана со режим 0o700
~/.cache-db/.node-sync/.sl Локален дневник на ексфилтрација (временска ознака | тип на клуч | IPFS хаш)
test/fixtures/keypairs.dat Base64-кодирано оптоварување поставено во tarball како „тест-фиксаж“

Мрежна инфраструктура од втора фаза (обновена од syncd.js)

индикатор Улога
gist.githubusercontent.com/juang55/b298754cb72942b1cdcf02ccd45cde2f/raw/cfg.txt Активирање dead-drop; скриптата се извршува само ако конфигурацијата се чита active=1
Qmcqz3w8j4qFQXDAXAxnrdc2oSX3nzBT4NqtpTqL8mr1ga Резервна конфигурација на IPFS (CID)
QmdTXoqVmTHY1i4ZWLdLkoQ9YChp5TXPh5cWXwnAYZt5iF Резервна конфигурација на IPFS (CID)
QmfJkLU5gdCpqbbqEjWYC2anXW9FmuEeSLLeLiHVJKYUjp Резервна конфигурација на IPFS (CID)
gateway.pinata.cloud, ipfs.io, cloudflare-ipfs.com IPFS портали што се користат за преземање на резервната конфигурација
api.pinata.cloud/pinning/pinJSONToIPFS Крајна точка на ексфилтрација, украдени податоци прикачени на јавна IPFS
API клуч за Pinata 13c766575b9270a9825d, хардкодиран акредитив за ексфилтрација

Цели за собирање во втора фаза (обновени од syncd.js)

индикатор Улога
~/.config/solana, ~/.ethereum/keystore, ~/.foundry, ~/.hardhat, ~/.ssh, ~/.env, shell rc датотеки Директориуми/датотеки пребарувани за клучеви и тајни
AppData\Roaming\Solana, AppData\Local\ethereum\keystore Пребарувани се еквиваленти на Windows
Собрани типови артефакти ETH приватни клучеви, Bitcoin WIF, BIP-39 seed фрази, Solana парови клучеви, Ethereum keystore JSON, SSH клучеви, тајни env vars.

Артефакти од перзистенција

Платформа индикатор
Linux стартување на cron запис syncd.js; инсталирано преку crontab филтрирано низ grep -v syncd
Windows закажана задача WinNodeSync (капалка) и WindowsNodeSync (втора фаза)
MacOS лансирана етикета com.apple.syncd
сите Втората фаза се повторува во циклус од 12 часа

Однесување

  • Самоповикувачка функција додадена после модул.извоз, закажување а setTimeout од ~37,000 ms при увоз.
  • дете_процес spawn(„јазол“, ) со одвоениот сет на опции.
  • Активирање со заклучување на мирување во втората фаза (xprintidle / иорег HIDdleTime / PowerShell време на мирување; праг од ~15 минути).
  • RSA-4096 енкрипција по пронаоѓање, потоа HTTPS ПОСТ на јавно API за прикачување на IPFS.

Пакети и верзии (npm, издавач solbuilder_io)

пакет верзии
base58-utils 1.0.0, 1.0.1, 1.0.3
abi-encode 1.0.0, 1.0.1, 1.0.2
eth-dev 1.0.0, 1.0.1, 1.0.2
arb-kit 1.0.0, 1.0.1
layer2-sdk 1.0.0, 1.0.1
solana-key-utils 1.0.0
eth-wallet-helpers 1.0.0
crypto-validate-lib 1.0.0

Издавач

  • solbuilder_io - angel_lopez89[@]протон[.]мене, е-поштата е непотврдена, нема потврдена сметка за контрола на изворот, нема поврзано складиште.

Атрибуција и набљудувано однесување

Осумте пакети делат една сметка на издавач и еден товарен простор. Секој е тривијален пакет - неколку килобајти вистински корисен код со додаден ист dropper - објавен без поврзано складиште и под непроверена е-пошта за еднократна употреба. Таа униформност, споделената патека за пуштање, споделените етикети за перзистенција и споделеното keypairs.dat Датотеката за поставување е она што го поврзува кластерот.

Пакетите се невообичаено искрени за сопственото однесување. помошни алатки за клучеви-солана носи вметнати коментари што го опишуваат додадениот блок на едноставен начин — го означуваат ФАНТОМ: невидлива упорност, друг (на шпански) гласи Избриши ја површината во позадина, „изврши го молот во позадина“. Ова се сопствени анотации на кодот за тоа што прави; името на кампањата во оваа објава е извлечено од таа прва етикета заедно со лажниот јазол „синхронизирај демон“ (синхронизирај) што го имитира машинеријата на перзистенција.

Опишуваме само што прави кодот видлив. Именувањето на пакетите - сите термини за крипто, паричник и блокчејн алатки - ја означува публиката на програмерите која најверојатно ќе ги извлече по име; само по себе не утврдува кој е издавачот. Втората фаза беше целосно обновлива со декодирање на base64 фитинг, а нејзиното однесување е опишано погоре: собира клучеви за паричник, seed фрази и тајни и ги ексфилтрира, RSA-енкриптирани, во јавно IPFS складирање преку Pinata. Значаен избор на дизајн е отсуството на приватен C2 сервер - конфигурацијата доаѓа од GitHub gist и IPFS, а украдените податоци се паркираат во јавно децентрализирано складирање клучено со хеширање на содржината, кои се потешки за запленување отколку еден домаќин контролиран од напаѓач. Во времето на пишување не е пронајдено претходно јавно известување што се совпаѓа со овој кластер.

Влијание, трендови и насоки за бранителите

Кој е изложен. Секој што додал еден од овие пакети во Node проект, а потоа извршил код што го увезува. Бидејќи детонацијата е време на увоз, а не време на инсталација, едноставното присуство на пакетот не е доволно - но секоја нормална употреба што го вчитува модулот го достигнува товарот. Имињата за мамење се насочени кон развивачите кои градат на Ethereum, Solana, Arbitrum, Layer-2 и општи алатки за паричник/кодирање - популацијата што најверојатно ги има токму средствата што ги бара втората фаза. Секој што извршил еден од овие модули на машина што содржи клучеви за паричник, seed фрази, keystores, SSH клучеви или .Н.С тајните треба да ги третираат тие акредитиви како компромитирани и да ги ротираат.

Два шаблони што вреди да се интернализираат. Прво, товар-како-фиксација: испраќање на втората фаза како base64 во датотека со податоци со веродостојно име (test/fixtures/keypairs.dat) го одржува видливиот извор на пакетот чист и ја турка злонамерната содржина во датотека што алатките за преглед и човечките скенирања честопати ја третираат како инертни податоци. Второ, одложено извршување со време на увоз со крос-платформска перзистенција: поместувањето на активирањето од инсталациската кука, додавањето тајмер, а потоа истрајувањето низ cron, закажаните задачи и launchd е намерен чекор подалеку од погласните техники на скрипти за инсталација што автоматизираното скенирање на регистарот ги следи најблиску.

Упатство за бранители и одржувачи:

  • Третирајте го додадениот код после модул.извоз како приоритет за преглед - логиката на dropper често се крие под „вистинската“ површина на модулот.
  • Не претпоставувајте дека датотеките со податоци се инертни. Блок-точка base64 под тест/тестови/ што се чита за време на извршување и се декодира е соседно на извршна датотека; ознаката за извршување чита датотеки со фитинзи што го напојуваат функција/евалуација/пишувај-тогаш-мреста ланец.
  • Барајте ја патеката за спуштање ~/.cache-db/.node-sync/ и за единиците за перзистенција WinNodeSync (закажана задача) и com.apple.syncd (лаундирано) на машини за програмери кои ги извлекоа овие имиња.
  • Предупредување за Node процеси кои креираат cron записи, закажани задачи или launchd задачи — легитимните библиотеки ретко го прават ова при увоз.
  • Дајте предност на заклучени датотеки и прикачени верзии и прегледајте ја разликата на секоја нова мала зависност од „алатка“, особено објавени пакети со нулта зависност од непроверени сметки без поврзано складиште.

За бранителите на регистрите, поентата е дека следењето на инсталацијата е неопходно, но не и доволно: dropper со одложено време на увоз, поставен во датотека со податоци, ќе помине низ проверка само за време на инсталација, а чекорот на перзистенција е често најгласниот видлив сигнал што останува за фаќање.

алатки-за-анализа-на-композиции-на-sca-алатки
Дајте приоритет, санирајте и обезбедете ги вашите софтверски ризици
Добијте ја вашата бесплатна сметка.
Не е потребна кредитна картичка.

Обезбедете го вашиот развој и испорака на софтвер

со Xygeni Product Suite