Malware Koruma Mekanizmaları Part 1
Sisteme bulaşmış bir zararlı yazılım tespit edildiğinde, zararlı yazılımın sistemde ne yaptığının bilinmesi büyük önem taşımaktadır. Zararlı yazılımın ne yaptığı bilinmeden sisteme nasıl bulaştığı, sisteme ne tür hasarlar verdiği (backdoor oluşturmak, dosyaları silmek vb.) veya hangi bilgilerin saldırganların eline geçtiği bilinemez. Böylece firma daha sonra gelebilecek saldırılara karşı savunmasız duruma düşer. Bu yüzden zararlı yazılımın analizini yapmak daha kıymetli hale gelmektedir. Bu kıymetin farkında olan saldırganlar, yazdıkları zararlı yazılımları, zararlı yazılım analistlerinin kullandığı metotlara karşı veya zararlı yazılım analizi yapabilen sandboxlara karşı çeşitli koruma yöntemleriyle korumaya almakta; böylece zararlı yazılımın gerçek doğasını gizlemektedir.
Bu yazımda koruma yöntemlerinden biri olan; IsDebuggerPresent fonksiyonundan bahsedeceğim ve bu tarz bir koruma yönteminin nasıl bypass edileceğini uygulamalı olarak göstereceğim.
IsDebuggerPresent Fonksiyonu Nedir ?
IsDebuggerPresent, user-mode debuger kontrolü yaparak prosesin debug edilip edilmediğinin kontrolünü yapabilen Windows fonksiyonudur. Zararlı yazılımın prosesi debuggerda çalışmıyor ise sıfır değerini döner ve zararlı yazılımın kendi kodunu çalıştırmaya devam eder. Eğer zararlı proses debuggerda çalışıyor ise sıfırdan farklı değer döner ve zararlı yazılım kendi doğasını gizlemek için çalışmaya zararsız kodlarından devam eder.
IsDebugger Tespiti ve Bypass Edilmesi
Öncelikle zararlı dosyanın debuggera sokmadan önce çalıştırarak zararlının ne yaptığını öğrenelim, zararlı dosyanın oluşturabileceği trafiği tespit edebilmek için ikinci linux sanal cihazında fakedns ve inetsim benzeri network simülasyon uygulamalarını çalıştırıyoruz. Böylece kurmuş olduğumuz ortamda dns, ftp, smtp, http ve https gibi protokollerinden gelen isteklere cevap vererek internet trafiğini simüle etmiş olacağız. Bir yandan da Wireshark’ı açarak trafiği izliyor olacağım.
Zararlı yazılım çalıştırıldıktan sonra wiresharkta 1.234.27.146 IP adresine TCP isteği gittiğini tespit ettim
Şimdi zararlı yazılımı debugger içerisinde çalıştırarak aynı sonucu elde edebilecek miyim onu deneyeceğim. Zararlı yazılım analizinde kullanılan x32/64 dbg tool içerisinde zararlı yazılımımı açıyorum.
Şimdi debug > Run yolunu izleyerek uygulamayı çalıştırıyorum. Zararlı yazılım çalıştıktan sonra bu sefer herhangi bir tcp trafiğinin oluşmadığını görüyorum. Bu durumda analizini yaptığım zararlı yazılımın debug altında farklı davrandığını düşünebilirim.
Şimdi zararlı yazılımın debugger’ı nasıl tespit ettiğini bulmak için ilk önce Windows API’larını kontrol ediyorum. Bunun için CPU tabında sağ click yaparak Search for > Current Region > Intermodular Calls yolunu takip ederek zararlı yazılımın kod içerisinde çağırdığı Windows fonksiyonlarını görebiliriz. Bu fonksiyonları kontrol ederken ilk olarak kernel32.IsDebuggerPresent fonksiyonu dikkatimizi çekmektedir.
Bu fonksiyona sağ tıklarak Follow in Disassembler’a tıklarsak kod içerisinde fonksiyonun çağrıldığı yere gitmiş olacağız.
Fonksiyonun çağrıldığı yeri belirledikten sonra fonksiyonun çağrıldığı adrese sağ tıklayarak Breakpoint > Toggle’a tıklayarak fonksiyonun çağrıldığı yerde kodu durdurmak için breakpointimizi set etmiş oluyoruz.
Breakpoint set edildikten sonra Debug > Run yolunu izleyerek kodumuzu breakpointe kadar çalıştırıyoruz.
Kodumuz IsDebuggerPresent fonksiyonu çağrılmadan önceki durumuna gelmiş bulunmakta şimdi fonksiyonun içerisine girmeden bir sonraki instruction’a gitmek için Debug > Step Over’a tıklıyoruz. Böylece kodumuz IsDebuggerPresent fonksiyonunu çağırarak dönüş değerini RAX register’ı içerisinde bize dönmüş oluyor. Hatırlarsanız IsDebuggerPresent fonksiyonu debugger tespiti yaptığında dönüş değeri olarak sıfırdan farklı bir değer dönüyordu. Aşağıdaki ekran görüntüsünde göründüğü üzere fonksiyon değer olarak 1 dönmüş görünmektedir. Zararlı kodumuz daha sonra rax regester’ının 32 bitlik kısmını alarak test instruction’ı yardımıyla bit bit and işlemine sokuyor ve daha sonra sonucu sıfırdan farklıysa 140001216 adresine atlayarak uygulamanda çıkıyor böylece zararlı işlemler tespit edilmeden gizliliğini koruyor.
Peki biz bu tespit yöntemini nasıl bypass edebiliriz burada debugger kullanmaktan vazgeçmeden kullanabileceğimiz 2 yol var birisi geçici birisi kalıcı yol. Geçici yöntem rax register değerini 1 den 0’da değiştirmek bunun için rax register’ına çift tıklayarak çıkan ekrandaki 1 değerini sıfır yapabiliriz. Ancak bu yöntemle sadece geçici bir çözüm yolu sağlamış oluruz kodumuz tekrar debugger’a yüklediğimizde bu noktada tekrar 1 değerinin geldiğini göreceğiz.
Kalıcı olarak bypass etmek istiyorsa eğer zararlı dosyamızı patchlememiz lazım peki bunu nasıl yapacağız öncelikle bize lazım olan hangi instruction zararlı kodu hiç bir işlem yapmadan çıkışa yönlendiyor bunun cevabını bulmak, bizim inceledeğimiz zararlı için bu instruction jne malicious file.140001216 instructionıdır.
Bu instructiondan kurtulmak için ilgili instruction’a çift tıklayalım;
Karşımıza çıkan ekranda bulunan yerin tümünü seçerek herhangi bir işlem yapmayan NOP instructionı ile değiştirelim ve kodun boyut bütünlüğünü korumak için Fill with NOP’s kutucuğunu işaretleyelim böylece jnz ve NOP instructionları arasında boyut farkı kadar daha NOP koyarak dosya boyutunu sabit tutacaktır.
Bu işlemi yaptıktan sonra file>patch file yolunu izleyerek zararlı dosyamızı içerisinde yaptığımız değişiklerle birlikte farklı bir dosya olarak kaydedelim.
Bu sayede zararlı kodumuz artık debugger içerisindede çalışabilecektir.
Sonuç
Zararlı yazılımlar, doğaları analistler tarafından keşfedilmesin diye çeşitli koruma yollarını kullanmaktadırlar bugün ki yazımda bu yollardan görece daha tespit edilip bypass edilebilen IsDebuggerPresent fonksiyonundan bahsettim okuduğunuz için teşekkür ederim. Hepinize zararlılardan uzak temiz günler dilerim.
Eline sağlık.
Çok teşekkür ederim Hakan Bey