各种 house of
House of Orange
概述
对top chunk进行利用,在没有free存在的情况下创造free到unsortedbin中的空闲块,从而得到unsortedbin地址,在进行后续操作即可获得main_arena地址等
原理
当当前堆的top chunk尺寸不足以满足申请的分配大小的时候,原来的top chunk会被释放并且放入unsortedbin中,接着再映射或者扩展一个新top chunk出来
glibc2.23:
当其他bin都满足不了,topchunk也无法满足时
1 | |
条件:
- 申请的size不能大于mmap分配阈值,默认128k
- 伪造size对齐的内存页
- 伪造size要大于MINSIZE(0x10)
- 伪造size要小于申请的chunk size+MINSIZE(0x10)
- 伪造size的prev inuse为必须为1
过程:
- 修改top chunk的size
- 申请一个大于top chunk的size
- scanf函数会申请一个0x1000的块,如果调用scanf的话就不用我们自己申请了,scanf调用完top chunk就会进入unsortedbin
House of Einherjar
概述
利用堆块的向后合并机制强制使得malloc返回一个几乎任意地址的chunk
原理
向后合并
1 | |
要有溢出的漏洞,比如off-by-one等
过程:(设有三堆块分别是0,1,2。2块用来隔开top chunk,还有A块为目标地址)
- 利用1块漏洞修改2块pre_inuse为0
- 利用1块漏洞修改2块pre_size为A块和2块之间距离,让2块释放时去找A块,也就是利用第6行的代码
- 在A块附近构造数据,以通过unlink检查
- A块size位为chunksize(A)
unlink检查:(2.26)
1 | |
- A块下一个块的prev_size字段要=A块大小,就是 &(A+chunksize(A))=chunksize(A)
- A块的fd,bk都指向A块的地址
2.23只有第二个检查
- 最后unlink将其放入了unsortedbin后需要将fd,bk改写为main_arena+88
最后malloc就得到目标地址的堆块了
House of Force
概述
利用篡改top chunk的size,来实现任意地址分配
2.23-2.27
原理
top chunk的分割机制(2.23)
1 | |
要可以控制top chunk的size域
要可以分配任意大小的堆块
过程:
- 首先溢出将top chunk的size变成-1,因为比较时会把size看成无符号数,这样-1就是一个极大数,可以通过所有检查
- 然后分配一块空间,利用这块空间将top chunk推到目标地址附近,如果要推到高地址,就malloc(+),推到低地址就malloc(-),这块空间大小为
malloc_size = target_addr - top_chunk_addr - 2*sizeof(size_t); - 然后再malloc一次就可以得到目标地址的堆块了
House of Lore
概述
利用篡改smallbins中free的块的bk来实现任意地址分配
<=2.26可以使用
2.27加入tcache,需要手动填满
原理
smallbins中
- 原理bins的堆块是更前面的堆块,所以fd指向远离bins的
- 靠近bins的堆块是更后面的堆块,所以bk指向靠近bins的
smallbins的分配中
1 | |
主要利用
1 | |
要可以修改 smallbin 中 chunk 的 bk 和 fake_chunk 的fd
过程
- 修改 smallbins 中的 chunk 的 bk为 &fake_chunk
- 修改f ake_chunk 的fd为 smallbins 中的 chunk 地址来通过检查
- 还需要另一个 fake_chunk 来使第二次分配时通过检查
- 需要伪造 fake_chunk->bk=&fake_chunk2
- 需要 fake_chunk2->fd=&fake_chunk
- 分配两次得到 fake_chunk
House of Rabbit
概述
利用 fastbin 和 malloc_consolidate 机制实现任意地址分配或读写
原理
利用 malloc_consolidate 的时候对 fastbin 中的堆块的 size 没有检查从而可以伪造一个 fake_chunk
可以修改 fastbin 的 fd 或 size
可以触发 malloc consolidate
利用过程
- 修改size
- 分配两个 chunk,fastbin 范围内,再来一个隔开 top chunk
- free 前两个 chunk
- 修改第一个 chunksize 为 0xa1
- 接着 malloc(0x1000) 触发 malloc_consolidate
- 然后这两个快就被分别放到了对应的 smallbin 中
- 修改 fd
- 分配1个 chunk ,fastbin范围内,再来一个隔开top
- free 掉第一个
- 修改第一个 fd 为 fake_chunk
- 接着 malloc(0x1000) 触发 malloc_consolidate
- 然后这个fake_chunk就合法了,可以对其进行其他操作
House of Roman
概述
利用fastbins attack和unsortedbin attack来 绕过PIE
要有溢出写和UAF类似的漏洞
2.23-2.29
原理
- 分配四个chunk(A,B,C,D),chunkB大小为0x70
- free(B),B进入fastbin[0x70]
- 利用A来将B->size修改为unsortedbin范围内
- 再次释放B,B进入unsortedbin,此时fd,bk都是main_arena+88,修改fd为_malloc_hook-0x23
- 利用A再次修改B的size,使其符合fastbin[0x70]
- 接着利用unsortedbin attack将_malloc_hook处写成main_arena+88
- 然后利用部分写将该地址改成one_gadgets或system完成攻击
House of banana
条件
程序调用exit函数
或
程序通过libc_start_main启动的主函数,且主函数可以结束
glibc-2.23及以上
程序能够实现largebinattach
原理
程序退出时会有以下调用,也就是说如果可以控制 array[i] 为ogg,就可以getshell
1 | |
而 rtld_global
1 | |
该结构体里有多个 _dl_ns 结构体,存储的是 elf 各段的符号结构体
1 | |
而 link_map 在 gdb 里
1 | |
当执行到 _dl_fini 函数时
1 | |
这里的 l 指的就是 link_map 结构体
控制 array 的
1 | |
DT_FINI_ARRAY 是宏,为 26
而 d_un 是一个联合体
1 | |
所以我们如果将 l->l_info[26] 设为 l->l_info[26] 的地址 ,l->l_info[27] 就是 array 的的值
控制 i 的
1 | |
DT_FINI_ARRAYSZ 宏,是 28
同理,如果这里将 l->l_info[28] 设为其地址,那么 i=l->l_[29]/8
这样同时控制了 array 和 i ,就可以在后面的流程里控制程序流了