-
-
[原创]从BookWriter看house_of_orange原理【新手向】
-
发表于:
2017-12-15 13:55
19481
-
[原创]从BookWriter看house_of_orange原理【新手向】
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直播授课