0x00 malloc workflow
0x01 fastbin_dup
利用条件
程序存在double free漏洞
目的
- fastbin array使用单链表实现,free的时候会对free-list进行检查,所以我们不能free同一个chunk两次。但是可以在两次free之间增加一次对其他chunk的free,从而绕过检查顺利执行,然后malloc三次,就得到了两个指向同一区域的指针
步骤
- a = malloc(8) = 0x602010
- b = malloc(8) = 0x602030
- c = malloc(8) = 0x602050
- free(a)
- free(b)
- free(a)
- d = malloc(8) = 0x602010
- e = malloc(8) = 0x602030
- f = malloc(8) = 0x602010
图解
高版本下的区别
libc大于2.27下,引入了tcache,所以需要先把tcache填满(size=7),然后用calloc申请内存。
calloc不请求tcache
0x02 fastbin_dup_into_stack
利用条件
程序存在double free漏洞
目的
接着fastbin_dup的思路,point d
指向了一个还在fastbins array的chunk,对该chunk写入数据就可以覆盖该fastbin的结构,来获取一个指向任意地址的指针。如果可以对该指针读或者写的话,我们就有了任意地址读/写。
步骤
- unsigned long long stack_var = 0x20
- a = malloc(8);b = malloc(8);c = malloc(8)
- free(a);free(b);free(a)
- d = malloc(8)
- d = (unsigned long long) (((char*)&stack_var) - 8)
- malloc(8)
- malloc(8) == ((char*)&stack_var) + 8
图解
0x03 fastbin_dup_consolidate
利用条件
程序存在double free漏洞
目的
fastbins除了在两次free之中加入另外一个free之外,还可以借助large bin中的malloc_consolidate来绕过检查达到double free的目的.
达到的效果就是fastbin_dup
64位下,largebin[0] 对应的size=0x410
步骤
- 填满0x50大小的tcache
- a=calloc(0x40)
- free(a)
- b=malloc(0x400) // malloc一个largebin大小的chunk,触发malloc_consolidate,merge到top chunk/unsortedbin
- free(a) // a和b现在指向同一个chunk,所以可以free(a)
- c=malloc(0x400)
- b==c
图解
0x04 unsafe_unlink
利用条件
free 的 chunk 前后存在空闲 chunk, 也可以通过溢出值覆盖需要 free 的 chunk 的 P
位, 能控制需要 unlink 的 chunk 的内容.
要free的chunk不能在fastbin范围内,因为fastbin的P位是1,不会触发unlink
目的
可以对一个全局指针ptr进行内存布局,然后借助unlink操作实现任意地址读写
- 通常ptr是一个data pointer(意思指向的是chunk 的data部分,所以如果要做unlink利用的话,要伪造整个chunk,而不单单是fake fd和fake bk)
- 可以利用它去改变其他存在&ptr附近的pointer,然后再利用这些pointer去造成任意地址读写。如果存在function pointer,可以更直接的控制eip
步骤
- 绕过
(P->fd->bk != P || P->bk->fd != P) = False
检查fd = &ptr - 0x18
bk = &ptr - 0x10
- 绕过
(chunksize(P) != prev_size (next_chunk(P)) == False
检查- 修改对应的prev_inuse和prev_size
- unlink执行后
ptr = ptr - 0x18
- ptr[3]可以修改ptr指向的内容
图解
0x05 house_of_spirit
利用条件
- 想要控制的目标区域前后一段都是可控的
- 存在可以被覆盖的堆指针
- 一般是在栈上做利用,故需要栈溢出
目的
覆盖一个堆指针,使其指向可控的区域,构造好相关数据,释放堆指针时会将该区域作为chunk放到fastbin里,再申请这块区域,就可以改写目标区域
步骤
- 伪造堆块,在可控的区域1和2构造数据,将目标区域伪造成一个fastbin chunk
- 覆盖堆指针指向伪造的fastbin chunk
- 释放伪造的fastbin chunk到fastbin
- 申请刚刚释放的chunk,使得可以向目标区域写入数据
图解
0x06 posion_null_byte
见shrink_the_chunk
0x07 shrink_the_chunk
利用条件
存在off-by-one null byte的漏洞
目的
创造出overlap chunk,进而更改其他chunk的中内容
主要利用unlink做合并的特性来达到目的
步骤
这个步骤意义不大,建议直接看图
图解
高版本下的区别
https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=b90ddd08f6dd688e651df9ee89ca3a69ff88cd0c
2.29引入,这个利用用到了unsorted bin,所以也受到了影响。
但是上面的利用方式其实已经是对于这个patch的绕过了
如果是低版本的glibc,都不用提前在chunk中写那个0x100
0x07 entend the chunk
利用条件
存在off-by-one漏洞
目的
创造出overlap chunk,进而修改其他chunk的内容
进而变成构造任意指针,从而任意地址读写
跟shrink很像,但主要是加大size,直接吃掉后面的chunk,只要后面的chunk header有对上就好
挖坑
中间那个chunk有必要这么大吗? 需要用到unsorted bin?
如果用到unsorted bin,那么也会收到这个patch的影响,(unsorted bin中chunk取出来时会做unlink,就要做prev_size和size的检查)在2.29之后使用受限
https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=b90ddd08f6dd688e651df9ee89ca3a69ff88cd0c
所以还是那句话,中间那个chunk有必要这么大吗? 如果不进入unsorted bin,是不是就不会做检查了
步骤
- A = malloc(0x30); B = malloc(0x160); C = malloc(0x30)
- free(A)
- malloc(0x38), 填入数据,并且触发off-by-one漏洞,修改chunk B的
size
一字节。使得chunk B的size大小等于chunk B、C总和。size=0x1B1
- free(B),free B的时候会把C顺带着吃掉。然后放入top chunk或者unsorted bin
- malloc(0x1a0),造成chunk C的overlap
图解
house_of_lore
overlapping_chunk
同extend_the_chunk
overlapping_chunk2
同shrink_the_chunk
house_of_force
高版本下的区别
https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=30a17d8c95fbfb15c52d1115803b63aaa73a285c
2.29后不可用
unsorted_bin_attack
高版本下的区别
https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=b90ddd08f6dd688e651df9ee89ca3a69ff88cd0c
2.29后不可用
large_bin_attack
house_of_einherjar
tcache_dup
高版本下的区别
做了double free检测,每个tcache chunk增加了一个key字段,其实就是tcache_perthread_struct指针,释放chunk的时候,会检查当前线程中tcache_perthread_struct是否已经释放过这个chunk,释放过就会crash掉。
主要针对tcache dup,不过改掉key就可以绕过
tcache_poisoning
tcache_house_of_spirit
house_of_botcake
house_stashing_unlink_attack
fastbin_reverse_into_tcache
house_of_mind_fastbin
house_of_storm
heap编年史
glibc 2.32 引入safe-linking
https://research.checkpoint.com/2020/safe-linking-eliminating-a-20-year-old-malloc-exploit-primitive/
https://www.anquanke.com/post/id/206457
- bypass
- https://www.researchinnovations.com/post/bypassing-the-upcoming-safe-linking-mitigation
- https://www.anquanke.com/post/id/207770
- https://cloud.tencent.com/developer/article/1643954
2021.8.1 glibc2.34发布,取消了free_hook, malloc_hook, realloc_hook等一众hook全局变量
https://developers.redhat.com/articles/2021/12/17/why-glibc-234-removed-libpthread
参考链接
- https://github.com/shellphish/how2heap
- https://bbs.pediy.com/thread-259269.htm