rop链的基础原理rop是Return Oriented Programming(面向返回的编程)的缩写;
根据函数调用规则,当刚跳转到其它函数去执行时,从被调用者的视角看:栈顶是返回地址,紧接着是自己的参数(X86架构下);
然后,被调用者会对栈空间进行一系列操作,保存寄存器和存储临时变量,但在即将退出时会清理自己消耗的栈空间,以使其回到自己被调用前的栈空间,保持栈平衡;
最后,被调用者以ret指令结尾,ret指令将栈顶地址传递到IP寄存器,随后代码也就跳转到之前栈顶存放的返回地址处;
rop链即是基于以上这个简单的原理,在代码空间中寻找以ret结尾的代码片段或函数(代码片段称为Rop gadgets),组合可以实现拓展可写栈空间、写入内存、shell等功能,依靠ret将代码执行权紧握在自己的手里;
早期的ret2libc原理也是基于ret,如下payload:libc_system函数地址位置处于存在栈溢出函数被调用前的栈顶,溢出函数执行完后,就会跳到这个地址开始执行,下一个地址大小是libc_system函数执行完的返回地址,在下一个地址大小开始是libc_system函数的参数。
```payload = "A"*n + p32(libc_system) + p32(final_ret) + arg_addr + ...```
构造rop链的实例(x86)漏洞特征
描述: 假如存在这样一个漏洞:造成了栈溢出,可以溢出数个地址大小,至少能覆盖掉ret返回地址(EIP)和后面需要布置的一些参数空间。
环境:ubuntu 16.04 32, 开了ASLR、DEP,关闭CANNARY,目标代码不基址随机化,plt和got表项中存在write或print等可以打印地址的函数,有目标机器的libc.so
利用思路:
payload1:跳转到write或print函数(plt处代码),构造参数使其打印got表中某项地址,并在地址泄露任务完成后跳回存在溢出的函数,使其可以被再次利用;
搜寻libc.so中system函数的地址和字符串"/bin/sh",使