用15行C代码实践UAF导致堆基地址的泄漏

代码如下:


用15行C代码实践UAF导致堆基地址的泄漏_第1张图片
image.png

实验环境:ubuntu 16.04 64位(但是实验用的程序是32位的),gdb(linux上的命令行调试器)带插件peda环境

首先,先学习两个名词:
通过malloc函数创建的空间,我们称之为内存块,简称块(chunk), 块被free()后,成为空闲块

问题:什么是UAF。
答:Use After Free。指的是一个块被free()后,如果再malloc()一段块时,会判断malloc()的块的空间大小是否等于或小于前一个被free()的块,如果是则,将空闲块的空间分配给,此时malloc()的块。看下图:

用15行C代码实践UAF导致堆基地址的泄漏_第2张图片
image.png

我们回到一开始的代码:一开始我malloc()了4个空间大小为0x80的块。我利用gdb,查看这四个块。在汇编中函数的返回值都会先保存在EAX这个寄存器上。如下图,刚执行完malloc(),记下它的返回值0x804b008,这是变量p1的值。但是块的真地址应该为0x804b000。
为什么?请继续往下看。


用15行C代码实践UAF导致堆基地址的泄漏_第3张图片
1522401193(1).jpg

当四个块malloc()完后利用gdb 指令查看它们,如下图。一眼看过去全是0。但是希望有人注意到:图中一共又4个“89”。


用15行C代码实践UAF导致堆基地址的泄漏_第4张图片
image.png

为了更方便的查看,我把源码修改一下。如下:


用15行C代码实践UAF导致堆基地址的泄漏_第5张图片
image.png

编译调试查看如下图。
0x41='A',0x42='B',0x43='C',0x44='D'
用15行C代码实践UAF导致堆基地址的泄漏_第6张图片
image.png

根据图,再解释一下。其实在malloc()一个空间大小0x80的块时,系统分配的块的大小实际上是0x88。这多出来的8个字节用申明当前块的大小。但是图中为什么显示是‘89’呢。这解释起来有点长,而且脱离了本文章的主旨,简单的说来就是当块被free()后,就变‘88’了
接下来就来看看p3,p1块被free()后,内存发生了什么。先来看看p3被free(),如下图,一看我们strcpy()进的9个‘C’被覆盖了8个剩下一个‘C’了:


image.png

现在free(p1)。看下图。图1是p3块附近的数据,图2是p1块赴京的数据:
image.png

图1
image.png

图2
在图1看到了我们堆的基地址0x804b000。之所有会出现基地址是由于linux中系统对空闲块的管理产生的。linux对不同大小的的空闲块有着不同的管理方式。而这里我们仅以空间大小为0x80的块来做实验,对于0x80块,是linux系统用双链表的数据结构来进行对空闲块的管理,所以会看到0x804b000(原p1块的地址),0x804b110(原p3块的地址)。
接下来我们malloc()一个空间大小为0x80的块,看看它的内存数据。
image.png

p1[0]:


image.png

p[1]:
image.png

看到的数据就知道现在的p1块就是一开始的p3块,这时后就产生了UAF。将数据prinrf()出来导致堆的基地址泄漏。

你可能感兴趣的:(用15行C代码实践UAF导致堆基地址的泄漏)