House of einherjar
0x01.简要介绍
house of einherjar可以让malloc返回一个任意大小的chunk,但条件有点苛刻::disappointed_relieved:
House Of Einherjar通过溢出修改chunk的prev_size和prev_inuse,
将prev_inuse改为0,让正常chunk被标记位被释放,
prev_size改为目标地址和正常chunk之间的距离,让正常chunk释放时去找fake chunk.
1 | /* consolidate backward */ |
在目标地址构造fake_chunk,需要伪造size位和fd,bk,fd和bk均指向chunk头部。
1 | if (__builtin_expect (FD->bk != P || BK->fd != P, 0)) \ |
通过释放正常的chunk触发向后合并让目标地址落入unsorted bin,
由于放入了unsorted bin,为了绕过检测,还需将fd,bk再次改为main_arena的地址
适用范围:存在off-by-null/off-by-one漏洞,可以在目标地址上构造fake chunk头。
例题分析:2016_seccon_tinypad
版本:2.23
0x02.保护分析

没有开启PIE,got表不可改。
0x03.功能分析
程序有4个功能add,delete ,edit,exit

add功能最多申请4个chunk,并且限制申请堆块最大为0x100

delete功能不会清空chunk list,存在UAF

edit功能会先strlen当前要edit的chunk,然后以此作为edit功能输入的最大长度,然后会把输入的内容存储到bss段的tinypad中,同时chunklist也在tinypad中,但是在0x100字节之上,无法覆盖。

程序的read_until功能存在off-by-null漏洞。
0x03.编写exp
#此程序下标从1开始,且每次输出菜单界面,都会附带输出4个chunk的内容
泄露地址
1 | add(0x70, 'a' * 8) |
通过UAF,泄露出堆地址,libc地址,和main_arena地址,然后free掉chunk4.
构造利用条件
1 | add(0x18, 'a' * 0x18)#1 |
计算出fake_chunk和正常chunk间的offset,再次计算出其中有几个\x00,通过循环,每次减少一个字节,通过read_until的off-by-null,把正常数据覆盖位\x00,在prev_size上构造出offset
然后edit chunk2,借此在tinypad高0x20位的地址上构造fake_chunk,
然后free(2),触发house of einherjar
可以看到unsorted bin中成功出现tinypad
然后再次edit,修改其fd,bk为main_arena
1 | payload=b'a'*0x20+p64(0)+p64(0x101)+p64(main_arena)*2 |
onegadget改返回地址
1 | environ=libc_addr+libc.sym['__environ'] |
environ中存在一个栈地址,因此把chunk1改为environ可泄露栈地址,把chunk2改为0x602148,在泄露地址后,把其改为返回地址,再次edit,把返回地址改为one_gadget,退出程序,即可getshell.