PhantomSync: npm Kripto Paketleri Cüzdan Hırsızını Gizliyor

PhantomSync: sekiz kripto geliştirici npm paketi, gecikmeli, kendi kendini kalıcı hale getiren bir dropper'ı gizliyor.

TL; DR

Tek bir npm yayıncısı, blockchain ve cüzdan geliştirme için günlük yapı taşları gibi görünen isimlere sahip sekiz küçük paket yayınladı. base58-utils, abi-encode, eth-dev, arb-kit, layer2-sdk, solana-key-utils, eth-wallet-helpers, ve crypto-validate-libHer biri çalışan bir yardımcı program içerir. Ancak bu yardımcı programın ardından, modül içe aktarıldığı anda çalışan, kendi kendini çağıran bir kod bloğu eklenir.

İçe aktarıldıktan yaklaşık 37 saniye sonraBu blok, paket içinde test düzeneği kılığında bulunan bir veri yükünü çözüyor, kullanıcının ana dizini altındaki gizli bir dosyaya yazıyor ve her yeniden başlatmada kendini yeniden başlatacak şekilde kaydediyor. login Windows, macOS ve Linux işletim sistemlerinde çalışır ve çözümlenmiş betiği ayrı bir işlem olarak başlatır. npm install sırasında hiçbir şey tetiklenmez; kodun içe aktarılmasını ve çalıştırılmasını bekler, bu da kurulumdan daha sessiz bir anıdır.

Veri yükü şeffaf değil. Düz base64 formatında gönderiliyor, bu nedenle "test düzeneği"nin kodunu çözmek ikinci aşamayı tamamen ortaya çıkarıyor: a kripto cüzdanı ve sır hırsızı Makine boşta kaldığında bekleyen, özel anahtarları ve kurtarma ifadelerini toplayan, bulunan her veriyi önceden tanımlanmış bir RSA-4096 anahtarıyla şifreleyen ve 12 saatte bir sinyal göndererek halka açık IPFS depolama alanına sabitleyerek dışarı sızdıran bir sistem.

Küme oluşumunu şu şekilde takip ediyoruz: PhantomSyncAnaliz sırasında sekiz paketin tamamı tek bir hesap altında yayınlanarak npm kayıt defterinde aktif durumdaydı.

Ekosistemnpm
Paketlerbase58-utils, abi-encode, eth-dev, arb-kit, layer2-sdk, solana-key-utils, eth-wallet-helpers, crypto-validate-lib
Hedeflenen platformlarWindows, MacOS, Linux
Temel davranışGecikmeli, içe aktarma zamanı tetikleyicisi test düzeneği olarak gizlenmiştir; platformlar arası kalıcılığı kurar.
YükünüKripto cüzdan ve sır hırsızı, RSA-4096 şifreleme, halka açık IPFS sabitleme yoluyla veri sızdırma

Saldırı anatomisi

Her paket ilk bakışta sıradan görünüyor. base58-utilsÖrneğin, bu birkaç kilobaytlık, sıfır bağımlılığa sahip Base58 / Bitcoin-WIF yardımcı kodudur; tam olarak adının vaat ettiği gibi. İlgili kod şu konumda yer almaktadır: sonra modülün modül.dışa aktarDosyanın en üst kısmına göz atan bir okuyucunun muhtemelen bakmayacağı bir yer: kendini bir zamanlayıcı ile zamanlayan, kendi kendini çağıran bir fonksiyon.

Paketin kaynak kodundan yeniden oluşturulan işlem zinciri şu şekildedir:

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

İki tasarım seçeneği öne çıkıyor.

