堆的整理

堆的结构

malloc chunk

1
2
3
4
5
6
7
8
9
10
11
12
13
14
chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Size of previous chunk, if unallocated (P clear) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Size of chunk, in bytes |A|M|P|
mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| User data starts here... .
. .
. (malloc_usable_size() bytes) .
next . |
chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| (size of chunk, but used for application data) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Size of next chunk, in bytes |A|0|1|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

free chunk

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Size of previous chunk, if unallocated (P clear) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
`head:' | Size of chunk, in bytes |A|0|P|
mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Forward pointer to next chunk in list |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Back pointer to previous chunk in list |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Unused space (may be 0 bytes long) .
. .
next . |
chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
`foot:' | Size of chunk, in bytes |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Size of next chunk, in bytes |A|0|0|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

在fasted bin中是LIFO

在unsorted bin 中是FIFO

堆叠技巧

http://4ngelboy.blogspot.com/2016/10/span-display-block-overflow-hidden_10.html

这位师傅的blog里讲的很详细了。

malloc_consolidate

简介

malloc_consolidate() 函数是定义在 malloc.c 中的一个函数,用于将 fastbin 中的空闲 chunk 合并整理到 unsorted_bin 中以及进行初始化堆的工作,在 malloc() 以及 free() 中均有可能调用 malloc_consolidate() 函数。

malloc_consolidate调用条件

1. malloc large bin

假如malloc的size大于small bin的范围,先调用malloc_consolidate将fastbin 合并为unsorted bin

在64位系统下,small bin <0x400

在32位系统下,small bin <0x200

2. top chunk不够空间

下面是简单的测试代码

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
#include <stdlib.h>
int main()
{
void* h1 = malloc(0x68);
void* h2 = malloc(0x20e48);
free(h1);
malloc(0x300);
return 0;
}
3. 在free函数在各种合并前后chunk之后的size大于FASTBIN_CONSOLIDATION_THRESHOLD 也就是65536

比较容易实现的是与top chunk合并后size大于FASTBIN_CONSOLIDATION_THRESHOLD 具体大概是下面的流程

  1. 判断chunk是否属于fastbin,如果不是,继续
  2. 判断chunk是否属于map的,如果不是,继续
  3. 假如下一个chunk是top chunk,合并
  4. 判断当前chunk的size是否大于FASTBIN_CONSOLIDATION_THRESHOLD,假如大于,调用malloc_consolidate

测试代码如下

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
#include <stdlib.h>
int main()
{
void* h1 = malloc(0x68);
void* h2 = malloc(0xa8);
void* h3 = malloc(0xa8);
free(h1);
free(h3);
return 0;
}

堆的leak大致方法

首先需要leak的内容:

1.主模块的基地址

2.heap的基地址

3.libc.so的基地址

常规流程是通过获取main_arena地址,因为main_arena存在于libc.so中可以通过计算偏移得到libc.so的基地址。再根据main_arena地址获得hook地址

然后要么system + binsh 要么one_gadget getshell

可供leak的漏洞

  • 堆内存未初始化
  • 堆溢出
  • Use-After-Free
  • 越界读
  • heap extend

以上都可以进行leak。

UAF

uaf漏洞产生的主要原因是释放了一个堆块后,并没有将该指针置为NULL,这样导致该指针处于悬空的状态,同样被释放的内存如果被恶意构造数据,就有可能会被利用。

根本原因:

1
应用程序调用free()释放内存时,如果内存块小于256kb,dlmalloc并不马上将内存块释放回内存,而是将内存块标记为空闲状态。这么做的原因有两个:一是内存块不一定能马上释放会内核(比如内存块不是位于堆顶端),二是供应用程序下次申请内存使用(这是主要原因)。当dlmalloc中空闲内存量达到一定值时dlmalloc才将空闲内存释放会内核。如果应用程序申请的内存大于256kb,dlmalloc调用mmap()向内核申请一块内存,返回返还给应用程序使用。如果应用程序释放的内存大于256kb,dlmalloc马上调用munmap()释放内存。dlmalloc不会缓存大于256kb的内存块,因为这样的内存块太大了,最好不要长期占用这么大的内存资源。

(所以你看到的某些ptr = null , ptr = 0。 然后进入到堆块里查看内容,发现堆块里的内容还是能看得到以前写入的数据,但是不能读取,就是这了。它被打上了空闲标记,但是没有真正清除(大概是这个意思吧?))

一种是直接进行free,且没有进行任何限制的

这种直接malloc,delete,show。

另一种就是*没悬空,其他该置零的置零。

UAF配合fasted bin的cyclic list(double free)

off by one

off by one 配合chunk overlap ;unlink

堆的杂记

注意一点。

动态链接:

第一次放入unsorted bin里面的堆块地址距离main_arena为0x58

main_arena = leak_addr - 0x58

malloc_hook_addr = main_arena_addr - 0x10

静态链接:

第一次放入unsorted bin里面的堆块地址距离malloc_hook为0xD0

overlapping

前向:

修改第一个堆块的size位即可

后向:

修改要覆盖的最后一个堆块的p位和prev_size位即可。

本文标题:堆的整理

文章作者:zhz

发布时间:2019年10月29日 - 23:10

最后更新:2020年05月17日 - 17:05

原始链接:http://yoursite.com/2019/10/29/“堆的整理”/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。