Ret2esp / Ret2reg
Ret2esp
Çünkü ESP (Yığın İşaretçisi) her zaman yığının en üstüne işaret eder, bu teknik, EIP'yi (Komut İşaretçisi) bir jmp esp
veya call esp
komutunun adresiyle değiştirerek ilgilidir. Bunu yaparak, shellcode, üzerine yazılan EIP'nin hemen ardına yerleştirilir. ret
komutu çalıştığında, ESP bir sonraki adrese işaret eder, tam olarak shellcode'un depolandığı yer.
Eğer Adres Alanı Düzeni Rastgeleleştirme (ASLR) Windows veya Linux'ta etkin değilse, paylaşılan kütüphanelerde bulunan jmp esp
veya call esp
komutlarını kullanmak mümkündür. Ancak, ASLR etkinse, bu komutları bulmak için muhtemelen savunmasız programın kendisine bakmanız gerekebilir (ve PIE karşısında başarılı olmanız gerekebilir).
Ayrıca, shellcode'u EIP bozulmasından sonra yerleştirebilmek, yığının ortasına değil, işlevin işlemi sırasında yürütülen herhangi bir push
veya pop
komutunun shellcode ile etkileşime girmesini önler. Bu tür bir etkileşim, shellcode yığının işlevin ortasına yerleştirilmiş olsaydı meydana gelebilirdi.
Yetersiz alan
Eğer RIP üzerine yazdıktan sonra yazacak alanınız yoksa (belki sadece birkaç bayt), başlangıçta bir jmp
shellcode'u yazın:
Ve kabuğu erken yığın üzerine yazın.
Örnek
Bu teknik örneğini https://ir0nstone.gitbook.io/notes/types/stack/reliable-shellcode/using-rsp adresinde bulabilirsiniz ve son saldırı şu şekildedir:
Bu teknikle ilgili başka bir örneği https://guyinatuxedo.github.io/17-stack_pivot/xctf16_b0verflow/index.html adresinde görebilirsiniz. NX etkin olmayan bir taşma durumu var, $esp
adresini azaltmak için bir araç kullanıldı ve ardından bir jmp esp;
ile kabuk koduna atlandı:
Ret2reg
Benzer şekilde, bir fonksiyonun kabuk kodunun depolandığı adresi döndürdüğünü bildiğimizde, call eax
veya jmp eax
komutlarını kullanabiliriz (ret2eax tekniği olarak bilinir), kabuk kodumuzu yürütmek için başka bir yöntem sunar. Eax gibi, ilginç bir adres içeren herhangi bir kayıt kullanılabilir (ret2reg).
Örnek
Bazı örnekleri burada bulabilirsiniz:
strcpy
kabuk kodunun depolandığı tamponun adresinieax
'e saklayacak veeax
üzerine yazılmıyorsa, birret2eax
kullanmak mümkündür.
ARM64
Ret2sp
ARM64'te SP kaydına atlamaya izin veren komutlar yoktur. Sp'yi bir kayda taşıyıp ardından o kayda atlamayı sağlayan bir aygıt bulunabilir, ancak benim kali libc'mde böyle bir aygıt bulamadım:
Keşfettiğim tek şey, sp'nin kopyalandığı kayıt değerini değiştirecek ve ardından ona atlamadan önce (bu nedenle işe yaramaz hale gelecektir):
Ret2reg
Bir kaydın ilginç bir adresi varsa, uygun talimatı bulmak yeterli olacaktır. Şöyle bir şey kullanabilirsiniz:
ARM64'de, bir fonksiyonun dönüş değerini saklayan x0
olabilir, bu nedenle x0'ın, kullanıcı tarafından kontrol edilen bir tamponun adresini sakladığı ve yürütülecek bir kabuk kodunu içerdiği olabilir.
Örnek kod:
Fonksiyonun ayrıştırmasını kontrol etmek, taşma ve kullanıcı tarafından kontrol edilen tamponun adresinin x0
'da saklandığını görmek mümkündür:
Ayrıca do_stuff
fonksiyonunda br x0
adlı araca rastlamak mümkündür:
Binary PIE OLMADAN derlendiği için bu araca atlamak için bu aracı kullanacağız. Bir desen kullanarak taşma ofsetinin 80 olduğu görülebilir, bu nedenle saldırı şu şekilde olacaktır:
Eğer fgets
yerine read
gibi bir şey kullanılsaydı, PIE'yi atlamak sadece return adresinin son 2 byte'ını üzerine yazarak br x0;
komutuna dönüş yaparak mümkün olurdu, tam adresi bilmeye gerek kalmadan. fgets
ile çalışmaz çünkü sona bir null (0x00) byte ekler.
Korumalar
NX: Stack çalıştırılamazsa, kabuk kodunu stack'e yerleştirmemiz ve çalıştırmamız gerektiği için bu işe yaramaz.
Referanslar
Last updated