Yük, bir test düzeneği olarak hareket eder. İkinci aşama, açıkça görülebilen bir kod olarak yazılmaz. Şurada yer alır: test/fixtures/keypairs.datAdı, anahtar çiftlerini işlediğini iddia eden bir pakete karışan bir base64 dosyası. Tarball'ı hızlıca inceleyen bir insan için örnek veri gibi görünür; eklenmiş kod için ise çözülmesi ve çalıştırılması gereken bir komut dosyasıdır. Dropper'ın kendisi ağ adresi içermez — bunlar ikinci aşamada bulunur — ancak ek bir gizleme yoktur: fikstür tek katmanlı bir base64'tür, bu nedenle onu çözmek (base64 -d) tam olarak geri kazanır syncd.js ve ağ davranışı. Sonraki bölümde, kurtarılan bu aşamanın ne yaptığı açıklanmaktadır.

Patlama gecikmeli gerçekleşiyor ve kurulumla değil, ithalatla bağlantılı. Çünkü tetikleyici Require () Kurulum kancası yerine yaklaşık 37 saniyelik bir zamanlayıcı eklenmesiyle, bu davranış yalnızca izleme yapan kontrolleri atlatıyor. npm kurulumu Bu adımda, gecikme birçok kısa süreli sanal ortam ve sürekli entegrasyon (CI) çalışmasından daha uzun sürer. Herhangi bir şey yürütüldüğünde, paketi indiren kurulum çoktan tamamlanmış olur.

Çözümlenmiş metin diske kaydedildikten sonra ~/.cache-db/.node-sync/syncd.js — rutin bir önbellek dizini gibi okunacak şekilde seçilen bir yol — bu dosya, üç ana platformun tümünde yeniden başlatmalardan etkilenmeden çalışmaya devam eder:

  • Linux: Komut dosyasını yeniden başlatan bir cron girdisi. Bu girdi, mevcut crontab'ı filtreleyerek yüklenir. grep -v syncdBu durum, aynı adı arayan düz bir aramada yeni girişin listeden çıkarılması gibi bir yan etkiye yol açar.
  • Windows: planlanmış bir görev adı WinNodeSync12 dakikalık aralıklarla tekrar oynatılacak şekilde ayarlanmıştır.
  • MacOS: bir başlatma işi etiketlendi com.apple.syncdPaketlerin birçoğunda bulunan ve meşru bir Apple sistem hizmetini taklit eden bir etiket.

Ardından komut dosyası, bağımsız bir işlem olarak hemen başlatılır, böylece içe aktarma programı sona erdikten sonra da çalışmaya devam eder.

İkinci aşama ne yapar?

