Esempio n. 1
0
    def test_introspect_daemon(self):
        self.history = []
        m = Manticore(ms_file, stdin_size=17)
        m.register_daemon(self.introspect_loop)
        m.run()

        sleep(1)  # Leave time for the callback to fire after we've finished
        self.assertGreater(len(self.history), 0)
        progression = []
        for hist in self.history:
            hist = hist.values()
            progression.append((
                sum(1 if (st.state_list == StateLists.ready) else 0
                    for st in hist),
                sum(1 if (st.state_list == StateLists.busy) else 0
                    for st in hist),
                sum(1 if (st.state_list == StateLists.terminated) else 0
                    for st in hist),
            ))
        self.assertEqual(progression[-1][0],
                         0)  # Once finished, we have no ready states
        self.assertEqual(progression[-1][1],
                         0)  # Once finished, we have no busy states
        # Once finished, we have only terminated states.
        self.assertGreater(progression[-1][2], 0)

        f = io.StringIO()
        with contextlib.redirect_stdout(f):
            m.pretty_print_states()
        self.assertIn("Terminated States: {}".format(progression[-1][2]),
                      f.getvalue())
Esempio n. 2
0
class StateHooks(unittest.TestCase):
    def setUp(self):
        core = config.get_group("core")
        core.seed = 61
        core.mprocessing = core.mprocessing.single

        dirname = os.path.dirname(__file__)
        self.m = Manticore(os.path.join(dirname, "binaries", "basic_linux_amd64"), policy="random")

    def test_state_hooks(self):
        @self.m.hook(0x400610, after=True)
        def process_hook(state: State) -> None:
            # We can't remove because the globally applied hooks are stored in
            # the Manticore class, not State
            self.assertFalse(state.remove_hook(0x400610, process_hook, after=True))
            # We can remove this one because it was applied specifically to this
            # State (or its parent)
            self.assertTrue(state.remove_hook(None, do_nothing, after=True))

            state.add_hook(None, do_nothing, after=False)
            state.add_hook(None, do_nothing, after=True)
            state.add_hook(0x400647, fin, after=True)
            state.add_hook(0x400647, fin, after=False)

        for state in self.m.ready_states:
            self.m.add_hook(None, do_nothing, after=True, state=state)

        f = io.StringIO()
        with redirect_stdout(f):
            self.m.run()
        self.assertIn("Reached fin callback", f.getvalue())
Esempio n. 3
0
    def test_daemon(self):
        self.fired = False
        m = Manticore(ms_file, stdin_size=17)
        m.register_daemon(self.daemon)
        m.run()

        self.assertTrue(self.fired)
Esempio n. 4
0
    def test_resume(self):
        m = Manticore(ms_file, stdin_size=17)

        # First instruction of `main`
        @m.hook(0x4009AE)
        def serialize(state):
            with m.locked_context() as context:
                if context.get("kill", False):
                    raise TerminateState("Abandoning...")
                context["kill"] = True
            raise SerializeState("/tmp/ms_checkpoint.pkl")

        m.run()
        self.assertEqual(m.count_terminated_states(), 1)
        for state in m.terminated_states:
            self.assertEqual(state.cpu.PC, 0x4009AE)

        m = Manticore.from_saved_state("/tmp/ms_checkpoint.pkl")
        self.assertEqual(m.count_ready_states(), 1)
        for st in m.ready_states:
            self.assertEqual(state.cpu.PC, 0x4009AE)
        m.run()

        self.assertEqual(m.count_terminated_states(), 18)
        self.assertTrue(
            any("exit status: 0" in str(st._terminated_by) for st in m.terminated_states)
        )
        m.finalize()
        for st in m.terminated_states:
            if "exit status: 0" in str(st._terminated_by):
                self.assertEqual(st.solve_one(st.input_symbols[0]), b"coldlikeminisodas")
