1 puan yazan GN⁺ 4 시간 전 | Henüz yorum yok. | WhatsApp'ta paylaş
  • LinkedIn'de yazılım mühendisi işe alımı teklif edildikten sonra, normal bir React/Web3 ödevi gibi görünen özel bir GitHub deposu gönderildi; çalıştırıldığında tailwind.config.js içine gizlenmiş JavaScript kötü amaçlı yazılımı geliştiricinin bilgisayarında devreye girdi
  • 30.987 baytlık yapılandırma dosyası, binlerce boşluğun arkasına 27 KB boyutunda obfuscate edilmiş kod gizledi; uzak bir sunucudan AES-256-CBC ile şifrelenmiş ikinci aşama yükü alıp bunu %TEMP%\pack içine kaydettikten sonra node pack ile çalıştırdı
  • Windows 11 ARM yalıtılmış VM üzerinde yaklaşık 10 dakika süren gözlemde, yükün dört bileşeni etkinleştirdiği görüldü: uzaktan kontrol arka kapısı, tarayıcı/cüzdan hırsızı, özyinelemeli dosya tarayıcısı ve pano gözetleyicisi
  • Socket.IO üzerinden terminal, SSH, ekran, klavye ve fareyi kontrol etti; Chromium veritabanları, cüzdan eklenti depoları, SSH anahtarları, kaynak kodu ve yapılandırma dosyalarını topladı; ayrıca dosya yükleme portunda 2.588 istek gözlendi
  • Yabancı birinin gönderdiği ödev deposu güvenilmeyen kod olarak ele alınmalı; gerçek tarayıcı profilleri, SSH anahtarları, bulut kimlik bilgileri veya cüzdanlar bulunmayan tek kullanımlık bir VM ya da container içinde incelenmeli; enfeksiyon varsa ağ bağlantısı kesilip kanıtlar korunmalı ve ardından gizli bilgiler dâhil her şey değiştirilmeli

Normal bir Web3 işe alım ödevi gibi görünen depo

  • LinkedIn kullanıcısı Wayan Adrian, shrapnel.com bünyesinde bir yazılım mühendisi pozisyonu önerdi ve yevhen-o hesabına ait tech-active-workplace-frontend-main adlı özel GitHub deposunu ödev olarak iletti
  • BLAIEXS adlı NFT kampanya platformu, dışarıdan bakıldığında sıradan bir React/Web3 projesiydi
    • React frontend; marka/yönetici paneli, kampanya yönetimi ve NFT oluşturma akışları sunuyordu
    • Express API; kimlik doğrulama, panel verileri, KYB kontrolleri, NFT oluşturma/talep etme, dosya yükleme ve bazı stub endpoint'leri işliyordu
    • Seed script'i; superadmin, marka ve tüketici demo hesapları, Demo NFT Drop kampanyası ve 100 adet sunulan Demo Collectible NFT oluşturuyordu
  • Asıl ödev kapsamı yalnızca basit bir MetaMask ağ gösterim özelliğiydi
    • src/utils/ethereum.js içindeki asenkron getChainId(), eth_chainId çağrısını yapıp ayrıştırılmış onaltılık değeri veya null döndürecek şekilde uygulanıyordu
    • Aynı dosyadaki getNetworkLabel(chainId), mevcut NETWORKS nesnesinden okunabilir ağ adını bulacak şekilde uygulanıyordu
    • src/components/Wallet/ConnectWalletButton.js, cüzdan bağlandıktan sonra bu iki fonksiyonu çağıracak şekilde değiştiriliyordu
  • Uygulama tamamlandıktan sonra geliştirme sunucusu çalıştırıldı, ancak uzun süre başlamadı; anormalliği fark eden kullanıcı internet kablosunu çıkardı

