ROP(Return Oriented Programming):面向返回编程。
1:ret2text
栗题:(jarvisoj_level2)
32位程序:
64位程序:(jarvisoj_level2 x64)
利用找到的gadgets来构造ROP链,payload=p64(pop_rdi_ret_address)+p64(binshaddress) 此payload功能是设置rdi指向binsh。
2:ret2shellcode
栗题:(题目为jarvisoj_level1)
解释:
shellcode=asm(shellcraft.sh())的作用是生成一段获取shell的shllcode。
shellcode.ljust(0x88+4,b'a')的含义是将shellcode不足112的部分用a补齐。
3:ret2syscall
栗题:(题目:inndy_rop)
4:ret2libc(题目:jarvisoj_level1)
栗题:
先去执行write_plt,泄露read_got地址的值,因为前边的代码执行过read函数,所以got表会存储read函数真实的地址,得到read地址之后,继续38行根据libc的偏移找到read在libc中的偏移,计算出libc的基地址,然后根据这个基地址得到system函数的地址以及binsh的地址。 然后第一个payload返回地址填的是main函数,会再执行一边程序,这时候rop链payload2就执行了systembinshell,得到shell。
5:ret2csu
不是所有程序我们都能很方便的找到各种的gadgets,如pop rdi;ret, pop rsi;ret等等程序的gadgets,但在64位程序中,如果它利用了libc中的函数,就会存在__libc_csu_init这样一个函数,这个函数存在两段gadgets可以帮我们去对寄存器赋值并调用一些函数。
那如何利用csu构造ROP链泄露libc呢
栗题:(题目:jarvisoj_level5)
gdb调试发送payload看其在栈里的情况:
继续单步执行就到了第一个gadget1:
结合这个图片与下图一起看更清楚,能明白栈上的哪些值赋值给了对应的寄存器。
看下payload发送后跳转到gadget1运行,对应参数的状态:
既然我们能利用rer2csu来调用一些got表中的函数的话,那我们的思路就会简单些,第一步泄露libc,然后根据泄露的libc计算出system函数的地址,第二步,调用read函数向bss段读入system地址和binsh字符串。第三步,调用system('/bin/sh')来get shell。
所以分三步走:payload1先泄露libc,然后根据泄露的libc计算出system与binsh的地址,第二步payload把计算出的system地址与binsh地址调用read函数写入bss段,第三步再触发漏洞调用system(binsh);
总结:
Comments | NOTHING