Esempio n. 5
0
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"]
Esempio n. 6
0
class StateMergeTest(unittest.TestCase):

    # Need to add a plugin that counts the number of states in did_fork_state, and records the max
    # Then, when we hit

    class StateCounter(Plugin):
        def did_fork_state_callback(self, *_args, **_kwargs):
            self.max_states = max(
                self.max_states,
                self.manticore.count_busy_states()
                + self.manticore.count_ready_states()
                + self.manticore.count_killed_states()
                + self.manticore.count_terminated_states(),
            )

        @property
        def max_states(self):
            with self.manticore.locked_context() as ctx:
                return ctx.setdefault("max_states", 0)

        @max_states.setter
        def max_states(self, new_val):
            with self.manticore.locked_context() as ctx:
                ctx["max_states"] = new_val

    def setUp(self):
        core = config.get_group("core")
        core.seed = 61
        core.mprocessing = core.mprocessing.single

        dirname = os.path.dirname(__file__)
        self.m = Manticore(
            os.path.join(dirname, "binaries", "basic_state_merging"), policy="random"
        )
        self.plugin = self.StateCounter()

        self.m.register_plugin(Merger())
        self.m.register_plugin(self.plugin)

    def test_state_merging(self):
        @self.m.hook(0x40065D)
        def hook_post_merge(*_args, **_kwargs):
            with self.m.locked_context() as ctx:
                ctx["state_count"] = (
                    self.m.count_busy_states()
                    + self.m.count_ready_states()
                    + self.m.count_killed_states()
                    + self.m.count_terminated_states()
                )

        self.m.run()
        s = config.get_group("core").seed
        self.assertLess(
            self.m.context["state_count"],
            self.plugin.max_states,
            f"State merging failed with seed: {s}",
        )
Esempio n. 7
0
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]
Esempio n. 9
0
    def test_custom_introspector(self):
        self.history = []
        m = Manticore(ms_file,
                      introspection_plugin_type=MyIntrospector,
                      stdin_size=17)
        m.register_daemon(self.introspect_loop)
        m.run()

        self.assertGreater(len(self.history), 0)
        self.assertTrue(
            any(
                getattr(st, "i_am_custom", False)
                for st in self.history[-1].values()))
Esempio n. 10
0
def benchmark(program):
    print(f"[*] Benchmarking program \"{program}\"")

    m = Manticore(program)
    m.run(should_profile=True)

    results = m._executor.dump_stats()
    if results is None:
        print(f"[*] Failed to collect stats for program {program}")
        return

    display(results)
    return results
Esempio n. 11
0
    def test_symbolic(self):
        # Create src and dst strings
        # This binary is compiled using gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
        # with flags: -g -static -fno-builtin
        BIN_PATH = os.path.join(os.path.dirname(__file__),
                                "binaries/str_model_tests", "sym_strncpy_test")
        tmp_dir = tempfile.TemporaryDirectory(prefix="mcore_test_sym_")
        m = Manticore(BIN_PATH, stdin_size=10, workspace_url=str(tmp_dir.name))

        addr_of_strncpy = 0x0400490

        @m.hook(addr_of_strncpy)
        def strncpy_model(state):
            state.invoke_model(strncpy)

        m.run()
        m.finalize()

        # Approximate regexes for expected testcase output
        # Example Match above each regex
        # Manticore varies the hex output slightly per run
        expected = [
            # STDIN: b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
            r"STDIN: b\'\\x00(\\x([0-9a-f]{2})){9}\'",
            # STDIN: b'\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff'
            r"STDIN: b\'(\\x((?!(00))([0-9a-f]{2}))){1}\\x00(\\x([0-9a-f]{2})){8}\'",
            # STDIN: b'\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff'
            r"STDIN: b\'(\\x((?!(00))([0-9a-f]{2}))){2}\\x00(\\x([0-9a-f]{2})){7}\'",
            # STDIN: b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff'
            r"STDIN: b\'(\\x((?!(00))([0-9a-f]{2}))){10}\'",
        ]

        inputs = f"{str(m.workspace)}/test_*.input"

        # Make a list of the generated input states
        stdins = []
        for inpt in glob(inputs):
            with open(inpt) as f:
                stdins.append(f.read())

        # Check the number of input states matches the number of regexes
        self.assertEqual(len(stdins), len(expected))

        # Assert that every regex has a matching input
        for e in expected:
            match = False
            for s in stdins:
                if re.fullmatch(e, s) == None:
                    match = True
                    break
            self.assertTrue(match)
