*

  • yanlis hatirlamiyorsam exploit'lerin stack'in ustune yazabildikleri fakat stack uzerinde code execute edilemeyen kosullarda (bkz: dep) (bkz: nx) kendi kodlarini calistirmak icin kullandiklari bir yontem. misal exploit kodunuz soyle bisey:

    mov ax, bx
    mov bx, 1
    call sysfunchede

    stack'e sadece return address'ler koyabiliyorsunuz. o zaman siz de return address'lerinizi oyle set ediyorsunuz ki arka arkaya su fonksiyonlarin sonlarini calistiriyo:

    kernel32!hetterehotterefunc+0x28283
    user32!bilmemnefunc+0x3737
    laylaymodule!hedefunc+0x3555

    tahmin edebileceginiz gibi bu fonksiyonlar tamamen alakasiz isler yapiyor olmalarina ragmen sirasiyla soyle bitiyorlar:

    ...
    mov ax,bx
    ret

    ...
    mov bx, 1
    ret

    ...
    call sysfunchede
    ret

    boylece siz sadece stack'e "donus adresleri" koymak suretiyle aslinda istediginiz kodu yaratip calistirabiliyorsunuz. e peki hangi fonksiyonun nasil bittigini nereden bileceksiniz yani kodunuz icin "return listesi" nasil yaratacaksiniz? onu da hali hazirdaki bu amac icin tasarlanmis derleyiciler analiz ederek sizin icin gerceklestiriyorlar.

    bu acidan bu isminin aksine bir programlama teknigi degil aslen. bir derleme teknigi.
  • şurdan http://en.wikipedia.org/…eturn-oriented_programming ek bilgiye ulaşabilirsiniz.
  • buffer overflowdan faydalanan bir tür güvenlik açığıdır.

    bu açıktaki asıl amaç programdaki her hangi bir yerde stackteki return adresinin üstüne yazarak istediğimiz yere dönmesini sağlamaktır. execute izni olduğu için geri dönülen kısım .text bölümünde olur. genelde daha fazla opsiyon sundukları için libc gibi büyük librarylerin kod segmentleri tercih edilir.

    istediğiniz yere dönebildiğiniz gibi ayrıca eğer stackteki return adressinin üstünde kalan kısmın da içine yazabiliyorsanız return ettiğiniz yerin de nereye return edeceğini belirleyebilirsiniz.

    bu şekilde birden fazla kod parçasını ard arda ekleyip çalıştırabilirsiniz ki bu da istediğiniz çoğu şeyi yapabileceğiniz anlamına gelir.

    örnek vermek gerekirse biri bir kod yazmışsa ve bu koddaki bir metodlardan biri şu şekilde ise.

    void hello()
    {
    char str[8];
    gets(str);
    printf(“hello \n”);
    }

    gets metodunun üstüne yazdığı yeri kontrol etmek için her hangi bir mekanizması bulunmadığı için eğer str’nin return adresinin 16 byte altını işaret ettiğini varsayarsak biz program bizden input istediğinde programa 24 karakterli bir input verirsek return adresinin içine yazabiliriz.

    eğer verdiğimiz inputun return addresinin içine yazılacak kısmı yani son 8 byte’ı programın her hangi bir yerindeki execute izni olan bir bir yeri gösteriyorsa metodun sonuna geldiğimizde kod oraya geri döner ve çalışmaya oradan devam eder.

    genelde bu açıktan faydalanmak için gadget adı verilen küçük kod parçaları kullanılır. genelde 2-3 byte olan bu kod parçaları eğer en son çalıştırmayı düşündüğümüz kısımda değil ise return opcodeu (x86-64 için c3) ile bitmek zorundadır yoksa kontrolü geldiği metoda geri döndüremez.

    pop instructionunun x86-64 mimarisinde tüm registerlar için bir byte olması onları

    pop <reg>
    ret

    formatındaki iki bytelık gadgetlar için optimal kılar çünkü gadgetın boyutu uzadıkça executeable segmentlerin içinde onu bulmak zorlaşır.

    bu iki bytelık gadgetların aynı zamanda metodlara argüman olarak verilebilen registerlari modifiye edebilmesi ve kontrolü istediğimiz bir yere geri devredebilecek olması eğer bir şekilde bu açıktan faydalanabilirsek istediğimiz metodları istediğimiz argümanlarla çağırabileceğimiz anlamıma gelebilir ki bu tehlikeli bir durumdur.
  • bounds checking hak getire olduğunda stack buffer overrun anomalisi barındıran programın call stack'inin manipüle edilip subroutine'lerin doğal nesting'inden (örn. d(c(b(a())))) faydalanılarak çalışan subroutine'in b yerine ahmetmehmet'e dönmesini sağlayan bir control flow hijacking tekniği. şayet program libc'ye dinamik linkliyorsa, buradaki ahmetmehmet system(3) gibi shell komutu çalıştırmaya yarayan bir prosedür de olabilir (bkz: return-to-libc attack). shadow stack (intel için linux desteği 6.6'da merge edildi), stack canary (return address'in overwrite edilmesi için bir önceki adresin de aynı şekilde overwrite edilmesi gerektiği için program başında belirlenen bir sayının orada olup olmadığını kontrol etmeye dayanıyor), executable space protection ve address space randomization gibi önleme yöntemleri mevcut.
hesabın var mı? giriş yap