tailwind.config.js içine gizlenmiş yürütme kodu

  • ls -la çıktısında tailwind.config.js 30.987 bayt görünüyordu, ancak editörde yalnızca 97 satır görünüyordu; wc -c ile de aynı boyut doğrulandı
    1. satır civarında, binlerce boşluğun arkasına insanın okuyamayacağı büyüklükte bir JavaScript blob'u gizlenmişti
  • Kod, tipik JavaScript obfuscation yöntemleri kullanıyordu
    1. Önemli dizeleri büyük bir dizide saklıyordu
    2. Dizi, sağlama toplamı eşleşene kadar döndürülüyordu
    3. Dizelere erişim bir decoder fonksiyonunun arkasına gizleniyordu
    4. Açık isimler sayısal indeksler ve wrapper çağrılarıyla değiştiriliyordu
  • İki decoder'dan biri Base64 benzeri biçimden dizeleri geri getiriyor, diğeri ise dize başına anahtar ve RC4 benzeri bir akış şifresi uyguluyordu; ayrıca decoder indeksleri doğru olmadan önce dize dizisi döndürülüyordu
  • Kötü amaçlı yazılımı çalıştırmadan obfuscation şu sırayla çözülebildi
    1. Dize dizisini çıkarmak
    2. Beklenen sağlama toplamına ulaşacak şekilde dizi döndürmeyi yeniden üretmek
    3. Decoder fonksiyonlarını yeniden uygulamak
    4. b(0x214), c(0x2f1, "key") gibi çağrıları gerçek dizelerle değiştirmek
    5. Wrapper nesnelerini ve yardımcı fonksiyonları sadeleştirerek yürütme niyetini açığa çıkarmak

1. aşama dropper'ın işleyişi

  • Açılmış kod, child_process, os, fs, path, crypto modüllerini yüklüyor ve geçici dizine axios ile socket.io-client kuruyordu
  • Süreç düzeyindeki uncaughtException ve unhandledRejection işleyicileri, hataları yok sayacak şekilde ayarlanmıştı
  • Uzak payload çalıştırma akışı şöyleydi
    • UID: 59e605dd78fb2aafccd1b622f06a00ca
    • Veri, http://45.146.252.17/api/service/59e605dd78fb2aafccd1b622f06a00ca adresinden alınıyordu
    • UID ve salt dizgesi, 32 baytlık anahtar türetmek için crypto.scryptSync içine veriliyordu
    • Yanıt, base64_iv:base64_ciphertext biçiminde ayrıştırılıp aes-256-cbc ile çözülüyordu
    • Düz metin, geçici dizindeki pack dosyasına yazılıyordu
    • child_process.execSync("node pack", { windowsHide: true, cwd: os.tmpdir() }) ile çalıştırılıyordu
  • Kendi başına işlev görmek yerine başka kötü amaçlı yazılımlar indirip çalıştıran bir malware dropper idi
  • İndirilen kodda imza doğrulama, hash allowlist'i, kaynak sabitleme, yol kısıtlama veya çalıştırma engelleyici korumalar yoktu; bu nedenle uzak endpoint, Tailwind yapılandırmasını yükleyen işletim sistemi hesabının yetkileriyle kod çalıştırabiliyordu

Yalıtılmış VM üzerinde yapılan dinamik analiz

  • Ana sistemi açığa çıkarmamak için UTM ile tek kullanımlık bir Windows 11 ARM VM kuruldu
    • Bellek 4096 MiB
    • Disk 64 GiB
    • shared/NAT ağ yapılandırması
    • Paylaşılan klasörler devre dışı
  • Kötü amaçlı yazılım davranışını farklı açılardan toplamak için araçlar kuruldu
    • Wireshark: paketleri ve C2/veri sızdırma trafiğini toplamak için
    • Sysinternals Sysmon: kalıcı Windows olay telemetrisi için
    • Procmon: çalışan süreç, kayıt defteri ve dosya sistemi etkinliklerini toplamak için
  • Kötü amaçlı yazılımın neyi topladığını doğrulamak amacıyla tuzak veriler yerleştirildi
    • SSH anahtar çifti
    • Özel GitHub deposu
    • Kripto para cüzdanları
    • Tarayıcı verileri
    • Bilgi hırsızının hedef alabileceği diğer dosyalar
  • VM içinde yarn start çalıştırıldı ve yaklaşık 10 dakika boyunca gözlemlendikten sonra run1-full.pcapng, run1-sysmon.evtx, stage2-pack.bin elde edildi