Esempio n. 12
0
class UnicornResumeTest(unittest.TestCase):
    _multiprocess_can_split_ = True
    MAIN = 0x402180
    PRE_LOOP = 0x4022EE
    POST_LOOP = 0x402346
    DONE = 0x4024D3
    FAIL = 0x40247C

    def hook_main(self, state: State):
        print("Reached main!!")

    def hook_pre_loop(self, state: State):
        print("Resuming emulation")
        state.cpu.emulate_until(self.POST_LOOP)

    def hook_ret_good(self, state: State):
        print("We made it!")

    def hook_ret_fail(self, state: State):
        self.assertTrue(False, "Target binary called `lose`!")

    def setUp(self):
        dirname = os.path.dirname(__file__)
        self.concrete_instance = Manticore(os.path.join(dirname, "binaries", "rusticorn"))
        self.concrete_instance.register_plugin(ResumeUnicornPlugin())
        self.concrete_instance.add_hook(self.MAIN, callback=self.hook_main)
        self.concrete_instance.add_hook(self.PRE_LOOP, callback=self.hook_pre_loop)
        self.concrete_instance.add_hook(self.DONE, callback=self.hook_ret_good)
        self.concrete_instance.add_hook(self.FAIL, callback=self.hook_ret_fail)

    def test_integration_resume(self):
        f = io.StringIO()
        with contextlib.redirect_stdout(f):
            self.concrete_instance.run()
            self.concrete_instance.finalize()

        output = f.getvalue()
        print(output)
        self.assertIn("Reached main!!", output)
        self.assertIn("Resuming emulation", output)
        self.assertIn("We made it!", output)

        path = self.concrete_instance.workspace + "/test_00000000.stdout"
        with open(path) as stdoutf:
            stdout = stdoutf.read()
        self.assertIn(
            "If we were running under Python, that would have taken a really long time!", stdout
        )
        self.assertIn("You win!", stdout)
        self.assertIn("8031989549026", stdout)
Esempio n. 13
0
def profile(program, sort="cumulative"):
    print(f'[*] Profiling program "{program}"')

    m = Manticore(program)
    m.run(should_profile=True)

    stats = m.get_profiling_stats()
    print(f"[*] Loaded profiling data.")

    if stats is None:
        print(f"[*] Failed to collect stats for program {program}")
        return

    stats.sort_stats(sort)

    stats.print_stats()
Esempio n. 14
0
def profile(program, sort="cumulative"):
    print(f'[*] Profiling program "{program}"')

    m = Manticore(program)
    profiler = Profiler()
    m.register_plugin(profiler)
    m.run()
    m.finalize()

    stats = profiler.get_profiling_data()
    print(f"[*] Loaded profiling data.")

    if stats is None:
        print(f"[*] Failed to collect stats for program {program}")
        return

    stats.sort_stats(sort)

    stats.print_stats()
Esempio n. 15
0
def test_symbolic_length_recv() -> None:
    BIN_PATH = os.path.join(os.path.dirname(__file__), "binaries",
                            "symbolic_length_recv")
    tmp_dir = tempfile.TemporaryDirectory(prefix="mcore_test_")
    m = Manticore(BIN_PATH, workspace_url=str(tmp_dir.name))

    m.run()
    m.finalize()

    found_msg = False
    less_len_msg = "Received less than BUFFER_SIZE"
    outs_glob = f"{str(m.workspace)}/test_*.stdout"
    # Search all output messages
    for output_p in glob(outs_glob):
        with open(output_p) as f:
            if less_len_msg in f.read():
                found_msg = True
                break

    assert found_msg, f'Did not find our message in {outs_glob}: "{less_len_msg}"'
Esempio n. 16
0
def test_symbolic_syscall_arg() -> None:
    BIN_PATH = os.path.join(os.path.dirname(__file__), "binaries",
                            "symbolic_read_count")
    tmp_dir = tempfile.TemporaryDirectory(prefix="mcore_test_")
    m = Manticore(BIN_PATH, argv=["+"], workspace_url=str(tmp_dir.name))

    m.run()
    m.finalize()

    found_win_msg = False
    win_msg = "WIN: Read more than zero data"
    outs_glob = f"{str(m.workspace)}/test_*.stdout"
    # Search all output messages
    for output_p in glob(outs_glob):
        with open(output_p) as f:
            if win_msg in f.read():
                found_win_msg = True
                break

    assert found_win_msg, f'Did not find win message in {outs_glob}: "{win_msg}"'
