Overlapping chunk是通过溢出使得malloc得到的块大小能够覆盖下个相邻块的空间。本文通过两个Demo来理解两种形式的Overlapping chunk。

原理

Overlapping chunk的基本原理是通过溢出修改在某个bin中的victim块的大小,并再次使用malloc申请对应大小的块,由于大小匹配所以会再次得到victim块,并且在程序的视角下victim块覆盖了下一个块,造成对后块的任意修改。

利用

Overlapping chunk有两种利用方式

  1. 先释放块,再溢出修改块大小:需要块大小能够进入Unsorted Bin,由于是单链表可以不管链上的size。
  2. 先溢出修改块大小,再释放块:需要注意释放时不要被TopChunk合并。

Demo

第一种利用方式,首先释放b块,然后溢出a块直至b块的size,将其改为0xd1,其中最后的1是prev_inuse位,表示前块还在使用。只要再次申请的块大小在0xc0-0xc8之间,就都可以得到这个块。

申请一个0xc0大小的块,就能将b的地址重新申请出来,这时b块已经将c块覆盖了。对b块的合法写入将可以修改c块的值。

void vuln1() {
    char *a, *b, *c;
    a = malloc(0x80);
    b = malloc(0x80);
    c = malloc(0x80);
    strcpy(c, "Hello!");
    free(b);
    a[0x88] = 0xd1;
    b = malloc(0xc0);
    puts(c);
    strcpy(b + 0x90, "Hacked!");
    puts(c);
}

第二种利用方式,首先申请abcd四个块,然后溢出a块,修改b块的size为0x121。此时释放b块再申请,就能得到覆盖后块的b块。

修改b块的大小时要注意,不要使它在释放后进入TopChunk,避免不必要的麻烦。

void vuln2() {
    char *a, *b, *c, *d;
    a = malloc(0x80);
    b = malloc(0x80);
    c = malloc(0x80);
    d = malloc(0x80);
    strcpy(c, "Hello!");
    a[0x88] = 0x21;
    a[0x89] = 0x01;
    free(b);
    b = malloc(0x110);
    puts(c);
    strcpy(b + 0x90, "Hacked!");
    puts(c);
}

完整代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void vuln1() {
    char *a, *b, *c;
    a = malloc(0x80);
    b = malloc(0x80);
    c = malloc(0x80);
    strcpy(c, "Hello!");
    free(b);
    a[0x88] = 0xd1;
    b = malloc(0xc0);
    puts(c);
    strcpy(b + 0x90, "Hacked!");
    puts(c);
}

void vuln2() {
    char *a, *b, *c, *d;
    a = malloc(0x80);
    b = malloc(0x80);
    c = malloc(0x80);
    d = malloc(0x80);
    strcpy(c, "Hello!");
    a[0x88] = 0x21;
    a[0x89] = 0x01;
    free(b);
    b = malloc(0x110);
    puts(c);
    strcpy(b + 0x90, "Hacked!");
    puts(c);
}

int main() {
    vuln2();
    return 0;
}

标签: 堆溢出, 二进制, 写个Demo理解堆溢出

添加新评论