如何理解堆和堆溢出漏洞的利用
发布网友
发布时间:2022-04-24 02:49
我来回答
共1个回答
热心网友
时间:2023-08-19 12:22
这篇文章详细的描述了堆,并且会教你如何编写基于堆溢出漏洞的利用。
运行下面的程序:
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
char *buf1 = malloc(128);
char *buf2 = malloc(256);
read(fileno(stdin), buf1, 200);
free(buf2);
free(buf1);
}
在第 10 行中,存在一个明显的可利用的溢出漏洞。那么首先我们就来了解下系统是怎样管理堆的 。
0×01 基本堆和堆块的布局
每个程序分配的内存(这里指的是 malloc 函数)在内部被一个叫做 ” 堆块 ” 的所替代。一个堆块是由元数据和程序返回的内存组成的(实际上内存是 malloc 的返回值)。所有的这些堆块都是保存在堆上,这块内存区域在申请新的内存时会不断的扩大。同样,当一定数量的内存释放时,堆可以收缩。在 glibc 源码中定义的堆块如下:
struct malloc_chunk {
INTERNAL_SIZE_T prev_size; /* Size of previous chunk (if free). */
INTERNAL_SIZE_T size; /* Size in bytes, including overhead. */
struct malloc_chunk* fd; /* double links -- used only if free. */
struct malloc_chunk* bk;
/* Only used for large blocks: pointer to next larger size. */
struct malloc_chunk* fd_nextsize; /* double links -- used only if free. */
struct malloc_chunk* bk_nextsize;
};
假设内存中没有堆块释放,新分配的内存区域紧随之前申请的堆块后。因此如果一个程序依次调用malloc(256),malloc(512),以及malloc(1024),内存布局如下:
Meta-data of chunk created by malloc(256)
The 256 bytes of memory return by malloc
—————————————–
Meta-data of chunk created by malloc(512)
The 512 bytes of memory return by malloc
—————————————–
Meta-data of chunk created by malloc(1024)
The 1024 bytes of memory return by malloc
—————————————–
Meta-data of the top chunk
在堆块之间的”—”是虚拟的边界,实际当中他们是彼此相邻的。你可能会问,为何我要在布局当中包含一个”顶块”元数据。顶级块表示堆中可利用的内存,而且是唯一的可以大小可以生长的堆块。当申请新的内存时,顶块分成两个部分:第一个部分变成所申请的堆块,第二个部分变为新的顶块(因此顶块大小可以收缩)。如果顶块不能够满足申请的内存区域大小,程序就会要求操作系统扩大顶块大侠(让堆继续生长)。