首页
社区
课程
招聘
how2heap动态演示
发表于: 2025-6-3 01:07 234

how2heap动态演示

2025-6-3 01:07
234

本文演示了how2heap仓库里面各个程序的执行流程。

学习how2heap之前,需要先熟悉ptmalloc逻辑,推荐先看一下《Glibc内存管理--ptmalloc2源代码分析》,另外有部分概念,我在深度理解glibc内存分配篇文章,更加细节的介绍过。


演示程序仅仅用于描述攻击的基本步骤,其中执行的每一步操作,在实际攻击中,都要通过漏洞程序的交互(本地/远程)逻辑触发:

(1) 交互可以访问并显示的范围通常有限,甚至依赖信息泄漏漏洞;

(2) 交互可以向程序写入的范围通常有限,甚至依赖写溢出漏洞;

(3) 交互通常不能轻易控制分配、释放的时机,以及分配内存的大小。


不过,只有透彻理解最基本的原型,才能将极其复杂的真实场景,转换成它们。

就跟下棋一样,不懂招数,看到的整盘棋都是零散的,反之每个阶段围绕一个战略目标,就可以分而治之,只需要应付每个较小范围里的变化。

过程说明:

将chunk(p)释放到unsorted_bin,然后利用漏洞 (比如UAF漏洞,因为chunk(p)当前为释放状态),修改chunk(p)->bk,使其指向fake_chunk,就将fake_chunk也链入unsorted bin了。

细节: 

chunk(p)被malloc(0x410)分配到了:

(1) chunk(p)没有移入其它bin,所以chunk(p)->fd保持不变;

(2) 停止遍历unsorted_bin,从而fake_chunk仍然链在unsorted_bin,并且fake_chunk->fd,指向了unsorted_bin,unsorted_bin->fd,仍然指向chunk(p)

     

过程说明:

相比unsorted_bin_attack.c,在执行34行之前,将chunk(victim)->size改掉了,使其不满足malloc(0x100)的要求,使其移入smallbin[0],从而继续往后遍历,最终分配到fake_chunk。

作用:

(1) 使目标位置可以被malloc()分配到;

(2) 可以在目标位置,写入unsorted_bin地址。

过程说明:

将victim_chunk释放到smallbin,然后修改victim_chunk->bk,使其指向fake_chunkA,就将fake_chunkA->fake_chunkB->...->fake_chunk6链入smallbin了。

细节:

glibc-2.26开始,新增了tcache功能,相比unsorted_bin_attack,第120行执行malloc(0x100),分配到所需chunk后,会继续遍历smallbin,将后续chunk移入tcache,直到tcache填满为止,第123行malloc(0x100),优先从tcache分配到fake_chunk4。

过程说明:

将chunk(p1)释放到largebin,然后修改chunk(p1)->bk,使其指向fake_chunk(&target-4),就将fake_chunk,链入largebin了。再触发chunk(p2)移入largebin,添加到它们之间时(largebin中的chunk会按大小排序),fake_chunk->fd_nextsize,就会被写为chunk(p2)。

glibc相关代码:


过程说明:

将chunk(b)释放到tcache,然后修改chunk(b)->fd,使其指向fake_chunk,就将fake_chunk,链入tcache了。

细节:

(1) tcache中链接的是tcache_entry对象,根据&chunk->fd位置强转得到,所以entry->next与chunk->fd位置对应。

    

(2) glibc-2.32开始,新增了加密指针功能,tcache以及fastbin链表中,chunk->fd不再直接指向下一个节点的地址,而是chunk->fd>>12 ^ 下个节点地址。


过程说明:

将chunk(a)释放到fastbin,然后修改chunk(a)->fd,使其指向fake_chunk,就将fake_chunk,链入fastbin了。

细节:

演示程序为了更接近真实的攻击过程,事先模拟了double free场景。

向fastbin添加chunk之前,只会检查链表头是否为要添加的chunk,不会检查整个链表(否则会影响free()的效率),所以在两次free(a)之间,执行一次free(b),就可以绕过glibc检测。