Ağda doğrulanan enfeksiyon akışı

  • 45.146.252.17 adresine giden HTTP isteklerinde portlara göre rol ayrımı vardı
    • Port 80: 1. aşama payload alma, ana bilgisayar kaydı, log gönderimi
    • Port 7641: Socket.IO komut ve kontrol arka kapısı
    • Port 7646: 2.588 adet dosya yükleme
    • Port 7649: daha büyük ama sayısı daha az olan 3 tarayıcı veri yüklemesi
  • İlk istek GET /api/service/59e605dd78fb2aafccd1b622f06a00ca idi ve yanıt, Content-Length: 150897 olan base64_iv:base64_ciphertext biçimindeydi
  • tailwind.config.js, yanıtı AES-256-CBC ile çözüp düz metni %TEMP%\pack içine yazdıktan sonra node pack ile çalıştırıyordu
  • Elde edilen 2. aşama payload şu özelliklere sahipti
    • SHA-256: 68a64d8c015c06fd70bcb8c5878c1e430da827dd00b62f8e6ef69e76bb94de5b
    • Boyut: 113136 bayt
    • Biçim: tek satırlı ASCII JavaScript
  • Çözülmüş pack dosyası da yeniden obfuscate edilmişti, ancak ilk aşamayla aynı teknikleri kullandığı için aynı prosedürle çözülebildi

Dört programdan oluşan 2 aşamalı payload

  • pack, tek bir script değil; aşağıdaki dört programı çalıştıran küçük bir süreç ağacıydı
    1. scdata komuta-kontrol arka kapısını geçici dizine yazıp çalıştırıyordu
    2. ldata tarayıcı ve cüzdan hırsızını geçici dizine yazıp çalıştırıyordu
    3. Özyinelemeli dosya tarayıcısını node -e ile doğrudan bellekten çalıştırıyordu
    4. Pano izleyicisini node -e ile doğrudan bellekten çalıştırıyordu
  • Başlıca yapılandırma değerleri UID 59e605dd78fb2aafccd1b622f06a00ca, kullanıcı anahtarı 308, host 45.146.252.17, Socket.IO portu 7641, anahtar portu 7648, tarayıcı yükleme portu 7649, dosya yükleme portu 7646 idi

scdata: etkileşimli uzaktan kontrol arka kapısı

  • scdata, %TEMP% içine dosya olarak yazıldıktan sonra npm i axios socket.io-client ... && node scdata ile çalıştırılıyor ve uzun süre çalışan bir alt süreç olarak kalıyordu
  • Çalıştıktan sonra kendisini meşru bir süreç gibi görünecek şekilde yapılandırıyordu
  • Uzaktan kontrol işlevleri için gerekli ek paketleri de kuruyordu
    • socket.io-client, ssh2, node-pty: terminal ve SSH benzeri işlevler
    • sharp, screenshot-desktop, clipboardy, @nut-tree-fork/nut-js: ekran görüntüsü, pano, fare taşıma-tıklama-kaydırma, klavye girişi
  • Socket.IO event'leri, uzaktan kontrol kapsamını doğrudan gösteriyordu
    • Terminal: start-terminal, terminal-input, terminal-resize, stop-terminal, command
    • Host doğrulama ve yakalama: whour, capture
    • Girdi kontrolü: mouseMove, mouseClick, mouseScroll, keyTap, keyCombo
    • Pano: copyText, pasteText
    • SSH ve sonlandırma: start_ssh, ssh_input, kill
  • PCAP'te 7641 portundaki polling ve WebSocket handshake'i ile ilk sunucu eventi whour doğrulandı; Sysmon'da ise sırasıyla node.exe scdata, sistem bilgisi sorgulayan PowerShell ve iki grup npm paket kurulumu yakalandı
  • Basit bilgi hırsızlığının ötesinde, saldırgana shell ve masaüstü kontrol yetenekleri de sağlıyordu

