一道堆方向的pwn(double free & unsorted bins)
在某博客上看到了一道堆的题,博主说是入门的,嗯,那正好适合我,于是我花了一周终于出结果了。。。。。。
来看看我都遇到了什么问题
另外,希望你在看这篇文章之前有了解过堆的数据结构
做题环境
Ubuntu 20.04.3 LTS,这是我在微软商店下载的子系统,也是一切万恶之源的开始
题目:Roc826
什么是double free
希望在此之前,你已经知道什么是堆了。
double free就是对一个堆free两次
在堆中,free后堆有这么几个去向
bins | 描述 |
---|---|
tcachebins | 存在与glibc2.7及以上版本,他的优先级比fastbins高 |
fastbins | 是个单链表,存放几个定长的被释放的堆 |
unsortedbin | 存的是不在前两个存储范围的被释放的堆 |
对于smallbins和largebins不做介绍,据说是在unsortedbin在被遍历的时候放入small或者large中的
根据大部分对double free的介绍来看,利用最多的就是第一次free,堆进入fastbins,第二次free后改变fd指针指向。
在做题时,由于我的子系统版本过高,glibc版本是2.31,因此存在tcachebins,也就是free之后的堆不会进入fastbins
- 来个例子
int main()
{
void *a = malloc(0x60);
void *b = malloc(0x60);
free(a);
free(b);
free(a);
return 0;
}
gdb调试,执行两次malloc
查看目前堆
Allocated chunk | PREV_INUSE
Addr: 0x8005290
Size: 0x71
Allocated chunk | PREV_INUSE
Addr: 0x8005300
Size: 0x71
继续跟进执行一次free
查看对结果如下,第一个堆状态为free,并且在tcache中
Free chunk (tcache) | PREV_INUSE
Addr: 0x8005290
Size: 0x71
fd: 0x00
Allocated chunk | PREV_INUSE
Addr: 0x8005300
Size: 0x71
再看看bins,可见tcachebins的优先级比fastbins高
pwndbg> bins
tcachebins
0x70 [ 1]: 0x80052a0 ◂— 0x0
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x0
那么问题来了,tcachebins下的堆能进行二次free吗,我特意试了一下,不行,会报错,也就意味着高版本glibc做不了这道题,于是一天过去,我想到了换个glibc来调试。
换个版本的glibc来编译运行一下
gcc test.c -m64 -z execstack -fno-stack-protector -no-pie -o test -Wl,--rpath=dir/ -Wl,--dynamic-linker=dir/ld-linux-x86-64.so.2
//指定glibc版本编译
于是我再一次对这个程序进行调试,运行到第一次free后查看堆状态,可见第一个堆进入了fastbins
pwndbg> heap
Free chunk (fastbins) | PREV_INUSE
Addr: 0x405000
Size: 0x71
fd: 0x00
Allocated chunk | PREV_INUSE
Addr: 0x405070
Size: 0x71
查看bins,发现也不存在tcachebins
pwndbg> bins
fastbins
0x20: 0x0
0x30: 0x0
0x40: