House of force
溢出修改topchunk的size,分配一个使size_t溢出的evil_size,使下一次分配在目标位置,进行修改。
|
|
Bctf2016 bcloud
分析
|
|
程序一开始让输入name、org、hostname,输入字符串函数存在null byte overflow。
输入name函数中,字符串数组在栈中后部紧邻指针变量,所以strcpy会将该指针一并拷贝入0x40的空间(实际可用0x44),并且null byte覆盖topchunk的最低字节。可以泄露堆的地址
输入org、hostname函数中,存在同样问题,可覆盖的更多的字节。可以覆盖topchunk的size
程序功能菜单
|
|
new note: 读入size存入全局数组,分配size+4的空间将指针也存入全局数组,读入字符串
show note: 打印WTF? Something strange happened.
edit note: 修改存储的内容,根据size数组和指针数组
delete note: free分配的空间
syn: 修改sync标识。在这里没用
思路
在input_name函数中,泄露堆的地址,由此可以计算evil_size;在input_orghost中覆盖topchunk的size为0xffffffff。使用atoi_got、free_got覆盖bss段所存储的全局指针数组,使用edit note函数将free_got处修改为puts_plt,使用delete note函数泄露libc base,最后使用edit note 修改atoi_got为system函数地址。
House of force
这个手法还是比较简单的,就是一开始没有找到漏洞。。只发现了null byte overflow。
使用input_orghost函数覆盖topchunk->size为0xffffffff,接下来就是计算evil_size了。
泄露的heap地址为分配的第一个0x40地址,称之为leak_heap。leak_heap+0x40就是此时的topchunk,后来又分配了两个0x40,此时topchunk = leak_heap + 0x40 + 0x48*2
。到目标地址,还需要分配两个chunk,也就有两个8字节的头,new note中又加了4字节,所以evil_size = dest_addr - topchunk - 8*2 - 4
。
exp中,直接发送这个负值就可以,int到size_t,其中所存的数字没有变化,只是两种类型的解读不一样。原来我想发送unsigned值(evil_size&0xffffffff),结果发现32位程序中atoi只会将其解析为4字节int最大的正数,即0x7fffffff。
Reference
- how2heap house_of_force.c
- https://uaf.io/exploitation/2016/03/20/BCTF-bcloud.html