先看138行之后的执行过程:

(1) 142~154: 填满tcache[21] (个人认为这一步没什么必要,因为后面没有需要避免chunk释放进tcache[21]的地方);

(2) 159~169: 将large_chunk,释放到largebin[2],将unsorted_chunk,释放到unsorted_bin;

(3) 204:           修改unsorted_chunk->bk,将fake_chunk链入unsorted_bin,其实就是利用unsorted_bin_attack,用于最后执行calloc()时,可以分配到fake_chunk;

(4) 207, 245: 修改large_chunk->bk、large_chunk->bk_nextsize,其实就是利用large_bin_attack,使得unsorted_chunk移入large_bin[2]时,添加到large_chunk和fake_chunk之间,使得unsorted_chunk->bk_nextsize->fd_nextsize,指向unsorted_chunk;

(5) 278:           执行calloc(alloc_size),从unsorted_bin分配fake_chunk。


malloc()优先从tcache分配,但calloc()不会:

回头再头138行之前的执行过程:

73~138:  为large_chunk->bk_nextsize指向,计算微调偏移,使得0x173,正好写入&fake_chunk->size处,保证fake_chunk->size满足calloc(alloc_size)的分配大小。

glibc-2.32开始,tcache以及fastbin链表中,chunk->fd不再直接指向下一个节点的地址,而是chunk->fd>>12 ^ 下个节点地址,而如果node和nextnode在同一个4K page,仅通过加密指针本身,就可以还原出nextnode地址

证明:

node:          A15,A14,A13,A12,A11,A10,A9,A8,A7,A6,A5,A4,A3,A2,A1,A0

nextnode: B15,B14,B13,B12,B11,B10,B9,B8,B7,B6,B5,B4,B3,B2,B1,B0

加密指针:C15,C14,C13,C12,C11,C10,C9,C8,C7,C6,C5,C4,C3,C2,C1,C0


由于node和nextnode只有低12位不相等,所以node也可以表示为:

node:          B15,B14,B13,B12,B11,B10,B9,B8,B7,B6,B5,B4,B3,A2,A1,A0


由于,加密指针 = node>>12 ^ nextnode

=> (1) B15,B14,B13 = C15,C14,C13

=> (2) C12,C11,C10 = B15,B14,B13 ^ B12,B11,B10 => B12,B11,B10 = B15,B14,B13 ^ C12,C11,C10,同理可求:B9,B8,B7、B6,B5,B4、B3,B2,B1、B0。

过程说明:

先触发chunk从smallbin移入tcache,再从tcache分配这个chunk,就可以绕过chunk->bk->fd == chunk检查。

原因:

(1) 从tcache分配chunk,不检查chunk->bk->fd == chunk;

(2) 从smallbin分配chunk,会取出首个chunk,并检查chunk->bk->fd == chunk,而如果tcache未满,会将剩余chunk移入tcache,并且不做检查。

fastbin FILO,tcache FILO,fastbin中的chunks移入tcache后,顺序会颠倒:

最先从fastbin移出的chunk,也会最先移入tcache,那么在tcache中,就会最后才能被移出。

fastbin_dup用于绕过double free检测,fastbin_dup_into_stack,就已经展示过。

也是用于绕过double free检测,原理都是先将相同的chunk,挤出fastbin链表头,只不过这里是挤到unsorted_bin。

作用:

真实攻击场景,如果目标位置不能直接控制写入,但其周围内容可控,并且周围地址的释放、分配也可控,就可以尝试将目标位置分配给程序后,再通过交互控制它的内容。

细节:

释放fake_chunk前,先要设置地址相邻的next_chunk->size,保证它属于(2*SIZE_SZ, av->system_mem)区间,绕过free()内部的检查。


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 2
支持
分享
最新回复 (1)
雪    币: 16067
活跃值: (17017)
能力值: (RANK:730 )
在线值:
发帖
回帖
粉丝
2
好文章!!!
9小时前
0
游客
登录 | 注册 方可回帖
返回