Bir zararlı geliyor uzaktan | Malware Analiz Notları #1

Selamlar, hatırı sayılır bir süredir zararlı yazılımlar üzerine çalışıyordum. Ofansif & Defansif farketmeksizin araştırıp bir şeyler test etmeye çalışıyordum ki AV’lere dadandığım dönemler olarak adlandırabiliriz bu dönemleri. Analiz tarafında hala çok zayıf olduğumu düşündüğümden ve daha da bu noktaya yüklenmem gerektiğini bildiğimden ve bu zamana kadar elde ettiğim bilgi birikimini unutmamak adına bir seri oluşturmaya karar verdim. Amacım basit. Piyasaya düşmüş, tespit edilmiş(gün gelir masumu düşer elimize onun feriştahına ineriz) zararlıların ötesini berisini incelemek. Nasıl çalışıyor, amacı ne, anatomisini gerçeğe yakın derecede çıkarabilir miyiz tarzı sorulara cevap vermek. Kısaca yazı boyunca teorik bilgilerle kafa şişirmek yerine zararlı yazılımları “deneysel” şartlar altında inceleyip, incelediğimiz zararlıya bağlı olarak yeni geliştirme teknikleri öğreneceğiz ve bize gerektiği kadarı ile analiz tekniklerine değineceğiz.

Ufaktan alet çantamızı açmaya başlayalım ve klasik kamu spotumuzu geçelim.

“Dikkat ! Zararlı dediğimiz arkadaşları incelerken izole bir ortam yaratın ve analiz işlemlerini bu ortamda yapın.”

malshare’da(ücretsiz malware örneklerine erişebileceğiniz bir site, piyasada ne detect oluyorsa düşüyor) neler var diye arama kutusunu zorlarken bir domain dikkatimi çekti. “http://ssrdevel*****.co.za” bu maşallahı olan domain üzerinden yayılmayı bekleyen yahut downloaderından emir bekleyen “masum” yirmiye yakın şüpheli exe bulunuyordu. İyi hoş alayım birini yanıma diyerek “d2.exe” isimli bir zararlıyı koydum çantama.

Analiz olayı 2 taraflı, statik ve dinamik. Statik dediğimiz şey dosya halinde diskimizde bekleyen zararlının process’e çevrilmeden sadece dosya bilgisi ve içeriği ile yapılan analiz türüne deniliyor diyebiliriz. Bu analiz olayında bakış açınız sadece “malicious bulam, c&c paneli ele geçirem” olmamalı. Saf, temiz bir program o. Onu tanımaya çalışın, onun hakkında her bilgi analiz raporumuzun içine girecektir. En basit bilgiler bile.(Dosya uzantısı, dosya bilgisi, strings’leri vs vs.) Fazla gevezelik etmeden konumuza dönelim. Zararlı elimde, bildiğim tek şey exe olduğu. PE bilgisini incelediğimde .NET çatısının 2.sürümünü baz alan (sebebi her girdiği bilgisayarda 2.sürümün default olarak yüklü geldiğinden bu sürümü baz alarak derlenen yazılımlarınsorunsuz çalışabilmesi) 2 mb küsürlük bir dosya olduğunu görüyoruz.

Screenshot_3

.NET görünce ister istemez içimi mutluluk basıyor. Halay başının halayın hiç bitmeyeceğini zannedercesine seviniyorum. Neden ? Kod okumak basit. Bir yazılım .NET’de yazıldı ise ne kadar karıştırma olursa olsun native’lere nazaran decompile olayı basit kalıyor, obfuscate mi var, özel bir metod yok ise de4dot zaten işimizi görüyor. Modlu obfuscator mı kullanmışlar, yama çakarız d4dot’a sıkıntı yok. Ondan hızlıca kodlara bakmak için dnSpy’ı açıp dosyamızı içeri bırakıyoruz. İstisnai durumlar olabiliyor onlara diğer yazılarda değineceğiz.

Screenshot_1

Form içerisinde cıvıl cıvıl elemanlar, byte döndüren bir fonksiyon. Basit duruyor, 2 mb dosya, icon desen şişirmez o kadar. Var bi çakallık diyerek kodlara yakından bakıyoruz.

Screenshot_2

Load resources’tan dosyayı alır, butona fişeği verir ve zincirleme reaksiyonumuz başlamış olur.Screenshot_4

Çağrılan eleman arkadaş bunun kadar bi de yerin altında var diyeceğimiz satırların çağırıcısı, lideridir.Basit bir string dizisi abartmaya gerek yok. Aşağıda buton 1 için önemli olan şeyleri sağlayacak.

Screenshot_5

Buton 1 adlı arkadaş döngüye girer ve string dizisi içerisinde sıralı halde duran satırlarının spesifik adları ile bu satırları çeker ve “workitout” adlı fonksiyona byte cinsinden paremetre olarak verir. Arından buton 3’ün fonksiyonunu çağırır. Önce “workitout”‘a bakalım.