Esempio n. 17
0
    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 executeDirected(program, pathsObject, args=[]):
    workplace_url = "/tmp/mcore_tmp"
    m = Manticore(program, argv=args, workspace_url=workplace_url, pure_symbolic=False)
    consts = config.get_group("core")
    consts.__setattr__("procs", 1)

    #Store variables in global context to ensure that we can communicate them to the callback function
    with m.locked_context() as context:
        context['paths'] = pathsObject
        context['targets'] = dict()

    #Register hook to have each executed instruction's RIP logged
    m.add_hook(None, log_rip)
    m.register_plugin(DirectedExtractorPlugin())

    #Output the set of paths
    for i in pathsObject.paths:
        l = [hex(j) for j in i.path]
        logger.debug(",".join(l))

    #Execute the directed symbolic execution
    m.run()

    #Obtain the dictionary of control flow edges from Manticore
    with m.locked_context() as context:
        targets = context['targets']

    #Output results
    logger.debug("--Results Sorted by Pathlen--")
    sortedPaths = sorted(pathsObject.paths, key=lambda x: x.pathLen, reverse=False)
    for i in range(pathsObject.pathsLen):
        pathID = sortedPaths[i].pathID
        if pathID in targets.keys():
            logger.debug("Path " + str(pathID) + "[len=" + str(sortedPaths[i].pathLen) + "] ending with " + hex(
                pathsObject.lastAddresses[pathID]) + " has the following successors " +
                  ",".join([str(i) for i in targets[pathID]]))
        else:
            logger.debug("Path " + str(pathID) + "[len=" + str(sortedPaths[i].pathLen) + "]" + " is infeasible")

    return targets
Esempio n. 19
0
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"
Esempio n. 20
0
def symbolic_run(prog, params, trace, pc_crash):
    print "Starting symbolic execution"

    trace_set = set(trace)
    m = Manticore(prog, params)

    # The hook will be applied only to the instruction @pc_crash
    @m.hook(pc_crash)
    def crash_analysis(state):
        # Add the constraint on eax
        state.constrain(state.cpu.EAX == 0x0804887c)  # 0x0804887c = @call_me
        # Retrieve the arguments corresponding to argv[1]
        argv_1 = next((i for i in state.input_symbols if i.name == 'ARGV1_1'),
                      None)
        if argv_1:
            # Ask the value of argv_1 to the solver
            val_argv_1 = state.solve_one(argv_1)
            # Pretty print of the solution
            print "The solution is:"
            print "\\x" + "\\x".join("{:02x}".format(ord(c))
                                     for c in val_argv_1)
        state.abandon()

    trace_set = set(trace)  # convert the list to a set

    # None: The hook will be applied to all the instructions
    @m.hook(None)
    def follow_trace(state):
        if 'visited' not in state.context:
            state.context['visited'] = set()
        state.context['visited'].add(state.cpu.PC)

        # We stop to explore the current path if it doesn't follow the targeted path
        if not state.context['visited'] <= trace_set:
            print "State diverge at 0x%x" % state.cpu.PC
            state.abandon()

    m.run()
Esempio n. 21
0
def concrete_run(prog, params):
    print "Starting concrete execution"

    m = Manticore(prog, params)
    # '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

        # Store the instruction
        with m.locked_context() as c:
            c['trace'] += [pc]

    m.run()

    # Print number of instructions recorded

    with m.locked_context() as c:
        print "%d instructions are recorded" % len(c['trace'])
        return c
Esempio n. 22
0
    def test_symbolic_fork(self):
        # This binary is compiled using gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
        # with flags: -g -static -fno-builtin
        BIN_PATH = os.path.join(os.path.dirname(__file__),
                                "binaries/str_model_tests", "sym_strlen_test")
        tmp_dir = tempfile.TemporaryDirectory(prefix="mcore_test_sym_")
        m = Manticore(BIN_PATH, stdin_size=10, workspace_url=str(tmp_dir.name))

        addr_of_strlen = 0x04404D0

        @m.hook(addr_of_strlen)
        def strlen_model(state):
            state.invoke_model(strlen_exact)

        m.run()
        m.finalize()

        # Expected stdout outputs
        expected = {
            "Length of string is: 0",
            "Length of string is: 1",
            "Length of string is: 2",
            "Length of string is: 3",
            "Length of string is: 4",
            "Length of string is: 5",
        }

        # Make a list of the generated output states
        outputs = f"{str(m.workspace)}/test_*.stdout"
        stdouts = set()
        for out in glob(outputs):
            with open(out) as f:
                stdouts.add(f.read())

        # Assert that every expected stdout has a matching output
        self.assertEqual(expected, stdouts)