Çünkü fikstür tek bir base64 katmanından oluştuğu için, ikinci aşama sorunsuz bir şekilde çözümlenir ve tamamen okunabilir. Sekiz paketin tamamı, başlık yorumunda kendini tanımlayan aynı komut dosyasının üç varyantından birini taşır. phantom Syncd v3 — geçerli süre (“uyuyan köstebek”). Görevi, kripto para cüzdanı materyallerini ve geliştirici sırlarını çalmak ve bunları makineden dışarı göndermektir. Şu adımları izler:

  • 1. Makine boşta kalana kadar bekleyin. Bir şey yapmadan önce, syncd.js Kullanıcının ne kadar süredir aktif olmadığını kontrol eder ve yalnızca belirli bir eşiği (yaklaşık 15 dakika) geçtikten sonra işleme devam eder. xprintidle Linux'ta, ıoreg macOS'ta HIDIdleTime ve Windows'ta PowerShell boşta kalma süresi sorgusu kullanılır. Bu nedenle veri toplama işlemi genellikle klavyede kimse olmadığında gerçekleşir.
  • 2. Uzaktan kumandalı bir aktivasyon anahtarı getirin.Komut dosyası, işlem yapmadan önce gizli bir sunucudan küçük bir yapılandırma dosyası çekiyor. Birincil kaynak, GitHub gist'in ham URL'sidir (gist.githubusercontent.com/juang55/…/cfg.txtKomut dosyası yalnızca bu yapılandırma okunduğunda etkinleşir. aktif=1Eğer özet bilgi mevcut değilse, genel ağ geçitleri aracılığıyla alınan üç adet sabit kodlu IPFS içerik tanımlayıcısına geri döner. ağ geçidi.pinata.bulut, ipfs.io, ve cloudflare-ipfs.comBu, operatöre sonradan kurma/silahsızlandırma kontrolü ve devrilmeye karşı dayanıklı bir yedekleme mekanizması sağlar. (En küçük varyant, şu şekilde sevk edilir: kripto-doğrulama-kütüphanesi, eth-cüzdan-yardımcıları, ve solana-anahtar-yardımcıları(Özet katmanı kaldırılmıştır ve yalnızca IPFS tanımlayıcılarına dayanmaktadır.)
  • 3. Cüzdan içeriğini ve sırlarını toplayın. Bu komut dosyası kullanıcının ana dizinini tarar. ~/.config/solana, ~/.ethereum/keystore, ~/.foundry, ~/.baret, ~ / .ssh, ve Masaüstü/evraklar/Dosya İndir (İspanyolca klasör adları dahil), artı ~/.env ve shell rc dosyaları ve bunların eşdeğerleri AppData Windows'taki konumları hedef alır. Ethereum özel anahtarlarını, Bitcoin WIF anahtarlarını, BIP-39 kurtarma ifadelerini, Solana anahtar çiftlerini, Ethereum anahtar deposu JSON'unu, SSH anahtarlarını ve gizli bilgi içeren ortam değişkenlerini hedefler. Daha büyük varyant (içinde) abi-kodlama, base58-utils, eth-dev(2048 kelimelik BIP-39 sözlüğünün tamamını içerir ve düzenli ifadeler kullanır) çıkarmak Okuduğu herhangi bir metinden bireysel anahtarlar ve doğrulanmış başlangıç ​​ifadeleri; iki küçük varyant ise bunun yerine dosyaları anahtar kelimeye göre eşleştirir (tohum, hafıza, cüzdan, metamask, fantom, defteri kebir, trezor(…) ve dosyaların tamamını yükleyin.
  • 4. Şifreleyin ve herkese açık bir pinleme hizmeti aracılığıyla dışarı sızdırın. Her bulgu, bir ana bilgisayar parmak iziyle birlikte paketlenmiştir (kullanıcıadı@anabilgisayarı(platform, zaman damgası) bilgileri kaydedilir ve komut dosyasına gömülü, önceden tanımlanmış bir RSA-4096 açık anahtarıyla şifrelenir. Şifrelenmiş kayıt daha sonra IPFS'ye sabitlenerek yüklenir. api.pinata.cloud/pinning/pinJSONToIPFSPinata API kimlik bilgileriyle kodlanmış şekilde doğrulanmıştır. Ele geçirilecek özel bir C2 sunucusu yoktur: çalınan veriler, operatör tarafından elde edilen içerik özetleri kullanılarak alınabilen, halka açık, merkezi olmayan bir depolama alanında saklanır. Yüklemeler birkaç saniyelik rastgele bir gecikmeyle yapılır ve yerel bir günlük tutulur. zaman damgası | anahtar türü | döndürülen karma değer tutulur ~/.cache-db/.node-sync/.sl.
  • 5. 12 saatlik bir döngüde ısrarcı olun ve sinyal gönderin. İkinci aşama kendi kalıcılığını yeniden oluşturur; Linux'ta bir cron girdisi, com.apple.syncd macOS'ta bir iş başlat ve zamanlanmış bir görev adı WindowsNodeSync Windows'ta — her 12 saatte bir yeniden çalışacak şekilde ayarlanmıştır. Bunun bir farklı Dropper'ın yüklediği Windows görevinin adı (WinNodeSyncİkisi de aramaya değer.

Tarihçesi

Sekiz paket, 13 ve 14 Temmuz 2026 tarihlerinde kısa bir süre içinde yayınlandı. Birçoğunun birden fazla sürümü bulunmaktadır; yükleyici, sürümler arasında aynıdır, yalnızca üstündeki zararsız yardımcı kodun boyutu değiştikçe satır kaydırmaları değişir.

Tarih Etkinlikler
2026-07-13 Kümedeki ilk paketler tek bir yayıncı altında görünür (solana-key-utils, eth-wallet-helpers, crypto-validate-lib ve geri kalanının ilk versiyonları)
2026-07-13 → 07-14 Geri kalan isimler ve takip eden sürümler yayınlandı; her birinde aynı eklenmiş damlalık gemileri bulunuyor.
2026-07-14 İşaretlenen ve analiz edilen sekiz paketin tamamı hala kayıt defterinden yüklenebiliyor;

Bu ani artış boyunca, yayıncının kayıt defterindeki itibarı, kümenin başlangıcındaki yaklaşık olarak nötr seviyeden, tespitler biriktikçe oldukça negatif bir seviyeye yükseldi; bu, paketlerin işaretlenmesinin gözlemlenebilir bir yan etkisi olup, tasarlanmış bir özellik değildir.

Uzlaşma Göstergeleri

Aşağıdaki tüm göstergelerin analiz sırasında mevcut olduğu doğrulandı; bunlar "İkinci aşama" tablolarındaki göstergelerin kod çözme işlemiyle elde edilen sonuçlarıdır. test/fixtures/keypairs.dat ve kurtarılanları okumak syncd.js.

Dosyalar ve yollar

Gösterge Rol
~/.cache-db/.node-sync/syncd.js 0o700 moduyla yazılan ikinci aşama çözümlendi.
~/.cache-db/.node-sync/.sl Yerel veri sızdırma günlüğü (zaman damgası | anahtar türü | IPFS özeti)
test/fixtures/keypairs.dat Base64 kodlu veri paketi, "test düzeneği" olarak tarball'ın içine yerleştirildi.

İkinci aşama ağ altyapısı (syncd.js'den kurtarıldı)

Gösterge Rol
gist.githubusercontent.com/juang55/b298754cb72942b1cdcf02ccd45cde2f/raw/cfg.txt Etkinleştirme gizli bırakma noktası; komut dosyası yalnızca yapılandırma okunduğunda çalışır. active=1
Qmcqz3w8j4qFQXDAXAxnrdc2oSX3nzBT4NqtpTqL8mr1ga IPFS yapılandırma yedeklemesi (CID)
QmdTXoqVmTHY1i4ZWLdLkoQ9YChp5TXPh5cWXwnAYZt5iF IPFS yapılandırma yedeklemesi (CID)
QmfJkLU5gdCpqbbqEjWYC2anXW9FmuEeSLLeLiHVJKYUjp IPFS yapılandırma yedeklemesi (CID)
gateway.pinata.cloud, ipfs.io, cloudflare-ipfs.com IPFS ağ geçitleri, yapılandırma yedeklemesini almak için kullanılır.
api.pinata.cloud/pinning/pinJSONToIPFS Veri sızdırma uç noktası, çalınan veriler herkese açık IPFS'ye sabitlendi.
Pinata API anahtarı 13c766575b9270a9825d, sabit kodlu veri sızdırma kimlik bilgisi

İkinci aşama toplama hedefleri (syncd.js'den kurtarıldı)

Gösterge Rol
~/.config/solana, ~/.ethereum/keystore, ~/.foundry, ~/.hardhat, ~/.ssh, ~/.envkabuk rc dosyaları Anahtarlar ve gizli bilgiler için arama yapılan dizinler/dosyalar
AppData\Roaming\Solana, AppData\Local\ethereum\keystore Windows eşdeğerleri arandı
Hasat edilen eser türleri ETH özel anahtarları, Bitcoin WIF, BIP-39 kurtarma ifadeleri, Solana anahtar çiftleri, Ethereum anahtar deposu JSON, SSH anahtarları, gizli ortam değişkenleri

Kalıcılık eserleri

Platform Gösterge
Linux cron girdisi başlatılıyor syncd.js; crontab aracılığıyla yüklendi ve filtrelendi grep -v syncd
Windows Planli gorev WinNodeSync (damlalık) ve WindowsNodeSync (ikinci aşama)
macOS lansman etiketi com.apple.syncd
Tümü İkinci aşama 12 saatlik bir döngüde kendini tekrar eder.

Davranışsal

  • Kendi kendini çağıran fonksiyon, sonrasında eklendi. modül.dışa aktar, planlama setZaman aşımı İçe aktarma işlemi yaklaşık 37,000 ms sürdü.
  • çocuk_işlemi spawn("düğüm", ) Ayrılmış seçenek ayarlanmış halde.
  • İkinci aşamada boşta kalma durumuna bağlı aktivasyon (xprintidle / ıoreg HIDIdleTime / PowerShell boşta kalma süresi; yaklaşık 15 dakikalık eşik değer).
  • Öncelikle RSA-4096 şifrelemesi, ardından HTTPS POST Herkese açık bir IPFS sabitleme API'sine.

Paketler ve sürümler (npm, yayıncı solbuilder_io)

paket sürümler
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

Publisher

  • solbuilder_io - angel_lopez89[@]proton[.]meE-posta doğrulanmamış, doğrulanmış kaynak kontrol hesabı yok, bağlantılı depo yok.

Atıf ve Gözlemlenen Davranış

Sekiz paket, tek bir yayıncı hesabı ve tek bir yük dosyası paylaşıyor. Her biri önemsiz bir paket; aynı dropper eklenmiş birkaç kilobaytlık gerçek yardımcı koddan oluşuyor ve bağlantılı bir depo olmadan ve doğrulanmamış, tek kullanımlık bir e-posta adresi altında yayınlanıyor. Bu tekdüzelik, paylaşılan bırakma yolu, paylaşılan kalıcılık etiketleri ve paylaşılan anahtar çiftleri.dat Hazırlık dosyaları, kümeyi bir arada tutan unsurlardır.

Paketler, kendi davranışları konusunda alışılmadık derecede açık sözlü. solana-anahtar-yardımcıları Eklenen bloğu sade bir dille açıklayan satır içi yorumlar içerir; bunlardan biri onu etiketler. HAYALET: görünmez kalıcılıkBir diğeri (İspanyolca) şöyle diyor: Ejecutar topo en background“köstebek işlemini arka planda çalıştır.” Bunlar, kodun kendi yaptığı işlere dair kendi açıklamalarıdır; bu gönderideki kampanya adı, bu ilk etiketten ve sahte düğüm “senkronizasyon servisi”nden (senkronize) kalıcılık mekanizmasının taklit ettiği şey.

Biz yalnızca kodun gözlemlenebilir şekilde ne yaptığını açıklıyoruz. Paketlerin adlandırılması —tüm kripto, cüzdan ve blok zinciri araçları terimleri— bunları adlarıyla çekme olasılığı en yüksek olan geliştirici kitlesini gösterir; tek başına yayıncının kim olduğunu belirlemez. İkinci aşama, base64 kodunun çözülmesiyle tamamen kurtarılabilir durumdaydı ve davranışı yukarıda açıklanmıştır: cüzdan anahtarlarını, kurtarma ifadelerini ve sırları toplar ve bunları RSA ile şifreleyerek Pinata aracılığıyla halka açık IPFS depolama alanına sızdırır. Dikkat çekici bir tasarım tercihi, özel bir C2 sunucusunun olmamasıdır — yapılandırma bir GitHub gist'inden ve IPFS'den gelir ve çalınan veriler, içerik karması ile anahtarlanmış halka açık merkezi olmayan depolama alanına park edilir; bunların her ikisi de tek bir saldırgan tarafından kontrol edilen bir sunucudan daha zor ele geçirilir. Yazım sırasında bu kümeye uyan önceden yapılmış herhangi bir kamu raporu bulunamadı.

Savunmacılar için Etki, Trendler ve Rehberlik

Kimler risk altında? Bu paketlerden birini bir Node projesine ekleyip ardından onu içe aktaran kodu çalıştıran herkes. Patlama, kurulum zamanından ziyade içe aktarma zamanında gerçekleştiği için, paketin mevcut olması yeterli değildir; modülü yükleyen herhangi bir normal kullanım, zararlı yazılımın devreye girmesine neden olur. Tuzak, Ethereum, Solana, Arbitrum, Layer-2 ve genel cüzdan/şifreleme araçları üzerinde çalışan geliştiricileri hedef alır; bu da ikinci aşamanın aradığı varlıklara sahip olma olasılığı en yüksek olan kitleyi oluşturur. Cüzdan anahtarları, kurtarma ifadeleri, anahtar depoları, SSH anahtarları veya benzeri verileri tutan bir makinede bu modüllerden birini çalıştıran herkes. .env Gizlilik birimi, bu kimlik bilgilerini tehlikeye girmiş olarak değerlendirmeli ve bunları değiştirmelidir.

İçselleştirmeye değer iki kalıp. İlk olarak, yük-sabitleme: ikinci aşamayı base64 formatında, mantıklı bir isimle adlandırılmış bir veri dosyası içinde göndermek (test/fixtures/keypairs.datBu yöntem, paketin görünür kaynağını temiz tutar ve kötü amaçlı içeriği, inceleme araçlarının ve insan taramalarının genellikle etkisiz veri olarak ele aldığı bir dosyaya iter. İkinci olarak, Platformlar arası kalıcılıkla zaman gecikmeli yürütmeTetikleyiciyi kurulum kancasından ayırmak, bir zamanlayıcı eklemek ve ardından bunu cron, zamanlanmış görevler ve launchd genelinde kalıcı hale getirmek, otomatik kayıt defteri taramasının en yakından izlediği daha gürültülü kurulum komut dosyası tekniklerinden bilinçli bir şekilde uzaklaşma adımıdır.

Savunmacılar ve bakımcılar için kılavuz:

  • Eklenen kodu aşağıdaki şekilde işleyin modül.dışa aktar Bir inceleme önceliği olarak — damlatıcı mantığı genellikle "gerçek" modül yüzeyinin altında gizlenir.
  • Veri dosyalarının etkisiz olduğunu varsaymayın. Bir base64 bloğu aşağıdaki gibidir. test/fikstürler/ Çalışma zamanında okunan ve çözümlenen, yürütülebilir dosyaya bitişik olan; bir besleyen fikstür dosyalarının çalışma zamanında okunmasını işaretleyen bayrak. İşlev/değerlendirme/sonra-yaz-yumurtlamak zinciri.
  • Düşüş yolunu arayın. ~/.cache-db/.node-sync/ ve kalıcılık birimleri için WinNodeSync (planlanmış görev) ve com.apple.syncd (launchd) bu isimleri çeken geliştirici makinelerinde.
  • Node süreçlerinin cron girdileri, zamanlanmış görevler veya launchd işleri oluşturması durumunda uyarı verin — meşru kütüphaneler içe aktarma sırasında bunu nadiren yapar.
  • Kilit dosyalarını ve sabitlenmiş sürümleri tercih edin ve özellikle yeni küçük "yardımcı" bağımlılıkların farklarını inceleyin. sıfır bağımlılığa sahip paketler yayınlandı Bağlantılı deposu olmayan doğrulanmamış hesaplar tarafından.

Kayıt defteri savunucuları için çıkarılacak ders şudur: yükleme kancası izlemesi gerekli ancak yeterli değildir: bir veri dosyası içine yerleştirilmiş, içe aktarma zamanında çalışan, zamanlayıcı gecikmeli bir yükleyici, yalnızca yükleme zamanında yapılan bir kontrolü geçecektir ve kalıcılık adımı genellikle yakalanması gereken en belirgin sinyaldir.

sca-tools-software-composition-analysis-tools
Yazılım risklerinizi önceliklendirin, giderin ve güvence altına alın.
Ücretsiz hesabınızı alın.
Hiçbir kredi kartı gerekmektedir.

Yazılım Geliştirme ve Teslimatınızı Güvence Altına Alın

Xygeni Ürün Paketi ile