def test(): from manticore.native import Manticore from manticore.core.smtlib import operators if __name__ == "__main__": m = Manticore("./angrme") else: m = Manticore("./test_hxp2018_angrme/angrme") m.context["solved"] = False max_length = 40 # maximum flag length (rough guess-timate) m.verbosity(1) @m.hook(0x555555555187) def inject_symbolic_input(state): # skip expensive call to fgets state.cpu.RIP = 0x5555555551A0 # manually inject symbolic variable in place of input with m.locked_context() as context: solution = state.new_symbolic_buffer(max_length) # constrain flag format state.constrain(solution[0] == ord("h")) state.constrain(solution[1] == ord("x")) state.constrain(solution[2] == ord("p")) state.constrain(solution[3] == ord("{")) # constrain characters to be printable ASCII or null byte for i in range(max_length): state.constrain( operators.OR( solution[i] == 0, operators.AND(ord(" ") <= solution[i], solution[i] <= ord("}")), ) ) address = state.cpu.RSP + 0x30 context["input_address"] = address print("[+] input address: " + hex(state.cpu.RSP + 0x30)) state.cpu.write_bytes(address, solution) @m.hook(0x555555556390) def abandon(state): print("[-] abandoning path") state.abandon() @m.hook(0x555555556370) def success(state): with m.locked_context() as context: print("[+] found success path") address = context["input_address"] flag = "".join(map(chr, state.solve_buffer(address, max_length))) print("[+] flag: " + flag) with m.locked_context() as context: if "hxp{4nd_n0w_f0r_s0m3_r3al_ch4ll3ng3}" in flag: context["solved"] = True m.kill() m.run() assert m.context["solved"]
def verify(argv): logger.debug(f'Verifying program "{argv}"') # Address and stack_size are from linux.py # TODO(yan): Refactor these constants into a reachable value in platform qemu.start("arm", argv, va_size=stack_top, stack_size=stack_size) gdb.start("arm", argv) m = Manticore(argv[0], argv[1:]) m.verbosity = 2 init_logging() logger.setLevel(logging.DEBUG) @m.hook(None) def on_instruction(state): """ Handle all the hooks for each instruction executed. Ordered as: pre_qemu * qemu exec * post_qemu // svc synchronization happens here (mmap specifically) pre_mcore * mcore exec * post_mcore // all memory written in a mcore syscall gets moved to qemu here """ global initialized, last_instruction # Initialize our state to QEMU's if not initialized: initialize(state) initialized = True if last_instruction: post_mcore(state, last_instruction) # Kernel helpers are inline in QEMU; do nothing if (state.cpu.PC >> 16) == 0xFFFF: return pre_qemu(state) last_mnemonic = [x.strip() for x in gdb.getInstruction().split(":") ][1].split("\t")[0] gdb.stepi() post_qemu(state, last_mnemonic) last_instruction = state.cpu.instruction pre_mcore(state) m.run()
def test(): from manticore.native import Manticore m = Manticore("test_ais3_crackme/ais3_crackme", ["a" * 30]) buffer_addr = 0 num_bytes = 24 with m.locked_context() as w: w[1] = False @m.hook(0x4005CD) def hook(state): print("fake 2 args EDI=2") state.cpu.EDI = 0x2 @m.hook(0x4005F3) def hook(state): print("retreive buffer from rax") global buffer_addr # print state.cpu.read_int(state.cpu.RAX), 'yoo' # assert 0 solution = state.new_symbolic_buffer(num_bytes) state.constrain(solution[0] == ord("a")) state.constrain(solution[1] == ord("i")) state.constrain(solution[2] == ord("s")) state.constrain(solution[3] == ord("3")) state.constrain(solution[4] == ord("{")) buffer_addr = state.cpu.read_int(state.cpu.RAX) with m.locked_context() as w: w[1] = buffer_addr print("buffer addr : %08x " % (buffer_addr)) state.cpu.write_bytes(buffer_addr, solution) @m.hook(0x40060E) def hook(state): state.abandon() print("failure path") @m.hook(0x400602) def hook(state): print("win path: attemping to solve") with m.locked_context() as w: buffer_addr = w[1] res = "".join(map(chr, state.solve_buffer(buffer_addr, num_bytes))) print("flag: %s" % res) if res == "ais3{I_tak3_g00d_n0t3s}": with m.locked_context() as w: w[1] = True m.kill() m.verbosity = 1 m.run() with m.locked_context() as w: assert w[1]
def symbolic_execution(self, targets): log.info("Starting symbolic execution...") linux = make_linux(self.path, auto_load=False) m = Manticore(linux) m.verbosity(0) # change to 2 for debugging buf_addr = targets["buf_addr"] # reached the goal (memcpy call) def reached_goal(state): con_buf = state.solve_buffer(buf_addr, 48) with m.locked_context() as context: context["magic_values"] = con_buf m.terminate() m.add_hook(targets["goal"], reached_goal) #skip intro shit def skip_intro(state): buf = state.new_symbolic_buffer(48) # buffer we will solve state.cpu.write_bytes(buf_addr, buf) state.cpu.RIP = targets["check_start"] m.add_hook(self.binary.symbols[b"__libc_start_main"], skip_intro) # never take jumps for failed solutions def constrain_jump(state): state.constrain(state.cpu.ZF == 1) for jne_addr in targets["jnes"]: m.add_hook(jne_addr, constrain_jump) m.run(procs=1) magic_values = m.context["magic_values"] return magic_values
def test(): from manticore.native import Manticore if __name__ == "__main__": import sys prog = sys.argv[1] params = sys.argv[2:] else: prog = "test_exploit_generation_example/bof" params = ["AAAAAAAAAAAAAAAAAAAAAAA"] m = Manticore(prog, params) m.verbosity(2) # 'trace' will contain the executed instructions m.context["trace"] = [] # None: The hook will be applied to all the instructions @m.hook(None) def record_trace(state): pc = state.cpu.PC ins = state.cpu.instruction # Store the instruction with m.locked_context() as c: c["trace"] += [pc] # We manipulate directly capstone instruction c["last_ins"] = "%s %s" % (ins.mnemonic, ins.op_str) # print(state.cpu) # print(state.mem) m.run() # Print number of instructions recorded and the last executed print("%d instructions are recorded" % len(m.context["trace"])) print("Last instruction executed:") print("0x%x: %s" % (m.context["trace"][-1], m.context["last_ins"])) assert m.context["last_ins"] == "call eax"
class ManticoreTest(unittest.TestCase): _multiprocess_can_split_ = True def setUp(self): dirname = os.path.dirname(__file__) self.m = Manticore( os.path.join(dirname, "binaries", "arguments_linux_amd64")) def test_profiling_data(self): p = Profiler() self.m.verbosity(0) self.m.register_plugin(p) self.m.run() profile_path = os.path.join(self.m.workspace, "profiling.bin") with open(profile_path, "wb") as f: p.save_profiling_data(f) self.assertTrue(os.path.exists(profile_path)) self.assertTrue(os.path.getsize(profile_path) > 0) def test_add_hook(self): def tmp(state): pass entry = 0x00400E40 self.m.add_hook(entry, tmp) self.assertTrue(tmp in self.m._hooks[entry]) def test_hook_dec(self): entry = 0x00400E40 @self.m.hook(entry) def tmp(state): pass self.assertTrue(tmp in self.m._hooks[entry]) def test_hook(self): self.m.context["x"] = 0 @self.m.hook(None) def tmp(state): with self.m.locked_context() as ctx: ctx["x"] = 1 self.m.kill() self.m.run() self.assertEqual(self.m.context["x"], 1) def test_init_hook(self): self.m.context["x"] = 0 @self.m.init def tmp(m, _ready_states): m.context["x"] = 1 m.kill() self.m.run() self.assertEqual(self.m.context["x"], 1) def test_hook_dec_err(self): with self.assertRaises(TypeError): @self.m.hook("0x00400e40") def tmp(state): pass def test_symbol_resolution(self): dirname = os.path.dirname(__file__) self.m = Manticore( os.path.join(dirname, "binaries", "basic_linux_amd64")) self.assertTrue(self.m.resolve("sbrk"), 0x449EE0) def test_symbol_resolution_fail(self): with self.assertRaises(ValueError): self.m.resolve("does_not_exist") def test_integration_basic_stdin(self): import struct dirname = os.path.dirname(__file__) self.m = Manticore( os.path.join(dirname, "binaries", "basic_linux_amd64")) self.m.run() self.m.finalize() workspace = self.m._output.store.uri with open(os.path.join(workspace, "test_00000000.stdin"), "rb") as f: a = struct.unpack("<I", f.read())[0] with open(os.path.join(workspace, "test_00000001.stdin"), "rb") as f: b = struct.unpack("<I", f.read())[0] if a > 0x41: self.assertTrue(a > 0x41) self.assertTrue(b <= 0x41) else: self.assertTrue(a <= 0x41) self.assertTrue(b > 0x41)
#!/usr/bin/env python3 # -*- coding: utf-8 -- from manticore.native import Manticore m = Manticore('./lab1B') m.verbosity(1) """ This lab has 21 unique cases equivalent to switch(0x1337d00d - input): case(1): ... case(2): ... ... case(21): ... by setting our input to 0x1337d00d - 1, we ensure we will hit the first case """ m.context['password'] = 0x1337d00d - 1 @m.hook(0x8048A55) def bad_password(state): """ If this address is reached, the password check has failed. Luckily, there are a limited number of possible cases. We can decrement our input to reach the next case, then manually jump back to the switch """
#!/usr/bin/env python3.6 """ pwnable - collision challenge $ python win.py Solves collision challenge from pwnable.kr, using symbolic execution to determine edge cases that can trigger a hash collision. """ from manticore.native import Manticore from manticore.core.smtlib import operators m = Manticore("./col", ["+" * 20]) m.verbosity(2) m.context["solution"] = None m.context["argv1"] = None @m.init def init(initial_state): """ define constraints for symbolic ARGV before execution """ # determine argv[1] from state.input_symbols by label name argv1 = next(sym for sym in initial_state.input_symbols if sym.name == "ARGV1") if argv1 is None: raise Exception("ARGV was not made symbolic")
""" """ def je_hook(state): # print("je HOOK: Here: {}".format(hex(state.cpu.EIP))) print('constra', state.constraints) res = state.solve_one(state.cpu.read_register('EDI')) # res = state.solve_one(state.cpu.EDI) print(chr(res), res) state.cpu.BL = res """ def exit_hook(state): # print("EXIT HOOK: Here: {}".format(hex(state.cpu.EIP))) state.abandon() for index, items in enumerate(addrs): entry, je_statement, exit_call = items # m.add_hook(je_statement, je_hook) m.add_hook(exit_call, exit_hook) """ def print_ip(state): if 0x400000 < state.cpu.RIP < 0x500000: print(hex(state.cpu.RIP)) """ m.verbosity = 0 m.workers = 1 m.run()
def test(): from manticore.native import Manticore from subprocess import check_output import sys """ Leverages Manticore to solve the manticore challenge: https://blog.trailofbits.com/2017/05/15/magic-with-manticore/ Author: @ctfhacker python win.py =MANTICORE== real 0m52.039s user 0m50.272s sys 0m2.340s """ file = "" if __name__ == "__main__": file = "manticore_challenge" else: file = "./test_manticore_challenge/manticore_challenge" addrs = [] def get_exits(): """ Extract exit calls from each check function using objdump """ def addr(line): """ Get just the address from a line of objdump output """ return int(line.split()[0][:-1], 16) exits_disasm = check_output("objdump -d %s | grep exit" % file, shell=True) exits_disasm = exits_disasm.decode() exits = [addr(line) for line in exits_disasm.split("\n")[2:-1]] for e in exits: yield e m = Manticore(file) m.context["solved"] = False buff_addr = None @m.hook(0x4009A4) def hook(state): """ Jump over `puts` and `fgets` calls """ state.cpu.EIP = 0x4009C1 @m.hook(0x4009C8) def hook(state): """ Inject symbolic buffer instead of fgets """ with m.locked_context() as context: context["buff_addr"] = state.cpu.RDI buffer = state.new_symbolic_buffer(12) state.cpu.write_bytes(state.cpu.RDI, buffer) @m.hook(0x400981) def hook(state): """ Finish all the checks, solve for the solution """ buff_addr = "" with m.locked_context() as context: buff_addr = context["buff_addr"] res = "".join(map(chr, state.solve_buffer(buff_addr, 12))) print("solution: " + res) # =MANTICORE== with m.locked_context() as context: if "=MANTICORE" in res: context["solved"] = True state.abandon() # Be sure to abandon and not continue execution def exit_hook(state): """ Abandon hook for each exit call """ state.abandon() """ For each exit that we found in each of the checks, add the exit_hook to that call """ for index, exit in enumerate(get_exits()): m.add_hook(exit, exit_hook) m.verbosity = 0 m.workers = 1 m.should_profile = True m.run() assert m.context["solved"]
def test(): #!/usr/bin/env python3.6 """ pwnable - collision challenge $ python win.py Solves collision challenge from pwnable.kr, using symbolic execution to determine edge cases that can trigger a hash collision. """ from manticore.native import Manticore from manticore.core.smtlib import operators # initialize Manticore object with symbolic input in # argv[1]. We can eventually solve for this through # state.input_symbol file = "" if __name__ == "__main__": file = "./col" else: file = "./test_pwnable_collision/col" m = Manticore(file, ["+" * 20]) m.context["solution"] = None m.context["argv1"] = None @m.init def init(initial_state): """ define constraints for symbolic ARGV before execution """ # determine argv[1] from state.input_symbols by label name argv1 = next(sym for sym in initial_state.input_symbols if sym.name == "ARGV1") if argv1 is None: raise Exception("ARGV was not made symbolic") # apply constraint for only ASCII characters for i in range(20): initial_state.constrain( operators.AND(ord(" ") <= argv1[i], argv1[i] <= ord("}"))) # store argv1 in global state with m.locked_context() as context: context["argv1"] = argv1 # add fail_state callback to abandon # paths we don't care about def fail_state(state): print("Fail state! Abandoning.") state.abandon() for addr in [0x400C2F, 0x400BE7, 0x400BAC]: m.add_hook(addr, fail_state) @m.hook(0x400BA6) def skip_syscalls(state): """ skip error-checking syscalls """ state.cpu.EIP = 0x400BFA @m.hook(0x400C1C) def success_state(state): """ since input is symbolicated in argv, we search in state.input_symbols to find the label """ with m.locked_context() as context: context["solution"] = state.solve_one(context["argv1"], 20) m.kill() # run Manticore, and print solution m.verbosity(2) m.run() print("EDGE CASE: ", m.context["solution"]) solved = False if "/bin/cat: flag: No such file or directory" in str( check_output([file, m.context["solution"]], stderr=subprocess.STDOUT)): solved = True # print("aaaaaa") # print(check_output([file, m.context["solution"]])) # print("bbbbb") # print(type(check_output([file, m.context["solution"]]))) assert solved
# longer than angr but slightly faster from manticore.native import Manticore m = Manticore("examples/r100", auto_load=False) m.verbosity(0) @m.hook(0x400844) def print_flag(state): with m.locked_context() as context: con_buf = state.solve_buffer(context["buf_addr"], 0xc) con_buf = "".join(chr(c) for c in con_buf) print("FLAG SHOULD BE:", con_buf) m.terminate() @m.hook(0x400838) def symbolicate_password(state): buf = state.new_symbolic_buffer(0xff) # buffer we will solve with m.locked_context() as context: context["buf_addr"] = state.cpu.RAX state.cpu.write_bytes(state.cpu.RAX, buf) ##### skip some libc stuff ##### @m.hook(0x400634) def skip_things(state): state.cpu.RIP = 0x4007e8