一、概念
- __malloc_hook攻击原理为fastbin attack,见文章:https://blog.csdn.net/qq_41453285/article/details/99315504。
- 通过fastbin attack,我们可以发起__malloc_hook攻击,将__malloc_hook作为我们的target。
二、攻击方向
- 方向①:我们可以将__malloc_hook函数指针改为got表中的其它函数指针,那么当执行malloc的时候就回去直接执行我们修改的函数。
- 方向②:如果我们将__malloc_hook函数指针修改为one_gadget的地址,那么我们就可以在执行malloc的时候起一个shell。
三、攻击方法
- 第一步:进程的__malloc_hook地址一定为0x7ffff7dd1b10,所以我们将0x7ffff7dd1b10作为我们的target目标。
- 第二步:但是由于0x7ffff7dd1b10地址的指定偏移处的size成员数值不能够满足glibc的检测,因此我们需要在__malloc_hook地址附近找一块合适的地址作为我们的攻击目标。下图可以看出0x7ffff7dd1b10地址的数值都为0不符合要求。
-
第三步:通过尝试发现,0x7ffff7dd1b10-0x23地址处的指定8字节偏移处的数值能够满足glibc的检测,所以我们最终把0x7ffff7dd1b10-0x23=0x7ffff7dd1aed地址作为我们的攻击目标。从下图可以看出,0x7ffff7dd1b10-0x23地址的数值为0x7f,满足size成员的要求。
四、演示案例
#include<stdio.h>
#include<malloc.h>
#include<unistd.h>
#include<string.h>
int main(){
int size = 0x60;
char *p = malloc(size);
long __malloc_hook_addr = 0x7ffff7dd1b10;
printf("%p\n",p);
sleep(0); //第一步,sleep函数为了程序打断点使用,无其他作用
free(p);
sleep(0); //第二步
printf("%p\n",p);
*(long *)p = __malloc_hook_addr - 0x23;
sleep(0); //第三步
char *q = malloc(size);
printf("%p\n",q);
sleep(0); //第四步
char *r = malloc(size);
printf("%p\n",r);
sleep(0); //第五步
strcpy(r,"aaajunkjunkjunkjunkbbbbbbbb");
sleep(0); //第六步
malloc(0);
sleep(0); //第七步
return 0;
}
第一步
- 在此处我们申请了一个chunk堆块,返回的指针为p(chunk的fd指针为p),并且从下图可以看到,申请的chunk头尾0x602000,printf打印的p(chunk的fd指针)指针为0x602010。
- 并且程序的__malloc_hook函数地址就为0x7ffff7dd1b10。
第二步
- 释放p,那么该chunk进入0x70~0x80大小范围的fastbin链中了,此时p指针还指向于chunk的fd成员处。
第三步
- 由于__malloc_hook的地址不能够过系统的检测,我们将0x7ffff7dd1b10-0x23地址作为我们的攻击目标。
- 在程序中我们将*p赋值为0x7ffff7dd1b10-0x23,也就是将fd的值变为攻击目标的地址。
- 通过bins我们可以看到,本来freechunk的fd指针指向于0的,现在指向于我们的0x7ffff7dd1aed了(0x7ffff7dd1b10-0x23)。
第四步
- 此时我们再去malloc(0x60),就是将我们刚才free的p申请出来使用了,并且p和q指向于同一块地址。
- 由于p和q指向于同一地址,所以printf打印的地址也为0x602010。
- 如果是正常释放,此时bin头的fd指针应该指向于0x0的,但是由于我们更改了freechunk的fd指针,所以malloc移除chunk之后,bin头的fd指针指向于我们的目标地址0x7ffff7dd1aed了。
第五步
- 此时bin链的fd指向于我们的目标地址了,当我们再去malloc的时候,系统会将我们这块目标地址给我们使用,此时我们可以通过r指针来读写这块内存地址了。
- 通过printf打印的内容可以看出,目标地址为0x7ffff7dd1aed,但是malloc的时候会偏移0x10,所以r的指针为0x7ffff7dd1aed+0x10=0x7ffff7dd1afd。
- 由于目标地址为0x7ffff7dd1aed,而malloc的返回地址为0x7ffff7dd1aed+0x10(r的地址)。
- 又因为目标地址是通过__malloc_hook的地址0x7ffff7dd1b10-0x23得到的,所以r的地址+0x13=就是我们__malloc_hook的地址。
第六步
- 此处我们向目标地址处写入了字符串“aaajunkjunkjunkjunkbbbbbbbb”。通过计算地址偏移,字符串“bbbbbbbb”会被写入到原本存放__malloc_hook函数地址的地方。
- 查看内存可以看到,存放__malloc_hook函数的地方被写入了字符串“bbbbbbbb”。
第七步
- 我们知道malloc函数执行的时候会先检测__malloc_hook是否为空,如果不为空就执行__mallochook。
- 此处我们将__malloc_hook地址内容写入了字符串“bbbbbbbb”,所以当malloc的时候,系统检测到此处有内容,就去执行,但是一执行,发现是字符串,于是就报错退出了。
- 我是小董,V公众点击"笔记白嫖"解锁更多【堆漏洞挖掘】资料内容。