Glibc-2.23 源码分析——free部分上

阅读量276392

|

发布时间 : 2021-09-17 10:00:32

 

前言

终于抽出时间对glibc动态内存管理部分源码进行初略的探究,试着从源码和动调来分析free函数执行过程和一些pwn的攻击技巧,分析的不是很全面,有错误的地方望提出指正,共同进步。ps:欢迎白帽子们关注 涂鸦智能安全响应中心。


Free in fastbin

正常情况下的free in fastbin

测试代码

Free -> libc_free,正常进入 free(p1)时,free_hook为空,修改free_hook为onegadget或者其他payload 可以任意执行

非mmap空间,进入 int_free()

Chunk_size的检查

Chunk_size <= 0x80 进入 fastbin的处理

对相邻下一块chunk进行size的对齐检查

Fastbin 建立 与串联链表 部分

触发double free 异常

free(p1);
free(p1);

此时free_chunk与 old相等 导致报错

Double free绕过方式

测试代码

Double free p1需要先释放另一个满足此fastbin size的堆块,修改old

运行结果

再次申请一个fastbin size的chunk,修改chunk的fd指针后,完成use after free,控制fastbin的申请区域

Use after free

代码

释放堆块后未对指针置空,并且能修改指针的情况下,可以直接use after free
运行结果:
之后第二次的malloc(0x20 ~ 0x2f)的申请 可以请求到构造的fake_chunk地址上。

Malloc in fastbin

测试代码

Fastbin 处理代码 位于 int_malloc(),类似于int_free()中fastbin处理,是一个相互的逆过程

fastbins链表结构为 main_arena + 0x10 -> p2 -> p1->0

对于取出fastbins表头的校验

之后对fastbin[0x20]表进行替换列表头的操作

之后对取出chunk的size进行检测(伪造size需要满足size移位之后等于对应的idx,即 若idx=7时fake_size应满足 0x70 ~ 0x7f)

程序运行结果

 

Free in unsortedbins

第一次进行free_in_unsortedbin
测试代码

由free() -> __int_free(),不满足之前对于fastbin的检测后,接着进行下面的逻辑判断,对于top_chunk的保护以及size是否对齐的判断

之后进入 unsortedbin 的处理部分(涉及 chunk overlap绕过技巧)

之后进入 unsortedbin 的链表处理,此时 fwd == bck,之后进行unsortedbin双链表的串联

此时的链表示意图,为了方便展示将fwd 和 bck分开放置

堆块向前overlapping

测试代码

通过置空prev_inuse 设置fake prev_size 欺骗unsortedbins的合并堆块机制

构造合适的prev_size 可以使堆块合并在已经被free的unsortedbin上,吞并未被释放的p2,p3

fake_prev_size = size_p1 + size_p2 + size_p3 = 0xb0 + 0x20 + 0x20 = 0xf0
之后重写写上size+ prev_size 的chunk头和下一块堆块的prev_size后,完成堆块的吞并

之后再申请出制定大小的堆块后,可以用于构造fastbin中的use after free

Unlink

测试代码
How2heap/glibc-2.23/unsafe_unlink.c

Unlink触发过程,伪造上一个堆块已被释放

unlink函数源代码

构造的堆块

Gdb没有挂载到unlink函数 直接分析汇编代码对应源码
p->prev_size 是否为0

builtin_expect (P->fd_nextsize->bk_nextsize != P, 0)

builtin_expect (P->bk_nextsize->fd_nextsize != P, 0)

之后汇编代码逻辑

目标地址 0x601068(P->fd_nextsize -> bk_nextsize P->bk_nextsize -> fd_nextsize 为同一地址)
目标地址先被写上 p->bk_nextsize(0x601058)

接着写上 p->fd_nextsize(0x601050)

Unlink构造条件

1.伪造 被释放堆块的prev_inuse和prev_size
2.伪造被释放堆块的prev_chunk 的 fd_nextsize 和 bk_nextsize
3.fd_nextsize = target – 0x18 bk_nextsize = target – 0x10,目标地址target 被写上 fd_nextsize

 

Malloc in unsortedbins

正常处理逻辑
测试代码

对 0x128 的unsortedbins 申请 0x100的chunk
unsortedbin 申请chunk代码段在 _int_malloc()函数中

运行效果:清空unsortedbins的操作为在 main_arena中清空 bins 表

之后 通过bck赋值变量fwd

改变申请的堆块的fd和bk指针

申请出的chunk被串入双链表

之后将申请出的chunk写上正确的size,并将剩余的bin串入 unsortedbins 并且写上size

Remainder 堆块的设置

House_of_lore

若双链表的bk指针被篡改指向伪造区域,并且在伪造的区域满足fd指针等于victim,申请到的堆地址将可控
测试代码:
how2heap/glibc-2.23/house_of_lore.c
先利用正常情况free一个smallbin进入 unsortedbins

此时双链表正常,之后篡改 unsortedbin的bk指针

之后进入 _int_malloc()的处理的校验逻辑

伪造的堆块被串联进入 bin

再次申请smallbins,申请到了伪造区域


本文作者:Jambolt@涂鸦智能安全实验室

漏洞悬赏计划:涂鸦智能安全响应中心(https://src.tuya.com) 欢迎白帽子来探索。

招聘内推计划:涵盖安全开发、安全测试、代码审计、安全合规等所有方面的岗位,简历投递sec@tuya.com,请注明来源。

本文由jambolt原创发布

转载,请参考转载声明,注明出处: https://www.anquanke.com/post/id/253042

安全客 - 有思想的安全新媒体

分享到:微信
+12赞
收藏
jambolt
分享到:微信

发表评论

内容需知
合作单位
  • 安全客
  • 安全客
Copyright © 北京奇虎科技有限公司 三六零数字安全科技集团有限公司 安全客 All Rights Reserved 京ICP备08010314号-66