house-of-orange专题总结
前言
最近在BUUCTF刷题,见到了house-of-orange真题,当时学的时候只是大概了解了原理,正好结合文件攻击总结一下
原理
house of orange 是一种堆利用手段,给的题目中没有free函数,攻击者可以通过覆写top chunk的size字段修改其为一个比较小的值,之后在malloc一个大于此值的chunk的时候让原top chunk进入unsorted bin,而原堆块通过brk或者mmap扩展,再从中分配堆块。通过这种方式可以让top chunk进入unsorted bin,从而间接free堆块。
题目特征就是没有Free,需要有一个堆溢出的漏洞可以利用。构造的时候注意top_chunk_addr + fake_size要是0x1000对齐,一般把倒数第三个字节改成0x00即可
Hitcon-CTF house of orange
题目分析
题目一共有三个功能,Build、See和Upgrade分别对应Add、Show和Edit.
Build函数可以Build 4个堆块,最大可以分配的size为0x1000,每次先分配一个house_chunk,其中存储price_chunk和name_chunk,读取price、name和color
See函数可以打印出house的name和price和color等内容
Upgrade有一个读取length并根据length编辑的溢出,溢出长度最多可达0x1000
漏洞利用
先分配一个堆块,利用Upgrade修改top chunk的size,再Malloc一个较大的堆块,使得top chunk进入unsorted bin。再Malloc一个large bin,从unsorted bin中切割出来,利用其bk泄露libc地址,再Upgrade这个large bin,可以用fd_next_size泄露heap地址。
再使用Upgrade溢出修改Unsorted bin,结构为:
“/bin/sh\x00”+p64(0x61)
p64(0)+p64(_IO_list_all-0x10)
p64(2)+p64(3)
‘\x00’*0xa8
fake_vtable_addr
之后Malloc一个堆块的时候会触发unsorted bin attack,具体的原理在之前SCTF的easy heap中有介绍,最终去执行fake table的system函数,参数为fp的”/bin/sh\x00”
exp.py
1 | #coding=utf-8 |
pwnable.tw Book Writer
程序逻辑
程序有4个功能,Add、View、Edit和Info
Add可以添加9个chunk,0x6020a0为chunk_list,0x6020e0为chunk_size_list,注意添加chunk的条件是i>8且chunk_list[i]不为NULL,我们的chunk[8]=chunk_size[0],从而得到一个可读size超大的堆。
View可以查看堆内容
Edit根据size的大小读取数据,并更新新的size为strlen(content),这里也有漏洞,当分配0x18的堆块并填充0x18时,content会跟下一个堆块的size连上,strlen的大小会包含size的部分。
Info函数可以修改author的值,最多可以读取0x40大小,而get_input函数没有给末尾强制加’\x00’,在chunk_list有值之后再修改author可以泄露堆地址。
漏洞利用
先利用Edit的溢出漏洞进行house of orange攻击,修改top chunk的size,得到一个Unsorted bin,分配一个large bin,用它泄露堆地址和lib基址(这里其实应该用author那个泄露堆地址,分配large bin的话后面要发送的数据量就太大了)。
分配8个堆块,从而可以覆写chunk_list[0],构造fake_file和fake_vtable,因为是根据strlen的结果修改size_list,我们可以发送数据的前面是’\x00’,这样就会让chunk_size_list[0]被改为0,从而可以malloc一个堆块,最后触发system(“/bin/sh\x00”)拿到shell。
exp本地可以,远程失败,原因是刚提到的数据量的问题,懒得改了。
exp.py
1 | #coding=utf-8 |
后言
看p4nda师傅看雪的一篇帖子提到HCTF 2017 有道baby printf也用到了house of orange,且不需要泄露heap地址,直接从libc中找fake vtable,在构造fake file的时候对应偏移修改system地址及参数地址即可,这个方法我尝试在book writer复现,但是libc中没找到所说的vtable,在libc 2.24中找到了,以后需要再搞吧,这里给个链接。