def main(): mem_type = int(sys.argv[1] if len(sys.argv) > 1 else 1) proj = angr.Project(os.path.dirname(os.path.realpath(__file__)) + '/crackme0x05', load_options={"auto_load_libs": False}) plugins = {} if mem_type == 1: mem_memory, reg_memory = factory.get_range_fully_symbolic_memory(proj) plugins['memory'] = mem_memory initial_state = proj.factory.entry_state(plugins=plugins) sm = proj.factory.simulation_manager(initial_state) def correct(state): try: return 'Password OK' in state.posix.dumps(1) except: return False def wrong(state): try: return 'Password Incorrect' in state.posix.dumps(1) except: return False sm.explore(find=correct, avoid=wrong) #print sm.found[0].posix.dumps(1) return sm.found[0].posix.dumps(0) # .lstrip('+0').rstrip('B')
def main(mem_type=1): project = angr.Project( os.path.dirname(os.path.realpath(__file__)) + "/ais3_crackme") plugins = {} if mem_type == 1: mem_memory, reg_memory = factory.get_range_fully_symbolic_memory( project) plugins['memory'] = mem_memory #create an initial state with a symbolic bit vector as argv1 argv1 = claripy.BVS( "argv1", 100 * 8) #since we do not the length now, we just put 100 bytes initial_state = project.factory.entry_state(args=["./crackme1", argv1], plugins=plugins) #create a path group using the created initial state sm = project.factory.simulation_manager(initial_state) #symbolically execute the program until we reach the wanted value of the instruction pointer sm.explore( find=0x400602 ) #at this instruction the binary will print the "correct" message found = sm.found[0] #ask to the symbolic solver to get the value of argv1 in the reached state as a string solution = found.solver.eval(argv1, cast_to=str) solution = solution[:solution.find("\x00")] return solution
def get_state(proj, start, mem_type=1, remove_options=set()): mem_type = int(sys.argv[1]) if len(sys.argv) > 1 else mem_type plugins = {} if mem_type == 1: mem_memory, reg_memory = factory.get_range_fully_symbolic_memory(proj) plugins['memory'] = mem_memory add_options = None #add_options = {angr.options.CACHELESS_SOLVER} state = proj.factory.blank_state(addr=start, plugins=plugins, remove_options=remove_options, add_options=add_options) if mem_type == 0: state.memory.write_strategies.insert( 0, angr.concretization_strategies.SimConcretizationStrategyRange( sys.maxsize)) state.memory.read_strategies.insert( 0, angr.concretization_strategies.SimConcretizationStrategyRange( sys.maxsize)) return state
def main(mem_type=1): proj = angr.Project( os.path.dirname(os.path.realpath(__file__)) + '/angrybird') # There's a couple anti-run instructions in this binary. # Yes, anti-run. That's not a typo. plugins = {} if mem_type == 1: mem_memory, reg_memory = factory.get_range_fully_symbolic_memory(proj) plugins['memory'] = mem_memory # Because I'm not interested in fixing a weird binary, I'm going to skip all the beginning of the program. # this also skips a bunch of initialization, so let's fix that: state = proj.factory.entry_state(addr=START_ADDR, plugins=plugins) state.regs.rbp = state.regs.rsp # using the same values as the binary doesn't work for these variables, I think because they point to the GOT and the binary is using that to try to fingerprint that it's loaded in angr. Setting them to pointers to symbolic memory works fine. state.mem[state.regs.rbp - 0x70].long = 0x1000 state.mem[state.regs.rbp - 0x68].long = 0x1008 state.mem[state.regs.rbp - 0x60].long = 0x1010 state.mem[state.regs.rbp - 0x58].long = 0x1018 sm = proj.factory.simulation_manager( state) # Create the SimulationManager. sm.explore( find=FIND_ADDR ) # This will take a couple minutes. Ignore the warning message(s), it's fine. found = sm.found[-1] flag = found.posix.dumps(0) # This trims off anything that's not printable. return flag[:20]
def common(self, file): p = os.path.dirname(os.path.realpath(__file__)) explorer = executor.Executor(p + '/binary/' + file) angr_project = explorer.project mem_memory, reg_memory = factory.get_range_fully_symbolic_memory( angr_project) return explorer.run(mem_memory=mem_memory, reg_memory=reg_memory, verbose=False)
def main(mem_type = 1): proj = angr.Project(os.path.dirname(os.path.realpath(__file__)) + '/crackme0x00a', load_options={"auto_load_libs": False}) plugins = {} if mem_type == 1: mem_memory, reg_memory = factory.get_range_fully_symbolic_memory(proj) plugins['memory'] = mem_memory initial_state = proj.factory.entry_state(plugins=plugins) sm = proj.factory.simulation_manager(initial_state) sm.explore(find=FIND_ADDR, avoid=AVOID_ADDR) return sm.found[0].posix.dumps(0).split('\0')[0] # stdin
def main(): mem_type = int(sys.argv[1] if len(sys.argv) > 1 else 1) proj = angr.Project(os.path.dirname(os.path.realpath(__file__)) + '/crackme0x03', load_options={"auto_load_libs": False}) plugins = {} if mem_type == 1: mem_memory, reg_memory = factory.get_range_fully_symbolic_memory(proj) plugins['memory'] = mem_memory initial_state = proj.factory.entry_state(plugins=plugins) sm = proj.factory.simulation_manager(initial_state) sm.explore(find=FIND_ADDR, avoid=AVOID_ADDR) return sm.found[0].posix.dumps(0).lstrip('+0').rstrip('B')
def main(): mem_type = int(sys.argv[1] if len(sys.argv) > 1 else 1) proj = angr.Project(os.path.dirname(os.path.realpath(__file__)) + '/crackme0x04', load_options={"auto_load_libs": False}) plugins = {} if mem_type == 1: mem_memory, reg_memory = factory.get_range_fully_symbolic_memory(proj) plugins['memory'] = mem_memory initial_state = proj.factory.entry_state(plugins=plugins) sm = proj.factory.simulation_manager(initial_state) cfg = proj.analyses.CFG() FIND_ADDR = cfg.kb.functions.function(name="exit").addr AVOID_ADDR = 0x080484fb # dword [esp] = str.Password_Incorrect__n ; [0x8048649:4]=0x73736150 LEA str.Password_Incorrect__n ; "Password Incorrect!." @ 0x8048649 sm.explore(find=FIND_ADDR, avoid=AVOID_ADDR) # embed() #print sm.found[0].posix.dumps(1) return sm.found[0].posix.dumps(0) # .lstrip('+0').rstrip('B')
def test_memory(self): angr_project = angr.Project("/bin/ls", load_options={'auto_load_libs': False}) mem_memory, reg_memory = factory.get_range_fully_symbolic_memory( angr_project) plugins = {} if mem_memory is not None: plugins['memory'] = mem_memory pass state = angr_project.factory.entry_state( remove_options={angr.options.LAZY_SOLVES}, plugins=plugins) test_symbolic_access(state.copy()) test_store_with_symbolic_size(state.copy()) test_store_with_symbolic_addr_and_symbolic_size(state.copy()) test_concrete_merge(state.copy()) test_concrete_merge_with_condition(state.copy()) test_symbolic_merge(state.copy())
import sys from executor import executor from memory import factory from memory import range_fully_symbolic_memory from utils import parse_args if __name__ == '__main__': t, file = parse_args(sys.argv) explorer = executor.Executor(file) angr_project = explorer.project if t == 0: mem_memory, reg_memory = factory.get_angr_symbolic_memory(angr_project) elif t == 1: mem_memory, reg_memory = factory.get_range_fully_symbolic_memory( angr_project) mem_memory.verbose = False explorer.run(mem_memory=mem_memory, reg_memory=reg_memory) if t == 1 and range_fully_symbolic_memory.profiling_enabled: range_fully_symbolic_memory.print_profiling_time_stats()
def main(mem_type = 1): l = logging.getLogger("angr.engines.successors") l.setLevel(logging.ERROR) project = angr.Project(os.path.dirname(os.path.realpath(__file__)) + "/CADET_00001") plugins = {} if mem_type == 1: mem_memory, reg_memory = factory.get_range_fully_symbolic_memory(project) plugins['memory'] = mem_memory initial_state = project.factory.entry_state(plugins=plugins) #let's find the buffer overflow (overwriting the return address) #overwriting the return pointer with user-controllable data will generate #an "unconstrained" state: the symbolic executor does not know how to proceed #since the instruction pointer can assume any value #by default angr discards unconstrained paths, so we need to specify the #save_unconstrained option sm = project.factory.simulation_manager(initial_state, save_unconstrained=True) #symbolically execute the binary until an unconstrained path is reached while len(sm.unconstrained)==0: sm.step() unconstrained_state = sm.unconstrained[0] crashing_input = unconstrained_state.posix.dumps(0) #cat crash_input.bin | ./CADET_00001.adapted will segfault unconstrained_state.posix.dump(0,"crash_input.bin") #let's now find the easter egg (it takes about 2 minutes) #now we want angr to avoid "unfeasible" paths #by default, "lazy solving" is enabled, this means that angr will not #automatically discard unfeasible paths #to disable "lazy solving" we generate a blank path and we change its options, #then we specify this path as the initial path of the path group sm = project.factory.simulation_manager(project.factory.entry_state()) #at this point we just ask angr to reach the basic block where the easter egg #text is printed sm.explore(find=0x804833E) found = sm.found[0] solution1 = found.posix.dumps(0) found.posix.dump(0,"easteregg_input1.bin") #you can even check if the easter egg has been found by checking stdout stdout1 = found.posix.dumps(1) #an alternative way to avoid unfeasible paths (paths that contain an unsatisfiable set #of constraints) is to "manually" step the path group execution and call prune() sm = project.factory.simulation_manager() while True: sm.step() sm.prune() #we "manually" ask angr to remove unfeasible paths found_list = [active for active in sm.active if active.addr == 0x804833E] if len(found_list) > 0: break found = found_list[0] solution2 = found.posix.dumps(0) found.posix.dump(0,"easteregg_input2.bin") #you can even check if the easter egg has been found by checking stdout stdout2 = found.posix.dumps(1) return (crashing_input, solution1, stdout1, solution2, stdout2)
def main(mem_type=1): p = angr.Project(os.path.dirname(os.path.realpath(__file__)) + "/license", load_options={'auto_load_libs': False}) plugins = {} if mem_type == 1: mem_memory, reg_memory = factory.get_range_fully_symbolic_memory(p) plugins['memory'] = mem_memory # Create a blank state state = p.factory.blank_state(plugins=plugins) # Build the file whose name is weird license_name = "_a\nb\tc_" # This is the license file # From analyzing the binary, we know that the license file should have five # lines in total, and each line has 6 characters. Not setting file content # may also work, but in that case, angr will produce many more paths, and we # will spent much more time in path trimming. bytes = None constraints = [] for i in xrange(5): line = [] for j in xrange(6): line.append(state.solver.BVS('license_file_byte_%d_%d' % (i, j), 8)) state.add_constraints(line[-1] != 0x0a) if bytes is None: bytes = state.solver.Concat(*line) else: bytes = state.solver.Concat(bytes, state.solver.BVV(0x0a, 8), *line) content = angr.state_plugins.SimSymbolicMemory(memory_id="file_%s" % license_name) content.set_state(state) content.store(0, bytes) license_file = angr.storage.SimFile(license_name, 'rw', content=content, size=len(bytes) / 8) # Build the file system dict # This interface might change in the near future fs = {license_name: license_file} state.posix.fs = fs ex = p.surveyors.Explorer(start=state, find=(0x400e93, ), avoid=(0x400bb1, 0x400b8f, 0x400b6d, 0x400a85, 0x400ebf, 0x400a59)) ex.run() # One path will be found found = ex.found[0] rsp = found.regs.rsp flag_addr = rsp + 0x278 - 0xd8 # Ripped from IDA # Perform an inline call to strlen() in order to determine the length of the # flag FAKE_ADDR = 0x100000 strlen = lambda state, arguments: \ angr.SIM_PROCEDURES['libc']['strlen'](p, FAKE_ADDR, p.arch).execute( state, arguments=arguments ) flag_length = strlen(found, arguments=[flag_addr]).ret_expr # In case it's not null-terminated, we get the least number as the length flag_length_int = min(found.solver.eval_upto(flag_length, 3)) # Read out the flag! flag_int = found.solver.eval(found.memory.load(flag_addr, flag_length_int)) flag = hex(flag_int)[2:-1].decode("hex") return flag