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
| import angr import sys import claripy
def main(filepath): project = angr.Project(filepath) init_state = project.factory.entry_state()
class ReplacementScanf(angr.SimProcedure): def run(self, format_string, key_address, input_address): scanf0 = claripy.BVS('scanf0', 4*8) scanf1 = claripy.BVS('scanf1', 20*8) for chr in scanf1.chop(bits=8): self.state.add_constraints(chr >= '0', chr <= 'z')
self.state.memory.store( key_address, scanf0, endness=project.arch.memory_endness) self.state.memory.store( input_address, scanf1, endness=project.arch.memory_endness)
self.state.globals['solution0'] = scanf0 self.state.globals['solution1'] = scanf1
scanf_symbol = '__isoc99_scanf' project.hook_symbol(scanf_symbol, ReplacementScanf())
def check_strncpy(state): strncpy_src = state.memory.load(state.regs.esp+8,4,endness=project.arch.memory_endness) strncpy_dest = state.memory.load(state.regs.esp+4,4,endness=project.arch.memory_endness) strncpy_len = state.memory.load(state.regs.esp+12,4,endness=project.arch.memory_endness) src_contents = state.memory.load(strncpy_src, strncpy_len) if(state.solver.symbolic(strncpy_dest) and state.solver.symbolic(src_contents)): password = "QOOCPPEV" password_address = 0x59554248 does_src_hold_password = src_contents[-1:-64] == password does_dest_equal_buffer_address = password_address==strncpy_dest
if state.satisfiable(extra_constraints=(does_src_hold_password, does_dest_equal_buffer_address)): state.add_constraints(does_src_hold_password, does_dest_equal_buffer_address) return True else: return False else: return False def is_successful(state): strncpy_address = 0x8048410 if(state.addr == strncpy_address): return check_strncpy(state) else: return False
sim = project.factory.simgr(init_state) sim.explore(find=is_successful) if sim.found: solution_state = sim.found[0] solution0 = solution_state.solver.eval(solution_state.globals['solution0'],cast_to=int) solution1 = solution_state.solver.eval(solution_state.globals['solution1'], cast_to=bytes) print(solution0,solution1[::-1]) else: raise Exception('Could not find the solution')
if __name__ == "__main__": if(len(sys.argv) != 2): print('usage:python angr_basic.py filepath') filepath = sys.argv[1] main(filepath)
|