首页
社区
课程
招聘
[原创]从BookWriter看house_of_orange原理【新手向】
发表于: 2017-12-15 13:55 19481

[原创]从BookWriter看house_of_orange原理【新手向】

2017-12-15 13:55
19481

0x00 背景


      最近在学习house_of_orange技术,house_of_orange技术已经和house_of_lore、house_of_Spirit一样,成为一种堆溢出利用技巧,思路来自ctf-HITCON-2016的同名题目。最近学习到这里,看了github上shellphish/how2heap中的讲解和多篇题解对漏洞触发条件依然不太理解,恰巧做到了pwnable.tw上的BookWriter题目,真正实践了一次。

0x01题目分析


首先这是一道逻辑清晰的题目,主要有添加书页、浏览书页、编辑书页和查看信息功能。


其中定义了两个int[8]数组在BSS段,分别存储书页的地址和书页内容大小信息,两数组在BSS段上位置相邻。

1. 添加操作使用从0~8顺序查找的方式,进行堆块申请,堆块大小由用户输入,并且用户此时可获得一次输入堆块内容的机会。


2. 查看书页内容操作,用户可输入0~7的数字查询书页内容。


3. 编辑操作,用户同样可输入0~7数字,根据存储在size数组的大小进行写入,并利用strlen函数,重新更新书页的size值。


4. 查看信息。打印一系列信息。


题目中给出的libc.so版本是 2.23.


0x02 漏洞分析


1. 堆地址泄露

可以主要到bss段上的排列顺序是char author_name[0x40]、int page[8]、int page_size[8]。在输入author_name时,输入长度是0x40,打印时使用%s,造成泄露page中存储的堆地址。

2. 堆溢出

堆溢出漏洞有两处,第一处在edit函数中,用户输入完数据后,程序使用strlen函数重置page_size的值,当用户输入与下一堆块中的size相连时,strlen会返回用户输入长度+下一堆块size,再次编辑造成了下一堆块的size被篡改。第二处在于add函数中对允许写入的判断是i<=8,page[i]==NULL。可以发现&page[8] = &page[0]的地址,当page[0]被覆盖为一个堆块地址时,造成了对page[0]超长写入,可以覆盖到很远的地址,可以说是一个等号引发的血案了。

0x03 漏洞利用


整个程序中没有出现free函数,常规的UAF、Double free都不存在。看了很多的house_of_orange资料,恰好想到使用这种方法,这种攻击成功需要如下条件(shellphish上提供的方法):

1. heap地址

2. 堆溢出

3. libc地址

4. libc 2.23及以下版本(2.24版本开始对vtable有check,不过也可以绕过)

house_of_orange思路简介:

1. 首先修改top块的size,然后申请一个较大的块(不大于mmap申请的阈值,大于top块当前大小),当修改的size满足一定条件时,原来的top会被释放到unsorted bin。

2. 通过堆溢出覆写原top内容,主要是构造IO_file_plus指针中的函数虚表,并伪造bk指针为unsorted bin攻击做铺垫。

3. 当再次申请内存时,造成unsorted bin attack,将__IO_list_all覆写为原top头地址,由于unsorted bin结构的破坏,程序异常,会在malloc中调用malloc_printerr函数进行错误打印,在malloc_printerr中调用__libc_message,进一步调用abort(),再调用 _IO_flush_all_lockp(),在其中调用了_IO_OVERFLOW(fp,EOF),这个函数是使用虚表调用,如果可以覆盖调用的虚表,就可以达到执行system('/bin/sh')。


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 4
支持
分享
最新回复 (10)
雪    币: 212
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
顶下
2017-12-15 16:12
0
雪    币: 201
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
house of orange 其实不用leak heap,也能做
2018-9-30 19:20
0
雪    币: 763
活跃值: (343)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
4
二进制忍者 house of orange 其实不用leak heap,也能做
恩恩,这个也是后学到的技术,当时做这个题的时候还不会。
2018-9-30 21:55
0
雪    币: 61
活跃值: (2420)
能力值: ( LV9,RANK:260 )
在线值:
发帖
回帖
粉丝
5
pwnda 恩恩,这个也是后学到的技术,当时做这个题的时候还不会。
师傅不leak heap的话,怎么把程序指向我们的控制流呢?能不能给个链接?
2018-12-3 14:59
0
雪    币: 763
活跃值: (343)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
6
iddm 师傅不leak heap的话,怎么把程序指向我们的控制流呢?能不能给个链接?
可以参考一下 hctf-2017 simp1e师傅出的这题,可以不用泄露堆地址执行system("/bin/sh"),也可以用绕过大于2.23版本libc的vtable检测,链接如下:http://simp1e.leanote.com/post/Hctf-2017-babyprintf
2018-12-3 16:28
0
雪    币: 61
活跃值: (2420)
能力值: ( LV9,RANK:260 )
在线值:
发帖
回帖
粉丝
7
pwnda 可以参考一下 hctf-2017 simp1e师傅出的这题,可以不用泄露堆地址执行system("/bin/sh"),也可以用绕过大于2.23版本libc的vtable检测,链接如 ...
嗯嗯 谢谢师傅
2018-12-3 20:29
0
雪    币: 199
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
8
额,不好意思。这个EXP似乎有问题。不确定是我的虚拟机的问题,还是程序本身,在 info() 的时候会申请一个0x1000的堆块。所以这里都不能使用info函数(虽然可以曲线救国,获取需要的东西)。再就是,EXP里泄露出的 libc 的地址也是错的,因为偏移错了。
顺便,我加不了第八个块(难道是我pwnable下的程序被patch了?但是ida的时候没发现问题啊。)
2019-9-12 00:32
0
雪    币: 763
活跃值: (343)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
9
mb_muzzkfuo 额,不好意思。这个EXP似乎有问题。不确定是我的虚拟机的问题,还是程序本身,在 info() 的时候会申请一个0x1000的堆块。所以这里都不能使用info函数(虽然可以曲线救国,获取需要的东西)。再 ...
不确定是你说的哪个问题,如果说偏移错了应该是libc版本的问题,这个exp是快两年之前写的了,那个时候是可以打通的,不确定tw
是否有patch了 :)
2019-9-12 16:20
0
雪    币: 199
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
10
抱歉,从你给的下载连接和从网站下载的程序的MD5值来看,是同一个程序。所以麻烦您再重新调下,exp是有问题的:2号块view时返回的,不是unsortbin的地址,而是largebin里的一个,因此,一个块能获得heap和libc。
最后于 2019-9-13 23:31 被mb_muzzkfuo编辑 ,原因:
2019-9-13 22:53
0
雪    币: 763
活跃值: (343)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
11
mb_muzzkfuo 抱歉,从你给的下载连接和从网站下载的程序的MD5值来看,是同一个程序。所以麻烦您再重新调下,exp是有问题的:2号块view时返回的,不是unsortbin的地址,而是largebin里的一个,因此, ...
我用这个exp重新打了一遍还是可以打通的,不太清楚中间还有什么坑点:)
2019-9-18 12:21
0
游客
登录 | 注册 方可回帖
返回
//