Heap基础知识
[toc]
house of force
一句话描述该漏洞,在glibc 2.23
下,通过控制top chunk
的size
域为一个特别大的值,导致可以通过malloc
特别大的值或者负数来将top chunk
的指针指向任意位置。
你需要进行控制的:
top chunk
的size
域
- 你需要可以
malloc
一个特别大的值
- 你需要可以多次
malloc
公式:
1 2 3 4 5
| request_size = new_top_chunk_addr - old_top_chunk_addr - 0x10;
|
原理:
在glibc 2.23
中,对于top chunk
的检查仅仅只有(unsigned long) (size) >= (unsigned long) (nb + MINSIZE)
。
那么,若我们将top chunk
的size
修改为一个特别大的值,甚至是-1
(由于是无符号数在进行判断,那么-1
是最大的数),那么便可以申请任意大小的chunk
。源码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| victim = av->top; size = chunksize(victim);
if ((unsigned long) (size) >= (unsigned long) (nb + MINSIZE)) { remainder_size = size - nb; remainder = chunk_at_offset(victim, nb); av->top = remainder; set_head(victim, nb | PREV_INUSE | (av != &main_arena ? NON_MAIN_ARENA : 0)); set_head(remainder, remainder_size | PREV_INUSE);
check_malloced_chunk(av, victim, nb); void *p = chunk2mem(victim); alloc_perturb(p, bytes); return p; }
|
这里用wiki
的例子,由于堆是低地址到高地址增长,那么可以申请负数地址来申请到更低的地址(例如malloc@got.plt
):
1 2 3 4 5 6 7 8 9
| int main() { long *ptr,*ptr2; ptr=malloc(0x10); ptr=(long *)(((long)ptr)+24); *ptr=-1; malloc(-4120); malloc(0x10); }
|
也可以通过申请特别大的值来申请到高地址,例如__malloc_hook
(在libc
里面)
1 2 3 4 5 6 7 8 9
| int main() { long *ptr,*ptr2; ptr=malloc(0x10); ptr=(long *)(((long)ptr)+24); *ptr=-1; <=== 修改top chunk size malloc(140737345551056); <=== 增大top chunk指针 malloc(0x10); }
|
笔者通过一小段代码在glibc2.23
中实现了house of force
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| #include <stdio.h> #include <stdlib.h>
int main() { setbuf(stdin, NULL); setbuf(stdout, NULL); long fake_chunk[0x110]; printf("the addr of fake_chunk is %p.\n", fake_chunk);
long *a = malloc(0x100); long *top_chunk = (long *)((long)a + 0x100); top_chunk[1] = -1;
long diff = (long)&fake_chunk[0] - (long)top_chunk; malloc(diff - 0x10);
long *b = malloc(0x100); printf("the addr of new malloc chunk is %p.\n", b - 2);
return 0; }
|