def get_default_value_by_type(type_, state=None): """ Java specify defaults values for primitive and reference types. This method returns the default value for a given type. :param str type_: Name of type. :return: Default value for this type. """ if type_ in ['byte', 'char', 'short', 'int', 'boolean']: return BVS('default_value_{}'.format(type_), 32) elif type_ == "long": return BVS('default_value_{}'.format(type_), 64) elif type_ == 'float': return FPS('default_value_{}'.format(type_), FSORT_FLOAT) elif type_ == 'double': return FPS('default_value_{}'.format(type_), FSORT_DOUBLE) elif state is not None: if type_ == 'java.lang.String': return SimSootValue_StringRef.new_string(state, StringS('default_value_{}'.format(type_), 1000)) if type_.endswith('[][]'): raise NotImplementedError # multiarray = SimSootExpr_NewMultiArray.new_array(self.state, element_type, size) # multiarray.add_default_value_generator(lambda s: SimSootExpr_NewMultiArray._generate_inner_array(s, element_type, sizes)) # return multiarray elif type_.endswith('[]'): array = SimSootExpr_NewArray.new_array(state, type_[:-2], BVV(2, 32)) return array else: return SimSootValue_ThisRef.new_object(state, type_, symbolic=True, init_object=False) else: # not a primitive type # => treat it as a reference return SootNullConstant()
def _get_default_symbolic_value_by_type(type_, state): if type_ in ['byte', 'char', 'short', 'int', 'boolean']: return BVS('default_value_{}'.format(type_), 32) if type_ == "long": return BVS('default_value_{}'.format(type_), 64) if type_ == 'float': return FPS('default_value_{}'.format(type_), FSORT_FLOAT) if type_ == 'double': return FPS('default_value_{}'.format(type_), FSORT_DOUBLE) if type_ == 'java.lang.String': return SimSootValue_StringRef.new_string( state, StringS('default_value_{}'.format(type_), 1000)) if type_.endswith('[][]'): raise NotImplementedError # multiarray = SimSootExpr_NewMultiArray.new_array(self.state, element_type, size) # multiarray.add_default_value_generator(lambda s: SimSootExpr_NewMultiArray._generate_inner_array(s, element_type, sizes)) # return multiarray if type_.endswith('[]'): array = SimSootExpr_NewArray.new_array(state, type_[:-2], BVV(2, 32)) return array return SimSootValue_ThisRef.new_object(state, type_, symbolic=True, init_object=False)
def make_pickles(): p = angr.Project(os.path.join(tests_location, 'i386', 'fauxware')) fs = { '/dev/stdin': SimFile('/dev/stdin'), '/dev/stdout': SimFile('/dev/stdout'), '/dev/stderr': SimFile('/dev/stderr'), #'/dev/urandom': SimFile('/dev/urandom', 0), } MEM_SIZE = 1024 mem_bvv = {} for f in fs: mem = BVS(f, MEM_SIZE * 8) mem_bvv[f] = mem # debug_wait() f = open("pickletest_good", "wb") #fname = f.name pickle.dump(mem_bvv, f, -1) f.close() # If you do not have a state you cannot write entry_state = p.factory.entry_state(fs=fs) #pylint:disable=unused-variable for f in fs: mem = mem_bvv[f] fs[f].write(0, mem, MEM_SIZE) f = open("pickletest_bad", "wb") #fname = f.name pickle.dump(mem_bvv, f, -1) f.close()
def make_pickles(): p = angr.Project("/bin/bash") fs = { '/dev/stdin': SimFile('/dev/stdin', 0), '/dev/stdout': SimFile('/dev/stdout', 0), '/dev/stderr': SimFile('/dev/stderr', 0), #'/dev/urandom': SimFile('/dev/urandom', 0), } MEM_SIZE = 1024 mem_bvv = {} for f in fs: mem = BVS(f, MEM_SIZE * 8) mem_bvv[f] = mem # debug_wait() f = open("/tmp/pickletest_good", "w") #fname = f.name pickle.dump(mem_bvv, f) f.close() # If you do not have a state you cannot write entry_state = p.factory.entry_state(fs=fs) #pylint:disable=unused-variable for f in fs: mem = mem_bvv[f] fs[f].write(mem, MEM_SIZE) fs[f].seek(0) f = open("/tmp/pickletest_bad", "w") #fname = f.name pickle.dump(mem_bvv, f) f.close()
def solve(): ''' Function Solve: 1. Create the angr project 2. Remove Lazy Solves 3. Set up command line arguments 4. Explore 5. Print flag from found path Python v2.7.12 angr v7.7.9.8.post1 Performance: Pylint score: 10/10 Runtime: ~6 seconds ''' # Create the angr project proj = Project('./challenge', load_options={"auto_load_libs": False}) initial_state = proj.factory.entry_state() # Discard lazy solves to speed up angr initial_state.options.discard("LAZY_SOLVES") # Program wants 31 command line arguments # The first argument is the program: ./challenge # The rest or the arguments are each one byte of the flag argument_list = ['./challenge'] for i in range(0, 30): argument_list.append(BVS("argv{}".format(i), 8)) # Pass arguments to program initial_state = proj.factory.entry_state(args=argument_list) # Create the path group path_group = proj.factory.simgr(initial_state) # Address of call to sym.success__ in main. successAddress = 0x400c70 # Find a path to the desired address path_group.explore(find=successAddress) # Get first found path found = path_group.found[0] # For every argument find the value used in the path flag = "" for arg in argument_list[1:]: flag += found.state.se.eval(arg, cast_to=str) # Print the result print flag
def state_entry(self, args=None, **kwargs): # pylint: disable=arguments-differ """ Create an entry state. :param args: List of SootArgument values (optional). """ state = self.state_blank(**kwargs) # for the Java main method `public static main(String[] args)`, # we add symbolic cmdline arguments if not args and state.addr.method.name == 'main' and \ state.addr.method.params[0] == 'java.lang.String[]': cmd_line_args = SimSootExpr_NewArray.new_array( state, "java.lang.String", BVS('argc', 32)) cmd_line_args.add_default_value_generator( self.generate_symbolic_cmd_line_arg) args = [SootArgument(cmd_line_args, "java.lang.String[]")] # for referencing the Java array, we need to know the array reference # => saves it in the globals dict state.globals['cmd_line_args'] = cmd_line_args # setup arguments SimEngineSoot.setup_arguments(state, args) return state
def nop_hook(s): pass ## hook mtspr instructions #proj.hook(0x77c, hook, length=4) #proj.hook(0x784, hook, length=4) # # hook external functions proj.hook(BASE + 0x9C8, nop_hook, length=4) # 0x68f0c #proj.hook(0x1a0, nop_hook, length=4) # 0x68f0c s = proj.factory.blank_state(addr=START) mem_location = BVS('mem_199400_location', 8) s.memory.store(0x199400, mem_location) s.options.add(angr.options.BYPASS_UNSUPPORTED_SYSCALL) s.options.add(angr.options.TRACK_MEMORY_ACTIONS) s.inspect.b('mem_read', when=angr.BP_BEFORE, action=mem_read_hook) s.inspect.b('mem_write', when=angr.BP_BEFORE, action=mem_write_hook) simgr = proj.factory.simgr(s) #r = simgr.explore(find=0x674) #r = simgr.explore(find=0x16c) #number of path to search r = simgr.explore(find=END, num_find=4) for save in r.found: #added later for syscall vals
def get_jni_function_params(proj, func_addr, jenv_ptr): constraints = [] record = Record.RECORDS.get(func_addr) if record is None: raise RecordNotFoundError('Relevant JNI function record not found!') # for user's JNI function, the first 2 parameters are hidden from Java side # and the first one will always be the JNIEnv pointer. params = [jenv_ptr] # Some parameters need to be cooperated with state update, this dict will # be returned for this purpose. state_updates = dict() jclass = JavaClass(record.cls) if record.static_method: jclass.init = True # The second hidden parameter is either a jclass or jobject of the current # Java class where the native method lives. If it is a static method in # Java side, it will be a jclass otherwise a jobject. ref = proj.loader.extern_object.allocate() obj_symbol = BVS("param_#0", proj.arch.bits) constraints.append(obj_symbol == ref) state_updates.update({ref: jclass}) params.append(obj_symbol) state_updates.update({ref: jclass}) # prepare for the none hidden parameters plist = None if record.signature is not None: plist, has_obj = parse_params_from_sig(record.signature) # if no object references passed via parameters, we let Angr to use default # setups. Since it will not affect our analysis. if plist is not None and has_obj: symbol_values = { 'Z': BVS('boolean_value', proj.arch.bits), '[Z': BVS('boolean_array', proj.arch.bits), 'B': BVS('byte_value', proj.arch.bits), '[B': BVS('byte_array', proj.arch.bits), 'C': BVS('char_value', proj.arch.bits), '[C': BVS('char_array', proj.arch.bits), 'S': BVS('short_value', proj.arch.bits), '[S': BVS('short_array', proj.arch.bits), 'I': BVS('int_value', proj.arch.bits), '[I': BVS('int_array', proj.arch.bits), 'J': BVS('long_value', proj.arch.bits), '[J': BVS('long_array', proj.arch.bits), 'F': BVS('float_value', proj.arch.bits), '[F': BVS('float_array', proj.arch.bits), 'D': BVS('double_value', proj.arch.bits), '[D': BVS('double_array', proj.arch.bits), } param_nb = 0 for p in plist: param = symbol_values.get(p) if param is None: cls_name = p.lstrip('[').replace('/', '.') jclass = None if cls_name == 'java.lang.Class': desc = 'object of java.lang.Class passed as parameter to ' +\ 'JNI function which makes it not possible to get ' +\ 'the class name' jclass = JavaClass(None, desc=desc) else: jclass = JavaClass(cls_name, init=True) if p.startswith('['): jclass.is_array = True ref = proj.loader.extern_object.allocate() obj_symbol = BVS("param_#%i" % (param_nb + 1), proj.arch.bits) constraints.append(obj_symbol == ref) state_updates.update({ref: jclass}) param = obj_symbol params.append(param) param_nb += 1 return params, state_updates, constraints