#!/usr/bin/env python2'''' Three parts' 0) Dump the ASM from IDA, Start @ 0x40107C and the length is 0x79 (see box @ loc_401029)' bytes = idaapi.get_many_bytes(0x40107C, 0x79)' with open('/home/firefly/buffer.asm', 'wb') as f:' f.write(bytes)' 1) Figure out what byte the code needs to be xor'ed with. Last word must match 0xfb5eL (loop at 401039, comparison check: 40105E)' Code to be xor'ed and add'ed is located at 40107C and the length is 0x79 (see box @ loc_401029)' To determine the input byte the modified (xord + add) bytes have to be passed through sub_4011E6 before the comparison check can be done' 2) After the check passes the state memory from angr needs to be interpreted as code, so use capstone' The op_str from capstone contains what looks like ASCII characters...' 3) Take the capstone output and interpret the ASCII codes to get the flag'''importangrimportsysp=angr.Project('greek_to_me.exe',load_options={'auto_load_libs':False})f2=None# Interate through all of the possible byte values to find the correct "user" input to de-mask the flagforbufinxrange(0x100):print("Trying buf = {0}".format(buf))# Variable to store the bits written to disk using IDAasm=None# Store the output from the first de-obfuscation routineb2=[]# Read in bytes written to file from IDAwithopen('greek_to_me_buffer.asm','rb')asf:asm=f.read()# Re-implement loc_401039dl=bufforbyteinasm:bl=ord(byte)bl=bl^dlbl=bl&0xffbl=bl+0x22bl=bl&0xffb2.append(bl)# Set up angr to "run" sub_4011E6 s=p.factory.blank_state(addr=0x4011E6)s.mem[s.regs.esp+4:].dword=1# Angr memory location to hold the xor'ed and add'ed bytess.mem[s.regs.esp+8:].dword=0x79# Length of ASM# Copy bytes output from loc_401039 into address 0x1 so Angr can run itasm=''.join(map(lambdax:chr(x),b2))s.memory.store(1,s.se.BVV(int(asm.encode('hex'),16),0x79*8))# Create a simulation manager...#import pdb; pdb.set_trace()simgr=p.factory.simulation_manager(s)# Tell Angr where to go, though there is only one way through this function, # we just need to stop after ax is setsimgr.explore(find=0x401268)# Once ax is set, check to see if the value in ax matches the comparison valueforfoundinsimgr.found:#import pdb; pdb.set_trace()print(' ax = %s'%hex(found.state.solver.eval(found.state.regs.ax)))# Comparison checkifhex(found.state.solver.eval(found.state.regs.ax))=='0xfb5eL':# Upon success, dump the asmcode=("%x"%found.state.solver.eval_upto(found.state.memory.load(1,0x79),1)[0]).decode('hex')print('\n Winner is: {0}\n\n'.format(buf))print(' %s'%code)bl=Nonedl=Noneflag=[]# Using capstone, interpret the ASMfromcapstoneimport*md=Cs(CS_ARCH_X86,CS_MODE_32)foriinmd.disasm(code,0x1000):flag_char=None# The if statements do the work of interpreting the ASCII codes to their value counterpartifi.op_str.split(',')[0].startswith("byte ptr"):flag_char=chr(long(i.op_str.split(',')[1],16))ifi.op_str.split(',')[0].startswith('bl'):bl=chr(long(i.op_str.split(',')[1],16))ifi.op_str.split(',')[0].startswith('dl'):dl=chr(long(i.op_str.split(',')[1],16))ifi.op_str.split(',')[1].strip()=='dl':flag_char=dlifi.op_str.split(',')[1].strip()=='bl':flag_char=blif(flag_char):flag.append(flag_char.strip())print(" 0x%x\t%s\t%s\t%s"%(i.address,i.mnemonic,i.op_str,flag_char))print('\n\n')print(''.join(flag))sys.exit(0)
HTTPSSSH
You can clone a snippet to your computer for local editing.
Learn more.