仅供个人学习参考

以ret2libc为利,我们在构造payload的时候有两种方式

1
2
payload1=b'a'*0x40+p32(system_addr)+p32(binsh_addr)
payload2=b'a'*0x40+p32(system_plt_addr)+p32(0xdeadbeef)+p32(binsh_addr)

这两种都可以打通,区别在于:
payload1中,system_addr指的是text段上的 call system的地址,如下图所示
1

payload2中,system_plt_addr指的是plt表上的system的地址,如下图所示
1

首先,我们要执行的system(“/bin/sh”),在汇编层面上长这样

1
2
3
lea eax, [address_binsh_str]
push eax
call system

call system可以进一步分解为

1
2
push ip     #执行system_addr之后的返回地址
jmp system_addr

所以直接调用plt system,需要先填入返回地址(覆盖ip)

而直接去调用call system 时,系统会先将下一条指令的地址(即紧跟在 call 指令后的指令地址)压入栈,然后跳转到system处开始执行。当system中的 ret 指令执行时,会从栈中弹出返回地址,并跳转到该地址继续执行主程序,也就是说系统自动帮我们填好了返回地址,不需要我们手动填入

payload1直接跳转到call system ,则不需要考虑填入返回地址,因为 跳过了push eax,而payload2是直接调用system函数,所以需要填入返回地址(由0xdeadbeef填充)