护网杯 2019 pwn flower 详解
TOC
- 1. flower 漏洞
- 2. scanf 触发 malloc_consolidate
- 3. 利用 malloc_consolidate 巧妙 unlink
- 4. chunk overlap 泄露地址
- 5. 劫持 top_chunk
- 6. 劫持hook
- 7. 完整代码
这题的质量是真心不错,学到了很多东西,所以拿出来特地讲解一下。
源程序下载:flower.zip 。
flower 漏洞
靶机环境 glibc-2.23 。
void __cdecl read_n(_BYTE *a1, unsigned int a2) |
非常明显的off by one
漏洞,但是由于size
限制为size > 0 && size <= 0x58
,所以使得程序的利用十分麻烦。
scanf 触发 malloc_consolidate
由于size的限制,我们只能申请到fastbin
,如果直接off by one
会把size给踩没了,这样free的话会直接crash,而且不放进unsorted bin
的话,我们也无法泄露地址,但是如何将chunk放入unsorted bin
呢?
当top_chunk
不够时,或者申请了一个large bin
,也就是size大于0x400
的chunk就能触发malloc_consolidate
,使得fastbin
合并,并且放入unsorted bin
中。
这里用到了scanf
的一个缓冲机制,当scanf
的缓冲区不够用时,就会malloc
一块更大的chunk
来充当新的缓冲区,然后使用完之后在free掉,当我们的输入大于0x400
时,自然会申请一块大于0x400
的chunk来当缓冲区,正是这个申请可以触发malloc_consolidate
。
for i in range(6): |
调试结果:
pwndbg> bin |
这里的chunk被放入smallbin
是因为申请0x400
的chunk时,对unsorted bin
进行了归位操作。
利用 malloc_consolidate 巧妙 unlink
虽然有unsorted bin
可以用了,但是我们并没有一个size为0x100
的chunk可以free,根据size的限制,我们也不可能申请到,那么该如何进行unlink呢,这里就要用到malloc_consolidate
一个巧妙的地方。
下面源码来自:glibc-2.23/malloc/malloc.c:4122
static void malloc_consolidate(mstate av) |
可以看到malloc_consolidate
操作是从小的fastbin
开始,然后逐渐转向大的,使他们都合并成unsorted bin
,如果我们先把size
的尾巴踩掉,使得该unsorted bin
和后面的chunk断片
,然后在申请一块较小的chunk,那么malloc_consolidate
时,这块较小的chunk,会优先放入unsorted bin
中,然后在合并后面断片的chunk时,就会直接unlink
进行合并,那么我们就可以利用中间的chunk来进行 chunk overlap
的操作了。
add(0x58, 0, 'a' * 0x50 + p64(0x61)) |
合并之前的情况如下:
pwndbg> bin |
根据我上面说的原理,0x55f4dccbe060
和0x55f4dccbe1e0
在malloc_consolidate
会合并成一个大chunk。
chunk overlap 泄露地址
简单的地址泄露。
add(0x18, 0, '\n') |
劫持 top_chunk
还是因为size > 0 && size <= 0x58
的限制,我们没有办法使用正常的0x7f
size来劫持__malloc_hook
,这时就需要我们想出新的办法来劫持hook。
由于fastbin和top_chunk邻近
,而且fastbin一般都是0x56....
(开了PIE)之类的,那么size > 0 && size <= 0x58
的限制刚好可以申请到这种size,所以我们利用fastbin
的地址充当size,然后malloc
出 main_arena
,再劫持 top_chunk
。
remove(3) |
代码的调试信息如下:
pwndbg> bin |
可以看到我们已经可以拿出main_arena
,由于只有当size为0x0000000000000055
才能申请出来,所以几率应该是1/3
。
然后我们可以将top_chunk
指向<_IO_wide_data_0+296>
,因为那里有一个天然的size
:
pwndbg> x/8gx 0x7ff5bb0bbb00-0x20-8 |
劫持hook
当我们成功劫持top_chunk
后,只要把unsorted bin
用完,那么程序就会从top_chunk
里面切割内存给我们,这样我们就能劫持下面的__malloc_hook
了。
add(0x48, 0, '\0' * 0x3b + p64(main_arena_addr - 0x28)) |
完整代码
概率是1/3
。
#!/usr/bin/python2 |