Screenshot_6

Programda “all” adı altında defaultta null değerine sahip bir değişken vardır, bu fonksiyon arkadaş parametre olarak aldığı byte değerlerinin aktarımını sağlar.

Screenshot_7

Buton 3 ise rawAssembly adında bir byte array oluşturur ve bunu buton 2’e kullanması için verir ve çağırır. Çağırmadan önce aşikar bir şekilde “all” değişkeninde bulunan değeri kriptografik bir fonksiyona maruz bırakmıştır. O satır dizilerini ilk görünce b64 zannetmiştim, olmadığını görünce iş çıktı diye sevinmiştim. Screenshot_8

Bu çağırdığı fonksiyonu eğer haşır neşirseniz basit crypterlardan hatırlarsınız. İşlevi oldukça anlaşılır bence. Programda önceden DES ile şifrelenmiş başka bir programa ait string türünden veri tutuluyor, bu fonksiyon da o verileri gömülü anahtar ile decrypt ediyor. Bu işlemlerden sonra buton 2’e geçiliyor.

Screenshot_9

Buton 2 ise temiz halde bulunan rawBytes’ları alıp ep’de run ediyor. Buraya kadar her şey anlaşılır ve problem yok. Ancak henüz zararlı bir şey görmedik, yani zararlımız bu değil. Bu arkadaş sadece basit ve klasik bir ön yükleyici. Amacı belli başlı metodları barındırarak asıl zararlı kodların bulunduğu kısmı dışa aktarmak ve bu süreçte AV’lerden kaçmak. Bu form yapısı ve butonların hiyerarşi olayı bir aralar güzel işe yarıyordu ancak şuan kek.

Şimdi bizim o rawBytes’ları elde etmemiz gerekiyor ve bundan dolayı ya çalışma esnasında müdahale edip bellekten alıcaz ya da kod üzerinde manipülasyon gerçekleştirip temiz programı ele geçiricez.

İlk aşama bana meşakatli geldi, ondan manipüle candır diyerek dnSpy’ın kod düzenleme özelliğine koşuyorum.Farkındaysanız rawAssembly adlı değişkene decrpyt edilmiş kodlar buton 3’ün fonksiyonunda atanıyordu ve asıl zararlıyı çağıracak olan buton 2 buton 3’te çağrılıyordu. Bundan dolayı düzenlememiz gereken nokta buton 3.

Screenshot_10

Şöyle tek satırlık bir kod ekleme ile işimi tamamlamış oluyorum. Atanan değişkeni zararlıyı bellekte çağırmak yerine sadece dosyaya yazıp bırakıyordu ki benim de istediğim bu.

Screenshot_11

Çıkan dosyamızın kaba olarak PE bilgisi, ön yükleyicisi ile aynı. Karşımızda .NET, yürekler gene sevinçli, gözler gene parlak. dnSpy’a yuvarlayıp okumamız gerek kodları.

Screenshot_12

“Decryption” sınıfını görünce “baba gene mi uzantıların ve gene mi kod çıkaracaksın” dedim ve sezdim. Başka sürprizler bekliyor gibiydi.Sınıf isimleriyle işte kötülüğü akıt buradan dediğim bir alan ve klasik “fişekleme” formu önümde duruyor.

Screenshot_15.png

Resources bölümünde 2 adet şifrelenmiş uygulama bulunuyor.(şifreli oldukları kanısına dosyaları export edip incelediğimde baktım, az sonra nasıl çözeriz ona değineceğiz)

Screenshot_13

Load’da work fonksiyonu çağrılmış.

Screenshot_14

Work kötülük tarafımızdan bir yükleme fonksiyonunu tanımlayıp çağırmış. Yavaş yavaş yükleme aşamasında neler yapılıyor bakalım.

Screenshot_16

Arkadaşımız ResManager tanımlıyor ve bu arkadaş üst tarafta bulunan “settings” isimli resources dosyasının işlerini üstlenecek. “decrypter” adı altında “Decryption”‘ı çağırarak “getDecryptKey” adlı byte türündeki arkadaşı bazı işlemler için kullanıyor.

Screenshot_17

O işlem şu şekilde. Basit bir decryption fonksiyonu. Paremetre olarak aldığı veriyi çözdükten sonra geri döndürüyor. Evet buraya kadar her şey güzel. Bu işlemlerden sonra “bootstrapIt” adlı fonksiyon çağrılıyor ki can alıcı kısım birazcık burada.

Screenshot_18Screenshot_19