class ManticornTest(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'),
                           argv=['argv', 'mc', 'argface'])
        self.concrete_instance = Manticore(os.path.join(
            dirname, 'binaries', 'arguments_linux_amd64'),
                                           argv=['argv', 'mc', 'argface'])

        self.concrete_instance.register_plugin(ConcretePlugin())
        self.concrete_instance.register_plugin(RegisterCapturePlugin())
        self.m.register_plugin(RegisterCapturePlugin())

    def test_register_comparison(self):
        self.m.run()
        self.concrete_instance.run()

        for reg in self.concrete_instance.context:
            self.assertEqual(self.concrete_instance.context[reg],
                             self.m.context[reg])

    def test_integration_basic_stdin(self):
        self.m.run()
        self.concrete_instance.run()

        with open(os.path.join(self.m.workspace, 'test_00000000.stdout'),
                  'r') as f:
            left = f.read().strip()
        with open(
                os.path.join(self.concrete_instance.workspace,
                             'test_00000000.stdout'), 'r') as f:
            right = f.read().strip()

        self.assertEqual(left, right)
Esempio n. 24
0
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)
Esempio n. 25
0
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):
        self.m.run(should_profile=True)
        profile_path = os.path.join(self.m.workspace, 'profiling.bin')
        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):
            self.m.context['x'] = 1
            self.m.terminate()

        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(state):
            self.m.context['x'] = 1
            self.m.terminate()

        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_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()
        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)
Esempio n. 26
0
@m.hook(0x8048A4E)
def success(state):
    """
    If this code is reached, our password must have been correct. Dump our input
    when this address is reached.
    """
    with m.locked_context() as context:
        print("[+] found success path")
        print("[+] password: {}".format(context['password']))
        m.terminate()


@m.hook(0x8048BF6)
def inject_data(state):
    """
    Instead of sending out input through stdin, it's more efficient to jump
    over calls to i/o functions like fgets or puts and inject our data
    manually onto the stack. Because these libc functions are so massive, this
    can give us significant performance improvements.
    """
    with m.locked_context() as context:
        # skip ahead several instructions to jump over puts/fgets/scanf
        state.cpu.EIP = 0x8048C52

        print("[+] injecting " + hex(context['password']))
        state.cpu.EAX = context['password']


m.run(procs=10)
        #

        print(f"introducing symbolic value to {state.cpu.RBP-0xc:x}")

        val = state.new_symbolic_value(32, taint=(taint_id, ))
        state.cpu.write_int(state.cpu.RBP - 0xc, val, 32)

    def has_tainted_operands(operands, taint_id):
        # type: (list[manticore.core.cpu.abstractcpu.Operand], object) -> bool
        for operand in operands:
            op = operand.read()
            if issymbolic(op) and taint_id in op.taint:
                return True
        return False

    every_instruction = None

    @m.hook(every_instruction)
    def check_taint(state):
        insn = state.cpu.instruction  # type: capstone.CsInsn
        if insn is None:
            return
        if insn.mnemonic in ('cmp', 'test'):
            if has_tainted_operands(insn.operands, taint_id):
                print(f'{insn.address:x}: {insn.mnemonic} {insn.op_str}')

    print('Tainted Control Flow:')
    m.run()

    print(f'Analysis finished. See {m.workspace} for results.')
def test():
    from manticore.native import Manticore

    if __name__ == "__main__":
        binary = "./filechecker"
    else:
        binary = "./test_internetwache15-re60/filechecker"

    m = Manticore(binary)
    m.context["solved"] = False

    @m.hook(0x40067A)
    def skip_file_check(state):
        print("Skipping file checking")
        print("Changing PC from {:x} to {:x}".format(0x40067A, 0x4006CA))
        state.cpu.PC = 0x4006CA

    # ignore file operations
    @m.hook(0x4006E1)
    def skip_read_file(state):
        print("Skipping file reading")
        print("Changing PC from {:x} to {:x}".format(0x4006E1, 0x400709))
        state.cpu.PC = 0x400709

    # inject symbolic value at location on stack of fgetc
    @m.hook(0x400709)
    def use_symbolic_password(state):
        context = state.context
        flag = context.setdefault("flag", [])
        count = len(flag)
        char = state.new_symbolic_value(32, "flag.{}".format(count))
        state.constrain(char < 0x100)
        state.constrain(char > 0)

        state.cpu.write_int(state.cpu.RBP - 0x18, char, 32)
        flag.append(char)

    # incorrect path
    @m.hook(0x400732)
    def failure(state):
        print("Found fail path")
        state.abandon()

    # print success
    @m.hook(0x400743)
    def success(state):
        print("Found success path")
        context = state.context
        ans = ""
        for i in context["flag"]:
            ans += chr(state.solve_one(i))

        print(ans)
        if ans == "IW{FILE_CHeCKa}":
            with m.locked_context() as locked:
                locked["solved"] = True
        m.kill()

    print("Start")
    m.run()

    assert m.context["solved"]