ldata: tarayıcı ve cüzdan veri hırsızı

  • ldata, %TEMP% içine yazılıyor ve npm i axios && node ldata ile çalıştırılıyordu; süreç başlığı npm-cache idi
  • Tarayıcı profilleri ile cüzdan eklentisi depolarını toplayıp http://45.146.252.17:7649/upload adresine gönderiyor, LevelDB durumu ise /cldbs üzerinden kontrol ediliyordu
  • Hedef tarayıcılar işletim sistemine göre geniş kapsamlı biçimde ayarlanmıştı
    • Windows: Chrome, Edge, Brave, LT Browser
    • macOS: Chrome, Brave, Opera, LT Browser, Edge ve yerel giriş keychain'i
    • Linux: karşılık gelen Chromium tabanlı profil klasörleri
  • Default veya Profile* dizinlerinden şu Chromium veritabanlarını yüklüyordu
    • Login Data
    • Login Data For Account
    • Web Data
  • Ardından Local Extension Settings/<extension-id> altında dolaşıyor, hard-code edilmiş cüzdan eklenti kimlikleri arasında MetaMask'ın nkbihfbeogaeaoehlefnkodbefgpgknn kimliği de yer alıyordu
  • İlk 8 cüzdan eklentisi yolu için LevelDB dizinlerini geçici klasöre kopyalayıp tek tek dosya yüklüyor, sunucunun cldbs yanıtına göre tamamlanma veya yeniden deneme kararı veriyordu
  • 7649 portunda doğrulanan üç yükleme şu veritabanlarıydı
    • Login_Data.sqlite: 51.200 bayt
    • Login_Data_For_Account.sqlite: 51.200 bayt
    • Web_Data.sqlite: 262.144 bayt
  • Deney verilerinde kayıtlı parola veya kart satırı yoktu, ancak 6 otomatik doldurma değeri ve tarayıcı meta verileri bulunuyordu
  • Chrome türevi tarayıcılar bazı alanları yerelde şifrelediği için yalnızca veritabanlarıyla düz metin sırları her zaman kurtarmak mümkün değildir
    • Ancak işletim sistemi sırları, çerezler, eklenti depoları ve kilidi açılmış tarayıcıyla birleştirildiğinde bu, kimlik bilgisi hırsızlığı hattının bir parçası haline gelir
  • Gerekli tarayıcı verileri ve LevelDB'ler yüklendiğinde ya da sunucu tamamlandı olarak işaretlediğinde sonlanıyor, operatörden ek komut beklemiyordu

