glibc2.23——house of orange
glibc2.23——house of orange
什么是house of orange,这个名字的由来是2016年一道题目,它里面的内容跟orange有关,因此这个手法也就相应而出现,其实house of orange 有两个阶段
第一阶段
有的时候程序限制了你申请堆块的限制(导致不能申请到unsortbin),或者直接不给你free功能,那么泄露libc地址就成了一个麻烦,但是house of orange 就可以解决这个问题,如果我们能控制到top chunk的size位,那么我们就可以把它修改掉,这样top chunk 变小了,那么下次我们再申请一个比它大的堆块的时候,就有两种情况,第一种就是把当前top chunk 加入unsortbin,第二种情况就是直接使用mmap来申请一块内存了,当然我们想要第一种情况,那么就要注意申请堆块的大小
1、(unsigned long) (old_size) >= MINSIZE
2、 prev_inuse (old_top) = 1
3、 ((unsigned long) old_end & (pagesize - 1)) == 0)
而且修改的时候还要注意页对齐,比如原来是0x2fe1,那么就可以改成0xfe1
那么就可以通过上面的操作得到unsortbin,然后进行切片就可以得到libc的地址,但是在2.23以前要实现house of orange还需要知道heap的地址,因为我们要精准的伪造虚函数表(vtable)那么就要得到它的准确位置,因为2.23以前对它的检查没有那么严格,所以我们可以直接把它放到fake_chunk里面,那么怎么得到堆地址呢,如果我们可以申请到largebin范围大小的堆块,那么就可以利用largebin的fd_nextsize来泄露堆地址,当然如果不给我们largebin范围大小的堆块,如果题目没有开pie,或者已经知道程序基地址的情况下,若堆块的指针保存在bss段上,那么可以通过unsortbin attack 来泄露堆地址。
到目前位置准备工作已经做完了,那么让我们进入下一阶段。
第二阶段
下面介绍一下**_IO_overflow,这个函数会把fd也就是文件指针当作第一个参数,然后进行调用,而_IO_overflow**这个函数在vtable的第4个位置,那么就可以把这个位置放上system,然后fd位放上/bin/sh,这个函数怎么来的?
当glibc检测到内存出错的时候会执行
malloc_printerr -> __libc_message -> __GI_abort -> _IO_flush_all_lockp -> _IO_OVERFLOW
因此核心思想就是劫持**IO_list_all**,这个东西是_IO_FILE_plus_结构体的指针,一般指向_IO_2_1_stderr
而vtable,也就是_IO_jump_t,而_IO_file_plus
是一个结构体,它继承自 _IO_FILE
结构体,并且包含了一个 _IO_jump_t
类型的指针(即虚函数表)。
那么现在就可以开始劫持了,但是在此之前还需要了解一下_IO_list_all
可以看见vtable在结构体的末尾,指向_IO_file_jumps我们伪造的就是它,具体偏移可以数一下64位下在0xd8的位置,而chain字段在0x68的位置,那么改怎么控制呢,我们知道unsortbin的chunk指向main_arena+88的位置,那么它加0x68的位置就是main_arean+0xc0的位置,那么这个位置就是smallbin第6条链表的位置,如果我们把unsortbin的bk字段改成 _IO_list_all -0x10的位置,那么由于unsortbin attack我们可以知道,此时 _IO_list_all的指针也指向main_arena+88的位置,但是这个位置我们不可控,那么就要寻找一下可以控制的地方,那么如果把unsortbin的size位改成0x61呢,那么下次申请堆块的时候如果不满足条件就会加入到smallbin的第六条链子中,前面提到了,此时chain字段偏移位main_arena+ 88 +0x68此时正好是我们修改之后堆块的头部,那么我们就可以在此处伪造vtable
不过还需要绕过一个fflush函数的检查,也就是如果缓冲区有东西的话才会刷新,也就是保证_IO_write_ptr 这个大小要大于 _IO_write_base,即可。
例题演示
题目保护情况
64位ida载入
那么可以看见是没有free函数的,那么可以考虑使用house of orange来获取libc地址
而且满足我们申请大堆块的要求,而且没有开pie
而且edit函数可以进行溢出
分析
那么思路很清晰,通过house of orange 来泄露libc,然后通过unsortbin attack来泄露heap地址,之后通过溢出来劫持IO流,通过malloc错误来获取shell
1 |
|