· kaynak Hacker News – Front Page (native)
npm math typosquat, tek bir denklemde uyanan şifreli implant saklıyor
SafeDep, mathjs'in npm'deki taklidi olan mathmain paketinin içinde, bir program kütüphaneyle belirli bir denklemi çözene kadar uykuda kalan şifreli bir uzaktan erişim implantı ortaya çıkardı.

SafeDep, popüler mathjs kütüphanesini taklit eden mathmain adlı npm paketinin içinde gizlenmiş bir uzaktan erişim implantını açıkladı. Güvenlik firmasına göre kötü niyetli kod şifreli halde dağıtılıyor ve bir program kütüphaneyi belirli bir denklemi çözmek için kullanana kadar hiçbir şey yapmıyor. Doğru girdi geldiğinde paket bir payload'ı çözüyor, diske yazıyor ve yüklüyor; böylece saldırgana ana makinede komut çalıştırma imkânı veren bir kanal açıyor.
Çözücünün içinde uyuyan bir tetikleyici
SafeDep, 17 Eylül 2026'da araçları paketi, mathjs'in obfuscate edilmiş eklemelerle yeniden adlandırılmış bir kopyası olarak işaretledikten sonra mathmain'i analiz etmeye başladı. Doğrusal denklemleri çözen lusolve() yordamının CommonJS build'inde araştırmacılar, sonuç zaten hesaplandıktan sonra araya eklenmiş bir ek çağrı buldu. Bu çağrı, alt üçgen matrisin verilerini removeSolveValidation() adlı bir fonksiyona iletiyor, dönüş değerini hiç okunmayan bir değişkene atıyor ve doğru cevabı olduğu gibi döndürüyor. Çağıran taraf açısından çözücü normal davranıyor.
Bu çağrı, paketin utility modülüne eklenmiş bir isGraph() yardımcı fonksiyonuna gidiyor. Yardımcı fonksiyon girdisini bir JSON string'ine dönüştürüyor ve bu string'i parola olarak kullanıyor. Bir dosya adını bu parolayla çözüyor, bir dosyayı aynı şekilde çözüyor, düz metni şifreli orijinalin yanına yazıyor ve require() ile yüklüyor. Çözülen modül daha sonra Node.js sürecinin tüm izinleriyle çalışıyor.
Tetikleyici tasarım gereği veriye bağımlı. Çağıran taraf, lusolve()'ın object formu üzerinden, alt faktörü tam olarak doğru parolaya serialize olan matris verisi sağlamalı; SafeDep görünür yükleyicide saklanmış bir parola bulamadı. Tahmin yanlışsa, herhangi bir dosya yazılmadan önce AES-GCM kimlik doğrulama denetimi başarısız oluyor. Manifest'te install hook yok ve paketi yalnızca import etmek hiçbir şey yapmıyor — önce çözücünün doğrulama ve hesaplama adımlarından geçmesi gerekiyor.
Şifreleme ve kademeli bir payload
SafeDep'ye göre şifre çözme kodu, paroladan scrypt ile 256 bitlik bir anahtar türetiyor ve AES-256-GCM kullanıyor. Her blob, sabit bir düzene sahip base64 metni: 16 baytlık salt, 12 baytlık initialization vector, 16 baytlık authentication tag ve ardından ciphertext. Paketteki üç dosya JavaScript yerine şifreli veri içeriyor — graph.js'te 20.918 bayt ciphertext, fraction.js'te 9.084, bignumber/type.js'te 1.179.416. Görünür yükleyici yalnızca graph.js'e atıfta bulunuyor ve SafeDep, sekiz baytlık şifreli dosya adının buna karşılık geldiğini düşünüyor. SafeDep burada bir yazım hatası olarak geçse de (SafeDeaf), graph.js çözüldüğünde diğer iki dosyayı sonraki aşamalar olarak yüklüyor. Aktif payload, saldırgandan komutlar alıyor ve bunları ana makinede çalıştırıyor; komut kanalı olarak halka açık bir chat servisi ile bir blockchain ağı kullanıyor.
Kaynakta değil, publish anında enjekte edildi
SafeDep aynı yükleyiciyi, tetikleyici kodu ve çözücü değişikliklerini, beş sürüme yayılmış iki pakette daha buldu: mathsbase ve math-universe. İkisi de halka açık GitHub repository'lerine işaret ediyor ve hiçbir repository yükleyiciyi içermiyor — npm build'leri, halka açık kaynakta bulunmayan ek çözücü çağrısını taşıyor. SafeDep'nin okumasına göre kötü niyetli kod, paketler açıkta geliştirilmek yerine yayımlandıkları sırada eklendi; ancak paylaşılan dosyalar bunu kimin eklediğini veya bir publisher hesabının ele geçirilip geçirilmediğini ortaya koymuyor.
Sürümleme kafa karışıklığını büyüttü: 17 Eylül'de npm, mathmain'in yükleyicisiz bir sürümünü varsayılan olarak sundu, bu yüzden yalnızca varsayılan sürümle sınırlı bir denetim 1.0.1'deki kodu gözden kaçıracaktı.
Tetikleyicinin kırılması onun ne kadar dar olduğunu gösterdi. SafeDep, şifreli dosya adına karşı 16.922 aday parolayı, ardından beş şifreli blob'un tamamına karşı 533 parolasını daha test etti; yaygın parolardan ve çözücünün kendi testlerinden gelen sayısal dizilerden yararlandı. Hiçbiri geçmedi. SafeDep, tetikleyiciyi üreten girdiyi ilk rapor eden JFrog'a teşekkür ediyor ve parolayı belirli bir alt faktör matrisinin JSON biçimi olarak tanımlıyor.
Etki alanı hâlâ bilinmiyor. npm'nin 12–18 Eylül indirme verileri, kayıt defterinin 17 Eylül'de her şey için sıfır indirme bildirmesi yüzünden güvenilmez; bu da mathmain'in o günkü sıfırını inandırıcı kılmıyor. Paketlerin hiçbirinin bağımlısı yok ve jsDelivr trafiği ihmal edilebilir düzeydeydi, ancak SafeDep kaç sistemin paketleri kurduğunu veya şifreli kodu çalıştırdığını belirleyemedi. GitHub kodunda, lockfile'larda ve bağımlılık servislerinde yapılan aramalar çözücüyü tetikleyen bir program bulamadı; yine de özel codebase'ler bu tür aramalara görünmez kalıyor.
Neden önemli
Bu, olağan savunmaları alt etmeye ayarlanmış bir supply-chain saldırısı. Payload şifreli ve kesin bir girdinin arkasına yerleştirildiği için statik inceleme sıradan bir matematik kütüphanesi görüyor ve sandbox'ta patlatma tetikleyiciye asla ulaşmıyor. Daha keskin ders, npm artifact'leri ile temiz GitHub repository'leri arasındaki ayrışma: kötü yazılım publish anında enjekte edildiğinde ve yalnızca yayımlanan tarball'larda bulunduğunda kaynak repository'leri denetlemek yetmez. Bu aynı zamanda bir paketin yalnızca varsayılan sürümünün değil, her sürümünün incelemeyi hak ettiğini gösteriyor. Geliştiriciler için pratik çıkarım, iyi bilinen paketleri tam adlarıyla kurmak, mathmain, mathsbase ve math-universe gibi taklit adları kırmızı bayrak saymak ve bağlantılı repository'ye güvenmek yerine tarball hash'lerini doğrulamaktır.
- #npm
- #supply-chain
- #security
- #malware
- #node-js