本题的注意点
- 程序更改了global_max_fast的大小,导致我们释放的chunk无法进入fastbin中,都会进入unsortedbin里面
程序分析
直接切入正题:
- add():允许申请1-111大小的chunk
- del():没有uaf
- edit():使用strlen的返回值作为read的参数,off by one漏洞,申请0x?8的大小chunk时填充满该chunk,再次编辑该chunk,strlen就会将下一个chunk的size也也算作一个字节,所以我们可以控制chunk的size位
- show():正常输出
程序情况列述
- chunk会进入unsorted bin,不修改global_max_fast则无法使用fastbin attack
- 存在off by one 可以使用堆重叠,能够获取libc基地址
解题思路
- 堆重叠获取libc_base地址
- 使用unsorted attack更改global_max_fast,使chunk进入fastbin
- 使用fastbin attack更改malloc_hook为one_gadget
detailed procedures
-
注:结合exp来理解
-
申请4个chunk,利用chunk0修改chunk1的size使其包含chunk1,chunk2
-
再次申请大小为0x18的chunk,打印出chunk2即得到main_arena_addr+offset(该offset可以gdb调试得知其偏移,前提是本地环境和远端一致否则远端打不通)
-
后面的一系列操作就是heap重叠,利用一个chunk去改写另外一个chunk的bk(unsorted attack),heap重叠图在下面
-
修改了global_max_fast,使用fastbin attack伪造chunk修改malloc_hook为realloc_hook
-
修改realloc_hook为one_gadget原因如下,其要求一个都不满足
- 所以我们这里使用realloc来使得rsp+0x30为null,具体可以参考下面博客链接
- realloc之前会有以下操作,我们可以利用这些push和sub0x38来使得rsp+0x30为null,执行完这个操作就会call realloc,因为我们把malloc改成了realloc,realloc改成了one_gadget所以,就会call one_gadget,那么我们计算的时候要把call 抬高栈的8算上去
exp
#!/usr/bin/python3
# -*- coding:utf-8 -*-
from pwn import *
context.arch = 'amd64'
# context.log_level = 'debug'
sh = process('./babyheap')
#sh = remote('nc.eonew.cn', 10502)
libc = ELF('./libc-xm/libc-2.23-babyheap.so')
gdb.attach(sh,'''
b *$rebase(0xbfc)
b *$rebase(0xcdb)
b *$rebase(0xe50)
b *$rebase(0xdc2)
''')
def add(size, data):
sh.sendlineafter(