Пример #1
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())
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
Пример #3
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)
Пример #4
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
Пример #5
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)
Пример #6
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)
Пример #7
0
            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()
Пример #8
0
"""
"""
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()
Пример #9
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()
        set_verbosity(0)
        self.m.register_plugin(p)
        self.m.run()
        self.m.finalize()
        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)

        profile_path_2 = os.path.join(self.m.workspace, "profiling_2.bin")
        with open(profile_path_2, "wb") as f:
            p.save_profiling_data(f)

        self.assertTrue(os.path.exists(profile_path_2))
        self.assertTrue(os.path.getsize(profile_path_2) > 0)

        self.assertTrue(filecmp.cmp(profile_path, profile_path_2))

    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_add_hook_after(self):
        def tmp(state):
            pass

        entry = 0x00400E40
        self.m.add_hook(entry, tmp, after=True)
        assert tmp in self.m._after_hooks[entry]

    def test_hook_after_dec(self):
        entry = 0x00400E40

        @self.m.hook(entry, after=True)
        def tmp(state):
            # Make sure we've executed the instruction at entry and we're at
            # the next one (but before it executes).
            assert state.cpu.PC == 0x00400E42
            self.m.kill()

        self.m.run()

        assert tmp in self.m._after_hooks[entry]

    def test_add_sys_hook(self):
        name = "sys_brk"
        index = 12

        def tmp(state):
            assert state._platformn._syscall_abi.syscall_number() == index
            self.m.kill()

        self.m.add_hook(name, tmp, syscall=True)
        self.assertTrue(tmp in self.m._sys_hooks[index])

    def test_sys_hook_dec(self):
        index = 12

        @self.m.hook(index, syscall=True)
        def tmp(state):
            assert state._platformn._syscall_abi.syscall_number() == index
            self.m.kill()

        self.assertTrue(tmp in self.m._sys_hooks[index])

    def test_sys_hook(self):
        self.m.context["x"] = 0

        @self.m.hook(None, syscall=True)
        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_add_sys_hook_after(self):
        def tmp(state):
            pass

        index = 12
        self.m.add_hook(index, tmp, after=True, syscall=True)
        assert tmp in self.m._sys_after_hooks[index]

    def test_sys_hook_after_dec(self):
        name = "sys_mmap"
        index = 9

        @self.m.hook(name, after=True, syscall=True)
        def tmp(state):
            pass

        self.m.run()

        assert tmp in self.m._sys_after_hooks[index]

    def test_init_hook(self):
        self.m.context["x"] = 0

        @self.m.init
        def tmp(_state):
            self.m.context["x"] = 1
            self.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)
Пример #10
0
    global buff_addr
    buff_addr = state.cpu.RDI
    buffer = state.new_symbolic_buffer(12)
    state.cpu.write_bytes(buff_addr, buffer)


@m.hook(0x400981)
def hook(state):
    """ Finish all the checks, solve for the solution """
    res = ''.join(map(chr, state.solve_buffer(buff_addr, 12)))
    print(res)  # =MANTICORE==
    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()
Пример #11
0
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"]
Пример #12
0
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