Ayar dosyasındaki değerlere göre içerisinde bulundurduğu fonksiyonları sırayla çağırmaya başlıyor. Ayar isimlerinden fonksiyonların ne işe yaradığını tahmin ettiğinizi düşünerek burada vakit kaybetmek istemiyorum. Sadece şu en üst tarafta yazan “getMainFile”‘ı ileride kullanacağız. Ona bakalım.

Screenshot_20

Şifreli uygulamalar var demiştik. Bu arkadaş oradan dosyayı alıp decrypt ediyordu, decrypt edilmiş dosya ise “_mainFile” adlı değişkene atanıyordu. Aynı dosyaya incelemek adına ulaşmam gerektiğinden decrypt fonksiyonunu ve şifreli programı yeni bir proje içerisinde buluşturarak çözmeyi denedim.

Screenshot_21

Şu şekilde derlediğim kod işimi gördü ve nur topu gibi yeni bir program verdi bizlere.

Screenshot_22

Yuvamızın yeni çocuğu diğerleri ile aynı sınıftaydı gene. Evet inceleme listemizde bir dosya daha var, onu bu önyükleyici ile işimiz bittikten sonra incelemek üzere kenara bırakıyorum.

Res’teki dosyayı çıkardı, kötücül fonksiyonları ayar dosyasındaki yönergelere göre çağırdı ve ve enjeksiyon aşamasına geçti. Enjeksiyon aşamasında gene veriyi res’ten alıyordu, res’teki değere göre hangi uygulamanın hedef alınacağı belirtiliyordu. Değerimiz 6 olduğundan kendi kendine enjekte olacağı aşikardı. “path” adlı değişkene dosya yolunu atadıktan sonra arkadaşımız “Runnit” altında bulunan “run” fonksiyonuna dosya yolunu ve o res’te bulunan şifreli dosyanın çözülmüş halini veriyordu.

Screenshot_23

Çok uzun olan bu fonksiyonun tüm halini malesef koyamadım. Çok uzun, üşendim valla. Ancak fonksiyonun ilk başından incelemeye başlarsanız runPe modülünün çalıştırma fonksiyonu olduğunu farkedeceksiniz. Çözülmüş halde bulunan res’teki dosyayı bellekte çalıştırıp işini bitiriyordu. Evet güzel gerçekten, kod okumaktan ciğerimiz soldu bu noktadan sonra bu ön yükleyicide inceleyecek önemli bir şey kalmadı. Yavaş yavaş diğer arkadaşa geçelim ve en sevdiğimiz dnSpy ile incelemeye başlayalım.

Screenshot_24

Yuvarladık dnSpy’a ve bir oh çektim. Şükürler olsun. Kodlar karıştırılmıştı, kafamız bulanacak, clean hale getiremezsek mindfuck olup onun verdiği haz ile zararlımızı bir hırs ile inceleyecektik. İsteğimden olsa gerek arkadaş de4dot’a dayandı. Manuel olarak clean edebilirdik ancak kodlara göz gezdirdiğimde basit bir obfuscate olduğunu ve dikkatli incelendiğinde okunabildiğini farkettim. Önce klasik Resources incelememizi yapalım.

Screenshot_25

Resources’te iki adet dosyamız bulunmakta. Bunları dışarı aldığımda beni şaşırtmayarak aynı sonucu verdiler. IELib gerçekten lib’di ancak Player farklıydı. Bu arkadaş ile işimiz bitince onu da inceleyeceğiz.

Screenshot_26.png

Screenshot_27

Programın EP’sine gittiğimde bir karnaval bekliyordu beni, şifreli stringler. Zararlı geliştirirken klasik bir yöntemdir. String ortada bırakılmaz, gömülü anahtar ile şifrelenip eklenir, çalışma esnasında aynı anahtar ile çözülüp kullanılır. Process halinde iken doğru zamanda okumaya çalışırsanız sıkıntı yaşamazsınız ancak statik incelerken “bu ne olm” diyebiliyorsunuz ancak çözüm basit. Decrypt fonksiyonunu alıp ufak bir program yazdım. Şifreli stringleri otomatik olarak çekip bana veriyordu ve işimi gerçekten kolaylaştırdı.

Screenshot_28

Başta bu şekildeydi. Dediğim gibi basit. Arkadaşlar Rijndael kullanarak işlerini görmüşler. Evet incelemeye devam.

Screenshot_29

Bilgisayar adı alınıyor, webpanellerle bağlantı kuruluyor. Yayımcısına hizmet ediyor. Çok fazla kod olduğundan elde ettiğim bilgileri paylaşayım en iyisi.

Screenshot_30

stringlerin bir kısmı bu şekildeydi. Zararlının her köşesi belli bir düzene sahip olduğundan otomatize bir araç tarafından oluşturulduğu belliydi. Dolayısıyla RAT yahut stealer olduğunu düşündüm.

Screenshot_31

