Protostar Challenges Walkthrough (StackOverflow – BufferOverflow)

Öncelikle iyi akşamlar. 15 Aralık 2018 tarihli Binary Exploitation Atölyesinde aldığımız eğitim üzerine öğrendiklerimi paylaşmak için bu yazıyı yazıyorum 🙂 Öncelikle Furkan Senan hocama ve Sercan Sayitoğlu kardeşime bu güzel etkinlik için teşekkür ederim. Elimden geldiğince dilim döndüğünce protostar sistemi üzerinde stack overflow ve buffer overflow challenge’slerini tamamlayacağız 🙂 Buraya tıklayarak protostar içindeki programların C kodlarını görebilirsiniz. Ona göre exploit yazıp overflow saldırıları yapacaz. Başlayalım isterseniz 🙂

Öncelikle protostar hakkında bilgi vereyim. Stack overflow ve buffer overflow saldırı teknikleri üzerine geliştirilmiş içinde bölümler olan bir makinedir. Sisteme user:user kullanıcı adı ve şifresi ile geçiş yaptıktan sonra ip addr komutu ile protostar makinemizin ip adresini öğrenip linux makinemizden ssh ile bağlanarak bölümlerimizi geçmeye başlayabiliriz 🙂   

/bin/bash komutu ile bash’e geçtikten sonra “cd /opt/protostar/bin/” komutu ile bölümlerimizin olduğu dizine geldik. Şimdi ls komutu ile bölüm listesini görebilirsiniz 🙂 Yavaştan başlayalım 🙂 

STACK0 

Şimdi gdb stack0 komutunu terminalimize girelim. Daha sonra disas main komutu ile main fonksiyonlarını görelim. 

Biz intel versiyonunu sevdiğimiz için fonksiyonları intel’e göre ayarlayalım. İntel’e göre ayar yapmak için komutumuz “disassembly-flavor intel” komutunu girelim.

Stack0 kodlarını incelediğimizde gördüğümüz üzere program 64 bit’e kadar izin veriyor yani 65 bit çalıştırdığımızda ilk stack overflow yaparak ilk challenge’mizi tamamlamış olacağız 🙂 Öncelikle sisteme break *main komutunu girelim ve belleğin taşma noktasını bulalım.

(python -c “print ‘a’*65”) | ./stack0 komutunu girelim. Ve ilk stack0 bölümünü tamamlayalım 🙂 

İlk bölüm tamamlanmıştır 🙂 

STACK1

Stack1’de de stack0’da olduğu gibi intel ayarına göre ayar yapalım. Tek tek anlatmama gerek yok yukarıdaki gibi intel ayarlarına gelene kadar aynı komutları girelim.  Ve başlayalım 🙂 

Burda da istenen aslında aynıdır. Sadece tek fark modified kısmında değer vermemiz gerekiyor. Son kez, ‘A’ değerini değiştirerek, 0x000041 değerini elde ettik. Bu sefer 4 değeri taşmaya çalışalım; 0x61, 0x62, 0x63 ve 0x64 değerlerini taşıralım 🙂

Bu, girişin verildiği şekli yeniden sıralamamız gerektiği anlamına geliyor 🙂

Görebildiğimiz gibi, yığındaki arabellek taşması yoluyla, yerel değişkeni modifiedbelirli bir değere değiştirebildik 🙂 Bu stack’ide bitirdik 🙂

STACK2

Bu stack de aslında bir önceki stack’imiz ile aynı sayılır. Sadece
environment değişkenini bize öğretiyor 🙂 

FarkıGREENIE ortam değişkeninden girişi alır ve daha sonra strcpygirişi arabelleğe kopyalamak için kullanıyor.

strcpy (), tehlikeli bir işlev olarak kabul edilir, çünkü hedef arabellek, kaynak içeriği tutacak kadar büyük değilse, taşacak. Bu, GREENIE’deki verilerin 64 bayttan fazla olması bufferdurumunda taşacak demektir.

Bu zamana ayarlamamız gereken değer modified, 0x0d0a0d0a’dır.

Burda da enjekte etmek istediğimiz kod bir önceki stack ile aynıdır. Sadece enjekte edeceğimiz değer ve program argümanı farklıdır. 

STACK3

Bu Stack bir değişkenin değerini kontrol edebilmenin tehlikelerini gerçekten göstermektedir.

Burada, 4 byte’lık bir değişkenin (Stack1 & 2’deki ile aynı) sadece bu sefer üzerine yazılması gerekiyor, değişken bir fonksiyonu göstermektedir. Ayarlamamız gereken değer, işlev kazanmasının kendisidir.  Bu Stackte 
bir bellek taşması, bir işlev işaretçisinin denetimine izin verdiğinde, yürütme akışının nasıl kontrol edilebileceğini öğretir. 
İlk olarak, fonksiyonun adresini bulmalıyız:

objdump taşmanın ilk adresinin 0x08048424 adresinde olduğunu ortaya çıkardı . Taşma değişkenine yazmak istediğimiz değer budur.

Stack3’ü de tamamlamış olduk. 

STACK4

Bu stack’te çağrılmayan bir fonksiyon mevcuttur. Yani herhangi bir overflow yapabileğimiz fonksiyon yoktur. Öncelikle onu bulmaya çalışalım 🙂 

Stack alt belleğe genişler, böylece stack’i x ile genişletmek için, x ESP tarafından çıkarılır. Stack1’de görüldüğü gibi, veriler daha yüksek belleğe doğru yazılır. Şimdi buradaki sorun, nasıl yürütmeyi kontrol edebiliriz? Bir işlev çağrıldığında, çağrı talimatından sonra komutun adresi stack üzerine yerleştirilir, böylece işlev döndüğünde devam edebiliriz. Bu Return Adress olarak bilinir . Bir işlevden dönerken, gerçekte, bir işaretçiyi stack’ten EIP’ye ( yürütmeyi denetleyen Yönerge Göstergesi ) atıyorsunuz. Peki bu değeri EIP’te değiştirmeden önce stack’te değiştirsek ne olur? Fonksiyon yürütmesini kontrol etmiş oluruz 🙂 

Şimdi Return Adress’e ulaşmak için yazmamız gereken byte sayısını bulalım

Çıktısına baktığımızda işlemin 0xbffff760 başladığını göreceksiniz. Çerçevenin tabanı 0xbffff7a8’dir ve ardından kaydedilen çerçeve işaretçisini atlamak için 4 ekliyoruz .

76 bayt yazıldıktan sonra Return Adress’inin üzerine yazılmaya başlar ve böylece fonksiyonun yürütmenin nerede kontrol edilebileceğine karar verebiliriz. Şimdi, aramak istediğimiz işlevin adresini bulalım.

EIP’i ayarlayacağımız adresi bulduk. 0x080483f4 bu noktada ayarlama yapacağız.  Saldırımız aşağıda ki gibi olmalıdır 🙂 

Unutmayın, küçük endian, böylece yığındaki arabellek adresi \ xf4 \ x83 \ x04 \ x08 ‘e dönüşür.

Program bu kodu çalıştırınca çökmüş olabilir, ama önce istediğimiz şeyi gerçekleştirmiş olduk :))

Herbir stack’i resimli anlatacaktım ama kısa bir video ile sırayla anlatırım diye düşündüm. Geriye kalan 3 tane daha stack var. Onları da ilerleyen günlerde bu yazıyı güncelleyerek anlatacam. Takipte kalın 🙂

Bunlara da bakmak isteyebilirsin ;)

2 yorum

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir