题源:基本 ROP - CTF Wiki (ctf-wiki.org) 的ret2libc的例一。
这道题很简单,bin/sh和system的地址都给了,只需要控制程序执行流返回到相应的地址即可。但是我在编写payload的时候遇到了点小疑问。 为什么栈上system的地址和他的参数bin/sh的地址之间要隔着四个字节呢?
bin_sh_addr = 0x08048721
system_addr = 0x08048303
payload = b'a' * 112 + p32(bin_sh_addr) + p32(system_addr) #错误的payload
payload = b'a' * 112 + p32(bin_sh_addr) + b'a' * 4 + p32(system_addr)#正确的payload
这其实是对函数执行时候的栈变化不了解。如下图所示。那个padding1和padding2表示填充的无关杂数据。
这个图表示的起始就是一个典型的反应函数执行状态的栈帧。 函数的地址下面四个字节其实是返回地址,然后才是函数所用的参数。
上图化简之后就是下面这个。
延伸:
这道题是只执行一哥system函数即可,system是最后一个执行的函数,因此他的返回地址我们没必要写,填点垃圾数据就行,我们直须达到攻击目的即可。
但是有的题我们得执行一连串的函数,比如gets,puts然后才能来到system,那这样的话那个返回地址就不能瞎填,那个返回地址就是程序下一步要执行的函数,选择的地址千万要慎重,而且这块东西还有妙用。
最后:
仔细的原理可以参考下面这篇文章:(这篇文章讲的很好,巨适合小白,而且适合多次看,每次都会有新的收获)
手把手教你栈溢出从入门到放弃(上) - 知乎 (zhihu.com)
只需要看:0x50 Return2libc章节的内容即可。