House of Force2
Last Update:
Word Count:
Read Time:
Page View: loading...
House Of Force2
基于top chunk分配机制的利用,glibc会对用户请求的size_1和top chunk现有的size_0进行验证,如果size_0大于用户申请的chunk大小size_1,就会将从top chunk中切割出size_1大小的chunk,剩余部分放入top chunk。
如果top chunk足够大(size_0大于top chunk与目标地址的距离),malloc两次,第二次申请的chunk就会到目标地址处,实现一次任意地址写。
然而实际上top chunk 的size_0,一般不会这么大,所以这种利用手法的前提是可以修改top chunk的size_0大小,把它变成一个很大的数,一般是将其改为-1(32位:0xffffffff,64位:0xffffffffffffffff),因为在将size_0和size_1进行比较时会把size转换成无符号长整型数,因此-1也就是说unsigned long中最大的数。
glibc源码:
1 |
|
例题
bcloud_bctf_2016
程序实现了三个功能,增加一个chunk,编辑一个chunk的内容,删除一个chunk
add函数
1 |
|
add函数申请chunk时会创建一个存放所有chunk mem指针的全局数组,思考如果可以申请chunk到全局数组处,修改全局数组,实现任意地址写
edit函数
1 |
|
delete函数
1 |
|
delete函数在释放chunk时存在UAF漏洞
自定义一个read函数
1 |
|
三个参数,a1为要输入的地址,a2为输入大小,a3为截止符
先把前面的一些东西写好
1 |
|
分析:
程序没有show函数,无法泄露libc基地址,观察程序发现最开时让我们输入name等信息处存在漏洞
strcpy复制结束的标志是’\x00’,chunk的mem大小只有64字节,如果输入64字节,show函数会把堆地址泄露出来
1 |
|
再看另一个函数
栈布局
1 |
|
这里的v2,v3和v4,s都是位于栈上的,且在栈上s和v4的空间是连着的,而strcpy复制结束的标志是’\x00’,如果我们将s填满(b’b’*0x40),再将v3写为0xffffffff,那么strcpy(v4, v3);会把v4变为0xffffffff, strcpy(v2, s);会把b’b’*0x40+0xffffffff复制给v2,而v2也是一个size大小为0x40的chunk的mem指针,0xffffffff将覆盖到chunkv2 的下一位,而下一位正好是top chunk的大小,这样我们就成功将top chunk的大小改为了0xffffffff(-1)
1 |
|
之后就来算一下存放chunk指针的全局数组heap_array(0x0804B120)与top chunk的距离,
因为程序一开始就申请了三个大小为0x40的chunk(算上头指针为0x48),第一次泄露的heap已经算上头指针,heap与top chunk距离0x48*3-0x8=0xD0大小,再加上我们一开始泄露出来的heap的地址(heap_addr)就是top chunk的mem指针地址,
1 |
|
heap_array - top_chunk_addr是top chunk的mem地址,减去0x8字节是top chunk的头指针地址,
之后申请offset-0x10大小的chunk,之所以是再减0x8是因为我们要将heap_array作为mem区域来修改,第一次申请offset-0x10大小的chunk,为第二次申请的chunk预留出chunk头的0x8字节大小(0x4字节的pre_size位和0x4字节的now_size位)。再次申请chunk即为heap_array为mem区域的chunk,可修改heap_array数组,
1 |
|
之后编辑chunk_1来修改heap_array数组
1 |
|
此时chunk依次为0,free_got,__libc_start_main_got,heap_array+0x10(保持原3号chunk不变)
1 |
|
此时chunk_1存放free_got地址,编辑chunk_1,将free_got改为puts_plt函数地址
1 |
|
free(chunk_2),相当于puts(__libc_start_main_got),泄露__libc_start_main_got地址,得到libc基地址,得到one_gadget地址
1 |
|
再次编辑chunk__1将puts函数地址改为one_gadget地址,free(chunk_1)执行exeve(“/bin/sh\x00”),获得shell。
1 |
|
exp
1 |
|