EP’nin son aşamasında res’ten dosya çekip kaydediyor ardından bu çalıştırıyordu.Stringi decrypt ettiğimde karşımda “Player”‘ı gördüm ve sıranın ona geldiği kanısına vardım. Bu yazma işleminde temp klasörü hedefteydi ve rassal üreteç ile bir dosya adı oluşturulduktan sonra exe uzantısı ile kaydediliyordu. Zararlı arkadaşımız bu işlemleri yaptıktan sonra çalışmaya zaten devam eder durumda kalıyordu. RAT ya da Stealer olduğu kanısına şurdan vardım; registry üzerinden değiştirdiği değerler incelendiğinde at koşturabileceği bir ortam yaratmak için gereken değerleri değiştirmiş, programın bir pattern’i var, kullandığı değerler statik değil, değişken olduğundan kural bazlı bir mekanizmaya sahip, onun dışında enjekte/bulaşma evresi dediğimiz evre klasik yöntemlerle sağlanmış ve kullanılan bazı fonksiyonlar eski zararlıları hatırlattı bana ondan dolayı bariz bir RAT ya da stealer. Kod üzerinde incelememiz bittiğinde biraz sörf ile düşüncelerimizi daha sağlam kanıtlarla destekleyebiliriz. Evet Player arkadaşa geldi sıra. Kendisi gene .NET 2.versiyonu baz alan bir uygulama ve obfuscate edilmemiş halde.

Screenshot_32

Yeni bir thread oluşturuyor ve runner fonksiyonu yer alıyor içerisinde.Screenshot_33Runner denen arkadaş ise bir doğurtkanlık edası ile yer alıyor makinamızda. Zararlının kabataslak analizi bitti nerdeyse. Biraz process boyutunu inceleyelim ve gözden kaçırdığımız bir şey var mı bakalım. Öncesinde internet ne diyor bu konuda onlara göz gezdirelim. Şimdi elimizde bir zararlı var ve bu arkadaşların yakalanması için antivirüs yazılımları ön plana çıkıyor. Kendileri belli analiz tekniklerinin otomatize halini barındırıyor olup imza tabanlı, dinamik bellek analizi, fonksiyon eşleştirmeli vs vs uzayıp giden ve her birinin başarı oranının çok yüksek olmadığı yöntemler ile tespit etmeye çalışıyorlar. Eğer zararlı hazır bir araç ile hazırlanmışsa başarı oranları yükseliyor. Bundan dolayı zararlımızı virüstotale atmak gerekli diyerek RAT olayını bize yaşatan arkadaşın sonuçlarını inceliyoruz.

Screenshot_34

İlk olarak 15 aralıkta taratılan arkadaş maşallah delik deşik olmuş. 42/66 yakalanma oranına sahip olan zararlımız trojan diye kayıtlara geçmiş ve AhnLab ise NjRat olduğunu belirtmiş ki bana da en mantıklı gelen bu. .NET ve RAT denince farklı türde çok RAT olmasına rağmen NjRat popülerlik bakımından önde geliyor ve olma olasılığı yüksek.Process monitor ve wireshark kullanarak dinamik analizini gerçekleştirdiğimde bulduğumuz sonuçlardan farklı şeyler bulmadık aslında. Çıkan çıktılar çok fazla olduğundan buraya aktarmam mümkün değil ancak kaba taslak şemasını çıkaralım.

  • cikti1.exe çalışır
  • Kuvvetle muhtemel W7 ve son güncelleme olmayan W10’larda çalışan UACBypass metodu kullanılarak evntvwr üzerinden yönetici yetkisini elde edip powershell ile kendini yetki ile başlatır.
    ” “C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe” Start-Process -FilePath “C:\Users\admin\AppData\Local\Temp\cikti1.exe” -wait “
  • Yönetici yetkisine sahip olan dosyamız dyndns üzerinden ip sorgusu gerçekleştirir.
  • Ardından UAC’ı tamamiyle kapatır.
  • temp klasörüne rastgele isim ile Player adlı programı çıkartır.
  • Ardından başlangıçta çalışması için çıkardığı dosyanın dosya yolunu “HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run” anahtarına yazar.
  • Son olarak çıkarttığı dosyayı çalıştırır ve SON.

Analiz sırasında elde ettiğim veri ve dosyalara ulaşmak için : Mega.Nz

Parola : infected

Okuduğunuz için teşekkürler. Eksik gedik vardır elbet. Kompleks yapıda olduğundan kaçırdığım noktalar olabilir. Belirtirseniz düzeltirim elbet. Yeni zararlılar ile görüşmek üzere. İyi günler.

 

Bir Cevap Yazın

Aşağıya bilgilerinizi girin veya oturum açmak için bir simgeye tıklayın:

WordPress.com Logosu

WordPress.com hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Google fotoğrafı

Google hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Twitter resmi

Twitter hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Facebook fotoğrafı

Facebook hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Connecting to %s