pwnable.tw
01 前提--->链接
02 Challenges
01 start
IDA似乎看不出啥来
扔到peda里反汇编看一看,因为是x86(file可知),先写再读。
就知道这么点信息,没啥头绪,猜测是shellcode解。
write的长度是0x14,read的长度是0x3c,明显读的比写的长
覆盖_exit的offset是20,两种方法
1 在_start的ret处下断点--->到退出是20,32位对应4字节,5*4=20
2 直接利用peda的函数
写shellcode--->execve('/bin/sh',null,null)
为什么是execve('/bin/sh',null,null)
呢?因为system("/bin/sh")的fork是execve啊,这里直接调用execve就好啊,看了下面这个图是不是懂一点?解释一下图---> 运行./hello --->子程序fork()--->调用execve,参数就是./hello(理解到这里就可以,不必往下先);同理啊,调用system--->fork()--->execve,参数是/bin/sh 或者/sh
有个问题哎--->把shellcode写到哪呢?
也不知道写到哪里?就一个.text
段,那就往它上面写呗
结果:居然又让你输入,这说明没有覆盖ret啊
为什么呢?
然后我改了改,又报错!上面那张图我理解的不对,add esp,0x14
---> 应该从esp+0x14
处开始(找个地方,存储shellcode)--->那就有一个问题,这个时候esp
是谁呢?我画个图,整理一下思路
所以EPI指到add esp,0x14
的时候把esp
赋值为0x8048087
,即左边esp
指向的位置,这个时候add esp,0x14
等于右边那个. 这个想法也是错误的
参考博客:[Pwnable.tw] – start
总结:
1 泄露栈的地址相当于泄露esp的地址
2 其他参考博客
poc:
1 菜是原罪
2 这题还是出的挺不一般的,首先它不是leave, ret ,而是直接ret
3 add esp,0x14 这处想明白了就明白了,另外泄露栈地址就是泄露esp啊
4 今天早上我就想,非得栈顶吗?反正是栈,我找到栈的栈底-0x100,然后我再这块放shellcode,不行吗?不行!为什么呢?因为栈总是栈顶入栈啊。除非我把栈顶的地址修改成栈底-0x100,或许这样行