Stack Based Overflows #3

PATTERN

Simge Karahan
3 min readDec 22, 2020

Merhaba, serinin bu yazısında Pattern kullanarak Stack’te EIP değerini kontrol etmeyi açıklayacağım. Bir önceki yazıda Stack’te nasıl buffer overflow yapıldığı ve ilk yazıda da EIP’in, çalıştırılacak bir sonraki komutun adresini tuttuğunu incelemiştik. Bu yazıda amaç EIP’i bulabilmektir. Çünkü program EIP’te yazan yeri çalıştırıyor, bu nedenle programın akışını kontrol edebilmek için aslında EIP’i kontrol edebilmek gerekiyor.

https://www.hebunilhanli.com/wonderland/bof-101/

Yanda görülen bu yapı Stack’in yapısıdır. Buffer overflow ile EIP’e kadar gidip EIP’in konumunu bulmayı amaçlıyoruz.

EIP’e ulaşabilmek için kullanılan mantık, tüm Stack’i bir önceki yazıdaki gibi A ile doldurmak yerine belirli bir düzene göre oluşturulmuş bir diziyle doldurmaktır. Bu sayede EIP’in yerini tespit edebiliriz.

Belirli bir düzene göre bir veri oluşturmak için ise Kali Linux’da Pattern kullanılır. Örnek bir veri için aşağıdaki komutu incelediğimizde oluşan sonuçta Aa0Aa1 şeklinde büyükHarf-küçükHarf-rakam düzeninde bir veri oluşmuştur. Görüldüğü üzere belirli bir düzene sahiptir. Örnek:

pattern_create.rb -l 5000 ile bir veri oluşturup bu veriyi Python kodunda dosyaya yazdırılacak veri olarak girdiğimizde, artık Stack’e veriler belirli bir düzene göre oluşturulmuş şekilde yazılır. Bu sayede EIP’de ne yazdığını bileceğimiz için EIP’in konumunu da bulabiliriz. Koddaki düzenlemeye göre dosyaya önce 25000 tane A yazıp sonra bir patterne göre veri yazılıyor. Bu işlem tamamen EIP’i bulmak için yapılmaktadır.

Oluşturulan “crashPattern.m3u” dosyasını Windows XP sanal makinede mp3 converter uygulamasıyla çalıştırıp assembly karşılıklarına bakmak için:

  • Immunity Debugger açılır.
  • MP3 Converter programa atılır ve run edilir.
  • run edilince converter uygulaması açılır ve buradan yüklenecek dosya (crashPattern.m3u) seçildiğinde assembly karşılıkları açılır.
Immunity Debugger

Bu işlemden sonra EIP’deki değeri “42386A42” olarak sarı kutucuklu yerde görüyoruz:

Şimdi patternde bu değeri bulmamız gerekiyor. Pattern yaratmak için create komutu kullanılmıştı, patternde bir değer bulmak için ise offset komutu kullanılır:

Ve patterndeki konumunu 1074 olarak bulduk. Kodda da 25000 tane A’nın ardından bu pattern yazıldığına göre EIP, 25000+1074=26074 konumundadır. Yani 26074 tane değer yazıldıktan sonra yazılan diğer değer EIP’e yazılır diyebiliriz.

O zaman yapacağımız işlem 26074 tane A harfi ve EIP’e yazmak istediğimiz değeri peş peşe dosyaya yazdırmak. EIP’e belli olsun diye XXXX değerini girdiğimizde bu char değerinin ascii hx karşılığı olan 585858 değerini EIP’de göreceğiz. Yeni kod:

Ve işte 585858 yani XXXX değerini EIP’te gördük. Yani EIP’e ulaşabildik.

Not: Adresleme biçimi little endion olduğu için aslında tersten yazıldı ama buradaki değerler aynı olduğu için bunu farketmedik. Örneğin ABCD yazsaydık EIP’de ABCD’nin asci karşılığ olan 41424344 yerine DCBA görürdük yani 44434241 olarak görürdük.

EIP’in adresine bakmak içim, yazdığımız bir sürü A harfinin sonunda XXXX olarak immunity debuggerdan bakabiliriz:

Sonuç olarak, Stack’te EIP’in konumu bulundu ve EIP’e yazdırılan değer manipüle edildi. Bu sayede EIP kontrol edilerek shellcode’lar çalıştırılabilir. Çünkü EIP çalıştırılacak bir sonraki komutun adresini tutan registerdır ve biz onu artık kontrol edebiliyoruz.

--

--