ConfuserEx Deep Analysis ~ AntiDump
Selamlar, bu yazımda ConfuserEx adlı “obfuscate” yazılımının içerisindeki AntiDump korumasının derin analizini yapacağım.
Bu Yazı Neler İçeriyor?
Bu yazı ve “ConfuserEx Deep Analysis” başlığı altında açılan yazılar genel olarak şu başlıklardan oluşacak :
- ConfuserEx Nedir? (*)
- AntiDump Nedir?
- ConfuserEx AntiDump Çalışma Prensibi
- Basit Bir AntiDump Yazalım
- ConfuserEx Anti-AntiDump
ConfuserEx Nedir?
ConfuserEx is an free, open-source protector for .NET applications. It is the successor of Confuser project.
.NET Uygulamaları için bedava, açık kaynaklı bir koruma. “Confuser” projesinin varisidir.
AntiDump Nedir?
AntiDump, bellekten alınmak istenen dökümü bozan, engelleyen bir yapı. (?)
ConfuserEx AntiDump Çalışma Prensibi
ConfuserEx korumasının AntiDump’ının çalışma prensibini inceleyebilmek için kodlarını Github sayfasından alalım.
https://github.com/yck1509/ConfuserEx/blob/master/Confuser.Runtime/AntiDump.cs
Şundan da bahsetmeliyim ki ConfuserEx, Runtime çalışabilen korumalardan oluşuyor. Yani AntiTamper, AntiDebugger, AntiDump gibi korumalar için Runtime şekilde çalışabilecek korumalar üretiyor ve daha sonrasında seçilen .NET dosyanın içine bunu enjekte edip Rename işlemine sokuyor. Örneğin linkini yukarda verdiğim AntiDump.cs dosyası Runtime çalışan (.NET Kütüphaneleri dışında farklı bir kütüphaneye ihtiyaç duymuyor(DLL) ) bir kod parçası.
https://github.com/yck1509/ConfuserEx/blob/master/Confuser.Protections/AntiDumpProtection.cs
Bu kısımda gördüğümüz kısım, Runtime çalışan class’ı içerisine enjekte eden kısım :
Runtime çalışan class’ın DLL Import kısmına bakalım.
Bu kısımda kernel32.dll ‘i içerisinde bulunan VirtualProtect apisi “VirtualProtect” ismi ile class’a dahil ediliyor.
VirtualProtect ?
Changes the protection on a region of committed pages in the virtual address space of the calling process.
Çağrılan işlemin sanal adres alanındaki korumayı değiştirir.
- “lpAddress” : İşaretçi, koruması değiştirilecek alanın başlangıç adresi.
- “dwSize” : Erişim koruma özniteliklerinin değiştirileceği alanın bayt cinsinden boyutu. lpAddress parametresi ve (lpAddress + dwSize) aralığında
- “flNewProtect” : Koruma seçeneği. Daha detaylı bilgi için https://docs.microsoft.com/en-us/windows/win32/memory/memory-protection-constants sayfası ziyaret edilebilir.
- “lpflOldProtect” : Belirtilen adres bölgesindeki ilk adresin önceki erişim koruma değeri.
https://docs.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualprotect
VirtualProtect üstünden de basitçe geçtiğimize göre şimdi kodları inceleyelim.
Initalize method’u içerisindeki kısım yani en başından başlıyoruz.
- uint türünde “old” adlı değişken tanımlanmış. Bunun kullanım amacı VirtualProtect apisinde bulunan “lpflOldProtect” parametresi olacak. out anahtar kelimesi ile parametre gönderilecek.
- “module” değişkenine yüklenen modül aslında programın kendisi. Program runtime şekilde çalıştığından bu şekilde yazılmış
- “bas” adlı değişken, programın memory’deki başlangıç yerini yani MZ Header başlangıç adresini tutuyor. Bunu göstermek istiyorum.
Örnek bir proje oluşturuyorum Visual Studio’dan ve ConfuserEx’den sadece AntiDump korumasını içerisine enjekte ediyorum. Output olarak “Confused” klasörünün içerisindeki dosyayı dnSpy üzerinde açıp .cctor kısmına gidiyoruz. (Neden buraya gidiyoruz diyecek olursanız Inject Phase kısmında bunu .cctor’a enjekte ettiğini göreceksiniz.) dnSpy üzerinde açtıktan sonra GetHISTANCE fonksiyonunun çalışmasından hemen sonra olan satıra breakpoint koyuyoruz ve programı yine dnSpy üzerinde debugluyoruz. breakpoint koyduğumuz yere gelince program duruyor ve dnSpy’ın “locals” penceresinden bas adlı değişkenimizin değerine bakınca “0x006A0000” adresini görüyoruz(sizde farklı olacaktır). HxD yazılımını başlatıp “Open Main Memory…” özelliğini kullanarak açılan sekmeden programımızı seçiyoruz. CTRL + G kombinasyonu sonucunda açılan sekmeye “bas” değişkeninden aldığımız değeri yazıyoruz (0x silmeniz gerekiyor) daha sonra OK tuşuna bastığınızda sizi direkt MZ ascii karakterlerinin olduğu yere götürecek yani en başa.
- Geldik hesaplama kısmına. Aslında bu kısmı daha iyi görebilmek için son hesaplama satırının hemen altında bulunan if yapısına breakpoint atıp continue diyoruz ve Locals kısmında. istediğimiz değişkenin değerini HxD üzerinden inceleyelim.
“ptr2” değişkeni aslında kod kısmında “sectNum” olarak geçiyor. İlgili adres ile birlikte HxD üzerinde offset araması yaptığımız zaman direkt bizi .text section’unun başına götürüyor.
- Bu kısımlarda boğulmayıp aslında direkt işlem yaptığı kısımlara gitsek daha mantıklı olur diyerek, debug ekranında daha rahat görebilmeniz açısından rename işlemine soktuğu VirtualProtect apisini temsil eden fonksiyonu tekrar ismini değiştiriyorum. İlk yaptığı VirtualProtect işlemine breakpoint atıp continue diyelim. “ptr7” değişkeninin tuttuğu alanı 11 bytelık yer şeklinde 64U flagi ile iznini değiştiriyor. VirtualProtect’i anlatırken verdiğim “memory protection constants” sayfasına giderseniz 0x40 constant’ının “PAGE_EXECUTE_READWRITE” iznini sağladığını göreceksiniz (64U onluk tabanda yazılmış hali onaltılık tabanda yazımını görmek için imleci üstüne getirirseniz dnSpy gösterecek). Locals kısmından ptr7’nin tuttuğu adrese gidiyoruz. ptr8 alanı da hemen öncesi CorExeMain .NET Flaglari. Silince dnSpy okuyamıyor programı…
Bu kısım… ptr2 adresinin tuttuğu alana gittiğimizde Section Headers’ları göreceğiz.
Bu kod parçası sectionlar içerisinde dolaşarak hepsinin ismini siliyor.
Bu kısımda BSJB flag’inin hesaplanmasını yapıp 4 byte’lık alan ayırıp onu siliyor. BSJB, meta veri tablosundaki ilk girdidir (Meta veri motorunda çalışan 4 adamın adlarının ilk 4 harfinin birleşimidir) evet, biraz saçma bir detay oldu :D.
AntiDump korumamız bu kısımları sildikten sonra dnSpy içerisindeki modules sekmesi ile dump alalım. Gördüğünüz gibi bütün flagler silindiği için ve section isimleri silindiği için okunamıyor.
Basit Bir AntiDump Geliştirelim.
Başında uyarayım bu sadece bir sürü yöntemi olduğunu gösterme amaçlı bir antidump olacak yani o kadar stabil çalışmıyor.
Runtime MZ Header Erase işlemi yapan bir kod parçacığı. Bu programı dump aldığımız zaman şöyle bir görüntü ile karşılaşıyoruz :
Anti-AntiDump
AntiDump olan bir .NET uygulamasından nasıl dump alırız? Bunun iki yöntemi veya birçok yöntemi olabilir.
1) JITFreezer (Bunun kodlarını inceleyelim) 2) x0rz’s antidump fixer tool ( BackBox üstadıma selamlar o7 ) x0rz bunun kodlarını obfuscate etmiş yani incelenmesini istemediği için mi o kısmı tam olarak bilmediğim için istemiyordur diye kodlarını deobfuscate etmeye gerek yoktur diye düşünüyorum.
JITFreezer
Çalışma prensibi çook basit.
clr.dll yüklendiği sırada uygulamaya suspend atıyor yani duraklatıyor tek işlevi bu. Suspend attığı sırada daha uygulama tam olarak yüklenmemiş olacağı için hiçbir fonksiyon çalışmamış olacak. Bu sırada dump alırsak AntiDump hiç devreye girmemiş olacak.
KULLANILABİLECEK MUHTEŞEM ÖTESİ KAYNAKLAR
https://www.codeproject.com/Articles/5841/Inside-the-NET-Application https://ring0.info/posts/pe-dosya-formatina-dalis