class ManticornTest(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'),
                           argv=['argv', 'mc', 'argface'])
        self.concrete_instance = Manticore(os.path.join(
            dirname, 'binaries', 'arguments_linux_amd64'),
                                           argv=['argv', 'mc', 'argface'])

        self.concrete_instance.register_plugin(ConcretePlugin())
        '''
        self.concrete_instance.register_plugin(RegisterCapturePlugin())
        self.m.register_plugin(RegisterCapturePlugin())
        '''

    @unittest.skip("Registers simply not matching for now")
    def test_register_comparison(self):
        self.m.run()
        self.concrete_instance.run()

        concrete_regs = {}
        normal_regs = {}
        for st in self.m.all_states:
            all_regs = st.platform.current.all_registers
            for reg in all_regs:
                normal_regs[reg] = getattr(st.platform.current, reg)

        for st in self.concrete_instance.all_states:
            all_regs = st.platform.current.canonical_registers
            for reg in all_regs:
                concrete_regs[reg] = getattr(st.platform.current, reg)

        for reg in concrete_regs:
            print(reg, concrete_regs[reg], normal_regs[reg])

        for reg in concrete_regs:
            self.assertEqual(concrete_regs[reg], normal_regs[reg])
        '''
        concrete_regs = self.concrete_instance.context['regs']
        normal_regs = self.m.context['regs']
        for reg in concrete_regs.keys():
            self.assertEqual(concrete_regs[reg],normal_regs[reg])
        '''

    def test_integration_basic_stdin(self):
        self.m.run()
        self.concrete_instance.run()

        self.m.finalize()
        self.concrete_instance.finalize()

        with open(os.path.join(self.m.workspace, 'test_00000000.stdout'),
                  'r') as f:
            left = f.read().strip()
        with open(
                os.path.join(self.concrete_instance.workspace,
                             'test_00000000.stdout'), 'r') as f:
            right = f.read().strip()

        self.assertEqual(left, right)
Esempio n. 30
0
class ManticornTest(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"),
            argv=["argv", "mc", "argface"],
        )
        self.concrete_instance = Manticore(
            os.path.join(dirname, "binaries", "arguments_linux_amd64"),
            argv=["argv", "mc", "argface"],
        )

        self.concrete_instance.register_plugin(ConcretePlugin())
        """
        self.concrete_instance.register_plugin(RegisterCapturePlugin())
        self.m.register_plugin(RegisterCapturePlugin())
        """

    def test_register_comparison(self):
        self.m.run()
        self.concrete_instance.run()

        should_match = {
            "RAX",
            "RDX",
            "RBX",
            "RSP",
            "RBP",
            "RSI",
            "RDI",
            "R8",
            "R9",
            "R10",
            "R12",
            "R13",
            "R14",
            "R15",
            "RIP",
            "CS",
            "DS",
            "ES",
            "SS",
            "FS",
            "GS",
            "AF",
            "CF",
            "DF",
            "IF",
            "OF",
            "SF",
            "FP0",
            "FP1",
            "FP2",
            "FP3",
            "FP4",
            "FP5",
            "FP6",
            "FP7",
            "FPSW",
            "FPCW",
        }

        concrete_regs = {}
        normal_regs = {}
        self.assertEqual(len(list(self.m.terminated_states)),
                         len(list(self.concrete_instance.terminated_states)))
        self.assertGreater(len(list(self.m.terminated_states)), 0)
        for st in self.m.terminated_states:
            for reg in should_match:
                normal_regs[reg] = getattr(st.platform.current, reg)

        for st in self.concrete_instance.terminated_states:
            for reg in should_match:
                concrete_regs[reg] = getattr(st.platform.current, reg)

        for reg in should_match:
            self.assertEqual(
                concrete_regs[reg],
                normal_regs[reg],
                f"Mismatch in {reg}: {concrete_regs[reg]} != {normal_regs[reg]}",
            )

    def test_integration_basic_stdout(self):
        self.m.run()
        self.concrete_instance.run()

        self.m.finalize()
        self.concrete_instance.finalize()

        with open(os.path.join(self.m.workspace, "test_00000000.stdout"),
                  "r") as f:
            left = f.read().strip()
        with open(
                os.path.join(self.concrete_instance.workspace,
                             "test_00000000.stdout"), "r") as f:
            right = f.read().strip()

        self.assertEqual(left, right)