之前就在how2heap上看过这种攻击方式,奈何智商和英语水平都不够,一直不能很好的理解,最近做了一道题就是利用的这种攻击方式。
首先这个攻击的先决条件是能够覆盖一个chunk的size的最后一个字节为0。
我们先申请3个chunk
void *a=malloc(0x38);
void *b=malloc(0x100);
void *c=malloc(0xd0);
当然这个size是有一定要求,看了后面的步骤就能明白这个要求。
现在我们有了3个chunk,这时我们free掉a和b
free(b);
不出意外的话b现在应该在unsorted bin 里面。这时b的size应该是0x110,我们利用漏洞将b的size改写成0x100。这时b和c之间就出现了大小为0x10的空隙。
我们再次申请两个chunk b1和b2:
void* b1 = malloc(0xa0);
void* b2 = malloc(0x30);
此时申请的两个chunk不出意外的话是从刚才的unsorted bin中分隔而来的chunk,这时我们再申请一个chunk分隔c和top chunk:
void d = malloc(0x100);
然后我们依次free掉b1和c,这时c的prev_size是没有被覆盖的,所以c在检查前后chunk状态的时候会检查到b1,此时b1已经被free,所以c和b1会合并成一个大chunk并加入unsorted bin 行列。
这时如果我们再申请大小合适的chunk,就会覆盖掉b2所在的地址。
当然,实际情况中可能直接覆盖chunk的内容没有什么用,所以大多数时候可能是在free(c)之前将b2给free掉,制造一个fastbin,然后通过覆盖fastbin的fd来实现任意(伪)的分配。
顺带说一点题外话,分配fastbin的时候唯一的检查就是查看当前chunk的size是不是真的是对应的size。所以也没有办法直接malloc到malloc__hook这种让人舒服的地址,不过申请到堆栈的地址还是没有什么问题的。