Özyinelemeli dosya tarayıcısı ve pano izleyicisi

  • Özyinelemeli dosya tarayıcısı, ayrı bir dosya oluşturmadan node -e ile çalıştırılıyor ve kullanıcı home dizininden itibaren tarama yapıyordu
    • Windows'ta Get-CimInstance Win32_LogicalDisk ile sürücü harflerini listeliyor ve her sürücünün kökünü de inceliyordu
    • Toplanan dosya kalıpları arasında *.env*, *.md, *.pem, *.ini, *.secret, *.json, *.js, *.ts, *.csv, *.txt, *.doc, *.docx, *.pdf, *.xlsx, .zsh_history, .bash_history yer alıyordu
    • ~/.ssh, ~/.aws, ~/.azure, ~/.config, ~/.foundry otomatik olarak ilgi klasörleri sayılıyordu
    • metamask, bitcoin, btc, solana, secret phrase, private key gibi adları da arıyordu
    • Sonuçları http://45.146.252.17:7646/upload adresine gönderiyordu
  • Yem ortamında id_ed25519, id_ed25519.pub, History.txt, seed.js, password.js, tokens.js, ConnectWalletButton.js, ExportWallet.js, RegisterWallet.js, tailwind.config.js, aptos-cli.json gibi dosyalar gerçekten yüklendi
  • ldata tarayıcı ve cüzdan depolarına odaklanıyorsa, dosya tarayıcısı SSH anahtarları, yapılandırmalar, kaynak kodu, yerel sırlar, shell geçmişi ve proje dosyalarını geniş kapsamda topluyordu
  • Pano izleyicisi de node -e ile çalıştırılıyor ve süreç başlığı npm-compiler.log idi
    • Birkaç saniye bekledikten sonra panoyu tekrar tekrar okuyordu
    • macOS'ta pbpaste, Windows'ta powershell -NoProfile -NonInteractive Get-Clipboard kullanıyordu
    • Değişen değerleri http://45.146.252.17/api/service/makelog adresine gönderiyordu
  • Biçimi yorumlamasa bile, kullanıcının kopyaladığı parolaları, kurtarma ifadelerini, özel anahtarları, API token'larını, tek kullanımlık kodları, GitHub URL'lerini, cüzdan adreslerini ve dağıtım sırlarını olduğu gibi yakalayabiliyordu

İşe alım ödevini çalıştırmadan önce uyulması gereken ilkeler

  • Tanımadığınız birinin gönderdiği ödev deposu, güvenliği doğrulanana kadar güvenilmeyen çalıştırılabilir kod olarak ele alınmalı
  • yarn install, npm install, yarn build, yarn start öncesinde şu öğeler incelenmeli
    • package.json
    • yaşam döngüsü script'leri
    • yapılandırma dosyaları
    • açık bağımlılık hook'ları
  • Bu vakadaki zararlı yazılım, insanların gözden kaçırmasının kolay olduğu tailwind.config.js içine gizlenmişti; yapılandırma dosyaları, bağımlılıklar ve build araçlarının tümü de kod olarak çalıştırılabilir
  • Mülakat projeleri, gerçek sırların mount edilmediği tek kullanımlık bir VM veya container içinde çalıştırılmalı
    • kişisel tarayıcı profilleri
    • parola yöneticisi
    • SSH anahtarları
    • kripto para cüzdanları
    • GitHub token'ları
    • bulut kimlik bilgileri
    • banka oturumları
    • birincil e-posta hesabı
  • Hesap veya cüzdan gerektiren ödevlerde, içinde para bulunmayan ve başka hizmetlerde tekrar kullanılmamış yeni bir test kimliği kullanılmalı
  • Web3 ödeviyse yalnızca testnet kullanılmalı ve zararsız görünse bile gerçek cüzdan bilinmeyen projelere bağlanmamalı

Enfeksiyon durumunu doğrulama göstergeleri

  • macOS ve Linux’ta önce şu öğeler kontrol edilir
    • node, pack, scdata, ldata, npm-compiler, vhost.ctl ile ilişkili çalışan süreçler
    • 45.146.252.17 veya 7641, 7646, 7649 portlarıyla bağlantılar
    • geçici dizinler, Downloads, Desktop, Documents, Library altındaki pack, scdata, ldata, vhost.ctl
    • */.npm/vhost.ctl işaret dosyası
    • indirilen proje içindeki IP, UID, /api/service/makelog, node scdata, node ldata, node pack dizgeleri
  • Windows’ta şu öğeler kontrol edilir
    • node, npm, cmd, powershell süreçleri arasında komut satırında pack, scdata, ldata, node -e, IP adresi, Get-Clipboard bulunan öğeler
    • 45.146.252.17 veya uzak port 7641, 7646, 7649 için açık TCP bağlantıları
    • %TEMP% altındaki pack, scdata, ldata, vhost.ctl, .npm\vhost.ctl
    • mülakat deposunun klonlandığı dizin içindeki bilinen C2 dizgeleri
  • Çalışan bir Node süreci, söz konusu IP bağlantısı veya pack·scdata·ldata çıktılarından herhangi biri bulunursa sistemin açığa çıkmış olduğu varsayılmalıdır
  • Bu göstergeler, analiz edilen örneğe özel ilk kontrol maddeleridir; tam bir adli inceleme prosedürü değildir

