强网杯 2021 baby_diary
强网杯 2021 baby_diary
漏洞
申请和show的时候没有检查负数
在申请空间的时候有off-by-one。
利用
泄漏
在bss段附近存放了地址,该地址指向的内容还是这个值。
二进制文件会输出地址处指向的内容
思路为指定index为负数进行泄漏。实际上sub_15DF函数进行了一些操作,校验size,并且取出了heap_addr+size(size太大可能进入不可访问内存)
内存布局如下
当index为-11的时候可以打印0x000055bc5b75a008指向的内容(还是这个值)。
需要当-11作为index的时候有一个合适的size能过校验,查看内存映射,发现0x7f00或0x5500加上0x000055f12f7ac008之后都会在heap附近,为了绕过校验,需要申请大chunk,设置为非0值然后进行爆破(在上图0x55bc5b75a114地址处四个字节加上0x000055bc5b75a008之后有概率进入刚申请的堆空间)。
泄漏libc
构造unlink,用最后写入的一个字节修改块的preve inuse位。 这里需要0x100的chunk才能触发unlink。
有一个不好构造的prev size位用最后写入的一个字节来写入(需要的prev size大小如0x0100)
此时有重合的chunk
290那行是原本的size,合并后的chunksize在2a0那行,接下来要做的就是释放一个原本在2a0 chunk范围内的空间(进入tcatch),然后申请(从tcatch中获得)然后再申请一块空间(此时会切割2a0的chunk)使被切割后的chunk的fd,bk写入到前面申请的chunk地址处。 如下图
到这里完成泄漏libc。
然后用add写入__free_hook
到某个tcatch的fd,然后alloc申请到空间写入system的地址
一些小技巧
可以让pwndocker的tmux左右分割
context.terminal =['/usr/bin/tmux', 'splitw', '-h', '-F#{pane_pid}' ]
下端点现实东西比较方便
def debug_1(addr,show=[],PIE=True):
debug_str = ""
if PIE:
text_base = int(os.popen("pmap {}| awk '{{print $1}}'".format(p.pid)).readlines()[1], 16)
for i in addr:
debug_str+='b *{}\n'.format(str(hex(text_base+i)))
for item in show:
debug_str+='x /50xg {:#x}\n'.format(text_base+item)
gdb.attach(p,debug_str)
else:
for i in addr:
text_base=0
debug_str+='b *{:#x}\n'.format(text_base+i)
gdb.attach(p,debug_str)
捕获下面异常可以用来方便爆破
except EOFError: