特征标志

  • 仅存在 off by null 漏洞

  • 不能申请大于 fastbin 的堆块(可以申请也能用这种方法)

    如果能申请大于 fastbin 的堆块,申请 0x101 覆盖成 0x100 并控制 prev_size ,就能向低地址的堆块合并

  • 存在 scanf (或其他将 fastbin 放置到 unsortedbin 的途径)

    单纯 offbynull 无法在 fastbin 中利用,需要结合 unsortedbin

适用glibc版本

无论有无 tcache ,都能适用。

存在 tcache 则需要先将对应 size 填满,才能放入 fastbin 。

攻击效果

造成堆重叠(chunk extend),进而控制各类 bin 中的指针,完成 getshell

原理

难点在于:fastbin 堆块的 size 长度为 1 个字节(如:0xf0),如果 offbynull 覆盖 prev_inuse 时,会将整个 size 覆盖为 0x00 ,而这会引起报错。

解决思路:

  1. 利用 unsortedbin 形成时,会将其所在的前一个(高地址)非 topchunk 的堆块 prev_size 设置为 0
  2. 利用 offbynull 修改在 unsortedbin 中的空闲堆块 size ,造成空洞。将 unsortedbin 重新分配出来时,前一个堆块 prev_size=0 的状态被保留
  3. 在原来 unsortedbin 的连续空间中,在低地址处构造出 unsortedbin ,释放前一个堆块时会向后合并,重叠部分堆空间

Demo程序

程序有问题,等待完善

Scanf 申请的缓存区问题

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <stdio.h>
#include <stdlib.h>

char *ptr[16];

void init(){
setvbuf(stdin,0,2,0);
setvbuf(stdout,0,2,0);
setvbuf(stderr,0,2,0);
}

int main(int argc,char *argv[]){
// init();
char* protect;
char buf[0x1000];

ptr[0]=malloc(0x18);//用于offbynull
ptr[1]=malloc(0x68);
ptr[2]=malloc(0x68);
ptr[3]=malloc(0x28);
ptr[4]=malloc(0x68);//用于先后合并形成堆重叠
protect=malloc(0x100);//防止与topchunk合并

free(ptr[1]);
free(ptr[2]);
free(ptr[3]);

/* chunk3内伪造header绕过检查 */
*((long int*)ptr[3]+2) = 0x100;//offbynull修改后的size
*((long int*)ptr[3]+3) = 0x10;

/* chunk4的prev_inuse成功被设定为0 */
scanf("%s",buf);//fastbin 2 unsortedbin

/* off bu null,空闲堆块大小从0x110变成0x100 */
*(ptr[0]+0x18)=0x00;

/* 切割0x100,切割完成之后unsortedbin原来堆块没有了 */
ptr[1]=malloc(0x68);
ptr[2]=malloc(0x68);
ptr[3]=malloc(0x18);

/* 布置一个unsortedbin用于向后unlink */
free(ptr[1]);
free(ptr[2]);
scanf("%s",buf);//fastbin 2 unsortedbin

/* 向后unlink,形成堆重叠 */
free(ptr[4]);
scanf("%s",buf);//fastbin 2 unsortedbin

return 0;
}

详细过程

  1. 如图布置出相邻的堆块:

    • chunk0 用于 offbynull ;chunk123 用于修改 chunk4 prev_inuse ;chunk4 用于向后 unlink 形成堆重叠
    • 伪造 chunk header :prev_size 为 offbynull 之后的 size

    Untitled Diagram1

  2. 将 chunk123 释放后进入 fastbin ,然后利用 scanf 将 fastbin 的空闲堆块整理进入 unsortedbin

    Untitled Diagram (1)

  3. offbynull 修改在 unsortedbin 的堆 size

    Untitled Diagram (5)

  4. 然后将空闲堆块切分多次取出(因为不能申请大于 fastbin)。当申请 0x20 时,修改的是 fake header 的 prev_inuse 标志位,chunk4 prev_inuse 被保留下来

    Untitled Diagram (3)

  5. 将 chunk12 重新放回 unsortedbin 后,释放 chunk4 造成向后 unlink ,形成堆重叠

    Untitled Diagram2

    Untitled Diagram6

  6. 造成重叠后就是常规思路利用

相关例题