Enfekte sistemin temizlenmesi ve gizli bilgilerin değiştirilmesi

  • Öncelikle bilgisayar ağdan ayrılmalı, enfekte ortamda inceleme, hata ayıklama veya yeni gizli bilgileri kopyalama işlemlerine devam edilmemelidir
  • Kanıt gerekliyse silmeden önce şu veriler korunur
    • süreç listesi
    • ağ bağlantıları
    • şüpheli dosyalar
    • tarayıcı geçmişi
    • kötü amaçlı depo
  • Ardından node pack, node scdata, node ldata, node -e, npm-compiler, vhost.ctl ile ilişkili süreçler sonlandırılır ve geçici dizinlerdeki pack, scdata, ldata, .npm/vhost.ctl kaldırılır
  • Tek kullanımlık bir VM ise ve normal Node çalışmalarını koruma gereği yoksa, macOS ve Linux’ta pkill node, Windows’ta ise tüm node süreçlerini zorla sonlandırma kullanılabilir
  • Kötü amaçlı depo ve node_modules silinir; ancak ek analiz gerekiyorsa ZIP kopyası çevrimdışı olarak saklanır
  • Yalnızca dosya silmek yeterli değildir; şu gizli bilgiler değiştirilmeli veya iptal edilmelidir
    • SSH anahtarları
    • GitHub ve npm token’ları
    • bulut anahtarları ve API anahtarları
    • dağıtım sırları
    • tarayıcıya kaydedilmiş parolalar
    • aktif oturumlar
  • Cüzdan seed’i veya özel anahtarın enfekte sisteme temas etmiş olma ihtimali varsa, temiz bir cihazda yeni bir cüzdan oluşturulmalı ve varlıklar taşınmalıdır

Geliştirme araçlarının güven sınırını kötüye kullanan saldırı

  • Geleneksel antivirüs ürünleri bu depoyu tespit etmedi ve ödevi çözmekte kullanılan popüler yapay zeka kodlama ajanları da projeye gizlenmiş kötü amaçlı kodu tanımlayamadı
  • Tailwind, JavaScript yapılandırma dosyalarını Node modülü olarak değerlendirdiği için, geliştirme araçları, build script’leri, editör entegrasyonları, Tailwind CLI, bundler’lar ve CI işleri yapılandırmayı yüklediği anda 95. satırdaki IIFE çalışır
  • Normal Tailwind yapılandırması 94. satıra kadardı ve bunun arkasına yaklaşık 27KB’lık obfuscate edilmiş kod eklenmişti
  • İndirilen payload, yapılandırmayı yükleyen kullanıcıyla aynı işletim sistemi yetkileriyle çalışır
    • yerel dosyalara, tarayıcı profillerine, kayıtlı kimlik bilgilerine, cüzdan eklentisi verilerine, SSH anahtarlarına, ortam değişkenlerine, paket token’larına, bulut kimlik bilgilerine, kaynak koda ve panoya erişebilir
    • CI’da çalışırsa dağıtım sırları, build çıktıları, registry kimlik bilgileri ve production erişim token’ları da açığa çıkabilir
  • Gerekli düzeltme, tailwind.config.js içindeki obfuscate edilmiş JavaScript bloğunu tamamen kaldırmaktır

Henüz yorum yok.

Henüz yorum yok.