UAF漏洞
什么是UAF
UAF就是Use After Free,简单来说就是释放后再次被使用,分为一下几种情况:
- 内存块被释放后,其对应的指针被设置为 NULL , 然后再次使用,自然程序会崩溃。
- 内存块被释放后,其对应的指针没有被设置为 NULL ,然后在它下一次被使用之前,没有代码对这块内存块进行修改,那么程序很有可能可以正常运转。
- 内存块被释放后,其对应的指针没有被设置为 NULL,但是在它下一次使用之前,有代码对这块内存进行了修改,那么当程序再次使用这块内存时,就很有可能会出现奇怪的问题
目前我刚入门只碰见第一种,看别人的博客说后两种比较常见。**我们一般称释放后没有被设置为NULL的内存指针为dangling pointer(悬垂指针)**。
这里在how2heap上有个实验
1 |
|
可以编译一下做一下这个实验
例题
做一个最简单的UAF漏洞的题,初学堆做出来再简单的题都会很有成就感😃。
下载地址:例题
一个经典菜单,打开各个功能看一下
Add note
1 |
|
申请堆块的时候先申请一个0x8大小的堆块管理,第一个字储存了print函数的地址,第二个字储存堆的内容地址,这个堆块的地址存在notelist中。下面就申请了储存内容的堆。
Delete note
1 |
|
这里存在UAF漏洞free掉堆块,但是没有把指针赋值为NULL
Print note
1 |
|
调用控制堆块的打印函数,传入参数为内容堆块的地址
存在后门函数
我们十分想调用这个诱人且友好的后门函数,但是怎么调用呢,这是个问题,我们知道使用打印内容功能的时候,会调用打印函数,如果调用打印函数的地址改为后门函数的地址那就好了,我们尝试一下
如果想改变控制堆块的print地址,我们就想办法,把控制堆块变成内容堆块,然后输入后门函数地址覆盖掉print的地址。
利用思路如下:
- 申请note0 大小为0x10(只要大小和控制堆块大小不一样就行)
- 申请note1 大小为0x10(同上)
- 释放note0
- 释放note1
- 此时大小为0x10的fast bin中链表为note1 -> note0
- 申请note2 大小为0x8,那么根据堆的分配规则
- note2的控制堆块分配note1的控制堆块,内容堆块分配note0的控制堆块
- 这时候我们向note2输入信息,就会储存再note0的控制堆块
- 由于我们的note0没有被赋值为NULL,存在UAF漏洞,所以我们还可以使用note0
- 当再次掉用note0的打印功能的时候,此时已经被我们覆盖为后门函数,那么就可以直接调用后门函数
OK了兄弟们,是不是非常神奇,一个简单的题,都要很巧妙的利用
EXP
1 |
|