Exemple #1
0
class EthDetectorTest(unittest.TestCase):
    """
    Subclasses must assign this class variable to the class for the detector
    """
    DETECTOR_CLASS = None

    def setUp(self):
        self.mevm = ManticoreEVM()
        self.mevm.verbosity(0)
        self.worksp = self.mevm.workspace

    def tearDown(self):
        self.mevm = None
        shutil.rmtree(self.worksp)

    def _test(self, name, should_find):
        """
        Tests DetectInvalid over the consensys benchmark suit
        """
        mevm = self.mevm

        filename = os.path.join(THIS_DIR, 'binaries', 'detectors',
                                '{}.sol'.format(name))

        self.mevm.register_detector(self.DETECTOR_CLASS())
        mevm.multi_tx_analysis(filename,
                               contract_name='DetectThis',
                               args=(mevm.make_symbolic_value(), ))

        expected_findings = set(((c, d) for b, c, d in should_find))
        actual_findings = set(((c, d) for a, b, c, d in mevm.global_findings))
        self.assertEqual(expected_findings, actual_findings)
    def _find_test_cases(self):
        print('Finding test cases ...')
        self._main_evm = ManticoreEVM(workspace_url=self._args.workspace)

        if self._args.quick_mode:
            self._args.avoid_constant = True
            self._args.exclude_all = True
            self._args.only_alive_testcases = True
            consts_evm = config.get_group("evm")
            consts_evm.oog = "ignore"
            consts.skip_reverts = True

        if consts.skip_reverts:
            self._main_evm.register_plugin(SkipRevertBasicBlocks())

        if consts.explore_balance:
            self._main_evm.register_plugin(KeepOnlyIfStorageChanges())

        if self._args.limit_loops:
            self._main_evm.register_plugin(LoopDepthLimiter())

        with self._main_evm.kill_timeout():
            self._main_evm.multi_tx_analysis(
                self._args.argv[0],
                contract_name=self._args.contract,
                tx_limit=self._args.txlimit,
                tx_use_coverage=not self._args.txnocoverage,
                tx_send_ether=not self._args.txnoether,
                tx_account=self._args.txaccount,
                tx_preconstrain=self._args.txpreconstrain,
                compile_args=vars(self._args),
            )

        self._test_cases = list(self._main_evm.all_states)
Exemple #3
0
    def test_graceful_handle_no_alive_states(self):
        """
        If there are no alive states, or no initial states, we should not crash. issue #795
        """
        # initiate the blockchain
        m = ManticoreEVM()
        source_code = '''
        contract Simple {
            function f(uint a) payable public {
                if (a == 65) {
                    revert();
                }
            }
        }
        '''

        # Initiate the accounts
        user_account = m.create_account(balance=1000)
        contract_account = m.solidity_create_contract(source_code,
                                                      owner=user_account,
                                                      balance=0)

        contract_account.f(1)  # it works
        contract_account.f(65)  # it works
        with self.assertRaises(NoAliveStates):
            contract_account.f(
                m.SValue)  # no alive states, but try to run a tx anyway
class EthDetectorTest(unittest.TestCase):
    """
    Subclasses must assign this class variable to the class for the detector
    """
    DETECTOR_CLASS = None

    def setUp(self):
        self.mevm = ManticoreEVM()
        self.mevm.verbosity(0)
        self.worksp = self.mevm.workspace

    def tearDown(self):
        self.mevm = None
        shutil.rmtree(self.worksp)

    def _test(self, name, should_find, use_ctor_sym_arg=False):
        """
        Tests DetectInvalid over the consensys benchmark suit
        """
        mevm = self.mevm

        dir = os.path.join(THIS_DIR, 'binaries', 'detectors')
        filepath = os.path.join(dir, f'{name}.sol')

        if use_ctor_sym_arg:
            ctor_arg = (mevm.make_symbolic_value(),)
        else:
            ctor_arg = ()

        self.mevm.register_detector(self.DETECTOR_CLASS())
        mevm.multi_tx_analysis(filepath, contract_name='DetectThis', args=ctor_arg, working_dir=dir)

        expected_findings = set(((finding, at_init) for finding, at_init in should_find))
        actual_findings = set(((finding, at_init) for _addr, _pc, finding, at_init in mevm.global_findings))
        self.assertEqual(expected_findings, actual_findings)
Exemple #5
0
    def setUp(self):
        evm_consts = config.get_group("evm")
        self.saved_sha3 = evm_consts.sha3
        evm_consts.sha3 = evm_consts.sha3.fake

        self.mevm = ManticoreEVM()
        self.worksp = self.mevm.workspace
Exemple #6
0
 def test_run_solc(self):
     source_a = '''
     import "./B.sol";
     contract A {
         function callB(B _b) public { _b.fromA(); }
         function fromB() public { revert(); }
     }
     '''
     source_b = '''
     import "./A.sol";
     contract B {
         function callA(A _a) public { _a.fromB(); }
         function fromA() public { revert(); }
     }
     '''
     d = tempfile.mkdtemp()
     try:
         with open(os.path.join(d, 'A.sol'),
                   'w') as a, open(os.path.join(d, 'B.sol'), 'w') as b:
             a.write(source_a)
             a.flush()
             b.write(source_b)
             b.flush()
             output, warnings = ManticoreEVM._run_solc(a)
             source_list = output.get('sourceList', [])
             self.assertIn(os.path.split(a.name)[-1], source_list)
             self.assertIn(os.path.split(b.name)[-1], source_list)
     finally:
         shutil.rmtree(d)
Exemple #7
0
 def test_run_solc_with_remappings(self):
     source_a = '''
     import "test/B.sol";
     contract A {
         function callB(B _b) public { _b.fromA(); }
         function fromB() public { revert(); }
     }
     '''
     source_b = '''
     import "../A.sol";
     contract B {
         function callA(A _a) public { _a.fromB(); }
         function fromA() public { revert(); }
     }
     '''
     d = tempfile.mkdtemp()
     lib_dir = os.path.join(d, 'lib')
     os.makedirs(lib_dir)
     try:
         with open(os.path.join(d, 'A.sol'),
                   'w') as a, open(os.path.join(lib_dir, 'B.sol'),
                                   'w') as b:
             a.write(source_a)
             a.flush()
             b.write(source_b)
             b.flush()
             output, warnings = ManticoreEVM._run_solc(
                 a, solc_remaps=['test=lib'])
             source_list = output.get('sourceList', [])
             self.assertIn("A.sol", source_list)
             self.assertIn("lib/B.sol", source_list)
     finally:
         shutil.rmtree(d)
class EthRetVal(unittest.TestCase):
    """ https://consensys.net/diligence/evm-analyzer-benchmark-suite/ """
    def setUp(self):
        self.mevm = ManticoreEVM()
        self.mevm.verbosity(0)
        self.worksp = self.mevm.workspace

    def tearDown(self):
        self.mevm = None
        shutil.rmtree(self.worksp)

    def _test(self, name, should_find):
        """
        Tests DetectInvalid over the consensys benchmark suit
        """
        mevm = self.mevm

        filename = os.path.join(THIS_DIR, 'binaries', 'detectors',
                                '{}.sol'.format(name))

        self.mevm.register_detector(DetectUnusedRetVal())
        mevm.multi_tx_analysis(filename,
                               contract_name='DetectThis',
                               args=(mevm.make_symbolic_value(), ))

        expected_findings = set(((c, d) for b, c, d in should_find))
        actual_findings = set(((c, d) for a, b, c, d in mevm.global_findings))
        self.assertEqual(expected_findings, actual_findings)

    def test_retval_ok(self):
        name = inspect.currentframe().f_code.co_name[5:]
        self._test(name, set())

    def test_retval_not_ok(self):
        name = inspect.currentframe().f_code.co_name[5:]
        self._test(
            name,
            set([(337, 'Returned value at CALL instruction is not used', False)
                 ]))

    def test_retval_crazy(self):
        name = inspect.currentframe().f_code.co_name[5:]
        self._test(name, set())

    def test_retval_lunatic(self):
        name = inspect.currentframe().f_code.co_name[5:]
        self._test(name, set())
Exemple #9
0
class EthDetectorTest(unittest.TestCase):
    """
    Subclasses must assign this class variable to the class for the detector
    """

    DETECTOR_CLASS = None

    def setUp(self):
        self.mevm = ManticoreEVM()
        self.mevm.register_plugin(KeepOnlyIfStorageChanges())
        log.set_verbosity(0)
        self.worksp = self.mevm.workspace

    def tearDown(self):
        self.mevm = None
        shutil.rmtree(self.worksp)

    def _test(self, name, should_find, use_ctor_sym_arg=False):
        """
        Tests DetectInvalid over the consensys benchmark suit
        """
        mevm = self.mevm

        dir = os.path.join(THIS_DIR, "contracts", "detectors")
        filepath = os.path.join(dir, f"{name}.sol")

        if use_ctor_sym_arg:
            ctor_arg = (mevm.make_symbolic_value(),)
        else:
            ctor_arg = ()

        self.mevm.register_detector(self.DETECTOR_CLASS())

        with self.mevm.kill_timeout(240):
            mevm.multi_tx_analysis(
                filepath,
                contract_name="DetectThis",
                args=ctor_arg,
                compile_args={"solc_working_dir": dir},
            )
        mevm.finalize()
        expected_findings = set(((finding, at_init) for finding, at_init in should_find))
        actual_findings = set(
            ((finding, at_init) for _addr, _pc, finding, at_init in mevm.global_findings)
        )
        self.assertEqual(expected_findings, actual_findings)
Exemple #10
0
    def test_parse_tx(self):
        m = ManticoreEVM()
        source_code = '''
        contract C{
            mapping(address => uint) balances;
            function test1(address to, uint val){
                balances[to] = val;
            }
        }
        '''
        user_account = m.create_account(balance=1000, name='user_account')
        contract_account = m.solidity_create_contract(source_code, owner=user_account, name='contract_account')


        calldata = binascii.unhexlify(b'9de4886f9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d')
        returndata = b'' 
        md = m.get_metadata(contract_account)
        self.assertEqual(md.parse_tx(calldata, returndata), 'test1(899826498278242188854817720535123270925417291165, 71291600040229971300002528024956868756719167029433602173313100742126907268509)')
Exemple #11
0
class EthBenchmark(unittest.TestCase):
    """ https://consensys.net/diligence/evm-analyzer-benchmark-suite/ """
    def setUp(self):
        self.mevm = ManticoreEVM()
        self.mevm.verbosity(0)
        self.worksp = self.mevm.workspace

    def tearDown(self):
        self.mevm = None
        shutil.rmtree(self.worksp)

    def _test_assert(self, name, should_find):
        """
        Tests DetectInvalid over the consensys benchmark suit
        """
        mevm = self.mevm

        d = DetectInvalid()
        mevm.register_detector(d)

        filename = os.path.join(THIS_DIR, 'binaries', 'benchmark',
                                '{}.sol'.format(name))

        mevm.multi_tx_analysis(filename, tx_limit=3)

        actual_findings = set(((b, c, d) for a, b, c, d in d.global_findings))
        self.assertEqual(should_find, actual_findings)

    def test_assert_minimal(self):
        self._test_assert('assert_minimal',
                          set([(95, 'INVALID intruction', False)]))

    def test_assert_constructor(self):
        self._test_assert('assert_constructor',
                          set([(23L, 'INVALID intruction', True)]))

    def test_assert_multitx_1(self):
        self._test_assert('assert_multitx_1', set())

    def test_assert_multitx_2(self):
        self._test_assert('assert_multitx_2',
                          set([(150, 'INVALID intruction', False)]))
Exemple #12
0
 def manticore(self):
     if self._manticore is None:
         if self._assigned_manticore is None:
             # we do lazy evaluation of ManticoreClient.manticore so self.log_directory will be assigned already
             if self.log_directory is None:
                 workspace = None
             else:
                 workspace = self.log_directory
             self._assigned_manticore = ManticoreEVM(
                 workspace_url=workspace)
         self._manticore = threadwrapper.MainThreadWrapper(
             self._assigned_manticore, _CONTROLLER)
         self._finalize_manticore()
     return self._manticore
Exemple #13
0
 def test_int_ovf(self):
     mevm = ManticoreEVM()
     mevm.register_detector(DetectIntegerOverflow())
     filename = os.path.join(THIS_DIR, 'binaries/int_overflow.sol')
     mevm.multi_tx_analysis(filename, tx_limit=1)
     self.assertEqual(len(mevm.global_findings), 3)
     all_findings = ''.join([x[2] for x in mevm.global_findings])
     self.assertIn('Unsigned integer overflow at SUB instruction', all_findings)
     self.assertIn('Unsigned integer overflow at ADD instruction', all_findings)
     self.assertIn('Unsigned integer overflow at MUL instruction', all_findings)
Exemple #14
0
 def test_int_ovf(self):
     mevm = ManticoreEVM()
     mevm.register_detector(IntegerOverflow())
     filename = os.path.join(THIS_DIR, 'binaries/int_overflow.sol')
     mevm.multi_tx_analysis(filename)
     self.assertEqual(len(mevm.global_findings), 3)
     all_findings = ''.join(map(lambda x: x[2], mevm.global_findings))
     self.assertIn('underflow at SUB', all_findings)
     self.assertIn('overflow at ADD', all_findings)
     self.assertIn('overflow at MUL', all_findings)
    def _run_test_case_on_contract(self, contract_code, conc_txs):
        m2 = ManticoreEVM()
        owner_account = m2.create_account(
            balance=10**10,
            name="owner",
            address=self._main_evm.accounts.get('owner').address)
        attacker_account = m2.create_account(
            balance=10**10,
            name="attacker",
            address=self._main_evm.accounts.get('attacker').address)
        try:
            call_args = get_argument_from_create_transaction(
                self._main_evm, conc_txs[0])
            create_value = m2.make_symbolic_value()
            m2.constrain(create_value == conc_txs[0].value)
            contract_account = solidity_create_contract_with_zero_price(
                m2,
                contract_code,
                owner=owner_account,
                args=call_args,
                balance=create_value,
                gas=0,
            )
        except Exception as e:
            return m2

        for conc_tx in conc_txs[1:]:
            try:
                m2.transaction(
                    caller=conc_tx.caller,
                    address=contract_account,
                    value=conc_tx.value,
                    data=conc_tx.
                    data,  # data has all needed metadata like function id ([:4]) and argument passed to function
                    gas=0,
                    price=0)
            except Exception as e:
                return m2

        return m2
def scenario1():
    m = ManticoreEVM()

    market = initialize(m,
                        parameters={'pr_fl': 10**6},
                        market_owner_token_balance=10**21)

    bob = init_user(m, market, 'bob', 100 * ONE_ETH)
    eve = init_user(m, market, 'eve', 100 * ONE_ETH)

    calls_support(market, [(eve, 1 * ONE_ETH), (bob, 10 * ONE_ETH)])

    market.reserve_contract.withdraw(caller=eve.account)
    print("[+] Eve called support")

    check_balance(m, market, eve)

    print(f"[+] Look for results in {m.workspace}")
Exemple #17
0
    def test_end_instruction_trace(self):
        """
        Make sure that the trace files are correct, and include the end instructions
        """
        class TestPlugin(Plugin):
            """
            Record the pcs of all end instructions encountered. Source of truth.
            """
            def will_evm_execute_instruction_callback(self, state, instruction,
                                                      arguments):
                if isinstance(state.platform.current.last_exception, Create):
                    name = 'init'
                else:
                    name = 'rt'

                # collect all end instructions based on whether they are in init or rt
                if instruction.semantics in ('REVERT', 'STOP', 'RETURN'):
                    with self.locked_context(name) as d:
                        d.append(state.platform.current.pc)

        mevm = ManticoreEVM()
        p = TestPlugin()
        mevm.register_plugin(p)

        filename = os.path.join(THIS_DIR, 'binaries/int_overflow.sol')
        mevm.multi_tx_analysis(filename, tx_limit=1)

        worksp = mevm.workspace
        listdir = os.listdir(worksp)

        def get_concatenated_files(directory, suffix):
            paths = [
                os.path.join(directory, f) for f in listdir
                if f.endswith(suffix)
            ]
            concatenated = ''.join(open(path).read() for path in paths)
            return concatenated

        all_init_traces = get_concatenated_files(worksp, 'init.trace')
        all_rt_traces = get_concatenated_files(worksp, 'rt.trace')

        # make sure all init end insns appear somewhere in the init traces
        for pc in p.context['init']:
            self.assertIn(':0x{:x}'.format(pc), all_init_traces)

        # and all rt end insns appear somewhere in the rt traces
        for pc in p.context['rt']:
            self.assertIn(':0x{:x}'.format(pc), all_rt_traces)
Exemple #18
0
    def test_emit_did_execute_end_instructions(self):
        class TestDetector(Detector):
            def did_evm_execute_instruction_callback(self, state, instruction, arguments, result):
                if instruction.semantics in ('REVERT', 'STOP'):
                    with self.locked_context('insns', dict) as d:
                        d[instruction.semantics] = True

        mevm = ManticoreEVM()
        p = TestDetector()
        mevm.register_detector(p)

        filename = os.path.join(THIS_DIR, 'binaries/int_overflow.sol')
        mevm.multi_tx_analysis(filename, tx_limit=1)

        self.assertIn('insns', p.context)
        context = p.context['insns']
        self.assertIn('STOP', context)
        self.assertIn('REVERT', context)
Exemple #19
0
def test():
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-

    __author__ = "Raz0r"
    __email__ = "*****@*****.**"
    """
    This is a solution to the PolySwarm's smart contract hacking challenge done with manticore.
    Please refer to https://raz0r.name/writeups/polyswarm-smart-contract-hacking-challenge-writeup/ for a complete walk through.
    """

    import binascii
    from manticore.ethereum import ManticoreEVM, ABI

    m = ManticoreEVM()
    m.context["solved"] = False

    # Set up accounts with original addresses
    owner_account = m.create_account(
        balance=1000,
        name="owner",
        address=0xBC7DDD20D5BCEB395290FD7CE3A9DA8D8B485559)
    attacker_account = m.create_account(
        balance=1000,
        name="attacker",
        address=0x762C808237A69D786A85E8784DB8C143EB70B2FB,
    )
    cashmoney_contract = m.create_account(
        balance=1000,
        name="CashMoney",
        address=0x64BA926175BC69BA757EF53A6D5EF616889C9999,
    )

    # Create WinnerLog contract using its init bytecode
    file = ""
    if __name__ == "__main__":
        file = "winnerlog.bin"
    else:
        file = "test_polyswarm_challenge/winnerlog.bin"

    with open(file, "rb") as f:
        bytecode = f.read()

    winnerlog_contract = m.create_contract(
        init=bytecode,
        owner=owner_account,
        name="WinnerLog",
        address=0x2E4D2A597A2FCBDF6CC55EB5C973E76AA19AC410,
    )

    # Allow cashmoney_contract to call logWinner() on winnerlog_contract
    m.transaction(
        caller=owner_account,
        address=winnerlog_contract,
        data=binascii.unhexlify(
            b"c3e8512400000000000000000000000064ba926175bc69ba757ef53a6d5ef616889c9999"
        ),
        value=0,
    )

    # Prepare symbready_statesand call logWinner() with that symbolic buffer
    symbolic_data = m.make_symbolic_buffer(64)
    calldata = ABI.function_call("logWinner(address,uint256,bytes)",
                                 attacker_account, 0, symbolic_data)
    m.transaction(
        caller=cashmoney_contract,
        address=winnerlog_contract,
        data=calldata,
        value=0,
        gas=10000000,
    )

    # Look for a running state that is not reverted
    for state in m.ready_states:
        world = state.platform
        result = state.solve_one(symbolic_data)
        print("[+] FOUND: {}".format(binascii.hexlify(result)))
        with m.locked_context() as context:
            context["solved"] = True
        break
    assert m.context["solved"]
 def setUp(self):
     self.mevm = ManticoreEVM()
class EthPluginsTests(unittest.TestCase):
    def setUp(self):
        self.mevm = ManticoreEVM()

    def tearDown(self):
        # shutil.rmtree(self.mevm.workspace)
        del self.mevm

    @unittest.skip("failing")
    def test_verbose_trace(self):
        source_code = """contract X {}"""
        self.mevm.register_plugin(VerboseTrace())

        # owner address is hardcodded so the contract address is predictable
        owner = self.mevm.create_account(
            balance=1000, address=0xAFB6D63079413D167770DE9C3F50DB6477811BDB
        )

        # Initialize contract so it's constructor function will be traced
        self.mevm.solidity_create_contract(source_code, owner=owner, gas=90000)

        files = set(os.listdir(self.mevm.workspace))
        # self.assertEqual(len(files), 0)  # just a sanity check? workspace
        # contains .state_id and other config files
        # Shall produce a verbose trace file
        with self.assertLogs("manticore.core.manticore", level="INFO") as cm:
            self.mevm.finalize()
            prefix = "\x1b[34mINFO:\x1b[0m:m.c.manticore"
            # self.assertEqual(f'{prefix}:Generated testcase No. 0 - RETURN', cm.output[0])
            self.assertEqual(f"{prefix}:Results in {self.mevm.workspace}", cm.output[0])
            # self.assertEqual(f'{prefix}:Total time: {self.mevm._last_run_stats["time_elapsed"]}', cm.output[2])
            self.assertEqual(len(cm.output), 1)

        import re

        files = set((f for f in os.listdir(self.mevm.workspace) if re.match(r"[^.].*", f)))
        expected_files = {
            "global_X.runtime_visited",
            "global_X_runtime.bytecode",
            "test_00000000.verbose_trace",
            "global_X.sol",
            "global_X.runtime_asm",
            "global_X.init_asm",
            "global_X.init_visited",
            "test_00000000.constraints",
            "command.sh",
            "global_X_init.bytecode",
            "test_00000000.tx",
            "test_00000000.pkl",
            "manticore.yml",
            "global.summary",
            "test_00000000.summary",
            "test_00000000.tx.json",
            "test_00000000.logs",
            "test_00000000.trace",
        }
        self.assertEqual(files, expected_files)

        result_vt_path = os.path.join(self.mevm.workspace, "test_00000000.verbose_trace")
        expected_vt_path = os.path.join(THIS_DIR, "data/verbose_trace_plugin_out")
        with open(result_vt_path) as res_fp, open(expected_vt_path) as exp_fp:
            res = res_fp.readlines()
            exp = exp_fp.readlines()

        self.assertEqual(len(res), len(exp))
        self.assertEqual(len(res), 204)

        # Till line 184 the outputs shall be the same
        # Next there is a CODESIZE instruction that concretizes to different values each run
        # and as a result, the values in memory might differ.
        #
        # For some reason even setting `(set-option :random-seed 1)` in z3 doesn't help
        for i in range(184):
            self.assertEqual(res[i], exp[i], f"Difference on line {i}")

        till = 130  # number of chars that doesn't differ
        for i in range(184, 188):
            self.assertEqual(res[i][:till], exp[i][:till], f"Difference on line {i}")

        for i in range(188, 195):
            self.assertEqual(res[i], exp[i], f"Difference on line {i}")

        for i in range(195, 200):
            self.assertEqual(res[i][:till], exp[i][:till], f"Difference on line {i}")

        for i in range(200, len(res)):
            self.assertEqual(res[i], exp[i], f"Difference on line {i}")
Exemple #22
0
from manticore.ethereum import ABI, ManticoreEVM

################ Script #######################

m = ManticoreEVM()
m.verbosity(0)
# The contract account to analyze
contract_source_code = """
pragma solidity ^0.4.15;

contract Reentrance {
    mapping (address => uint) userBalance;
   
    function getBalance(address u) constant returns(uint){
        return userBalance[u];
    }

    function addToBalance() payable{
        userBalance[msg.sender] += msg.value;
    }   

    function withdrawBalance(){
        // send userBalance[msg.sender] ethers to msg.sender
        // if mgs.sender is a contract, it will call its fallback function
        if( ! (msg.sender.call.value(userBalance[msg.sender])() ) ){
           revert();
        }
        userBalance[msg.sender] = 0;
    }   
}
//Function signatures: 
from manticore.ethereum import ManticoreEVM

# initiate the blockchain
m = ManticoreEVM()
source_code = '''
pragma solidity^0.4.20;
contract Simple {
    function f(uint a) payable {
        if (a == 65) {
            throw;
        }
    }
}
'''

# Initiate the accounts
user_account = m.create_account(balance=1000)
contract_account = m.solidity_create_contract(source_code, owner=user_account, balance=0)

# Call f(a), with a symbolic value
contract_account.f(m.SValue, caller=user_account)

# Check if an execution ends with a REVERT or INVALID
for state in m.terminated_states:
    last_tx = state.platform.transactions[-1]
    if last_tx.result in ['REVERT', 'INVALID']:
        print "Error found in f() execution (see %s)"%m.workspace
        m.generate_testcase(state, 'BugFound')
Exemple #24
0
 def setUp(self):
     self.mevm = ManticoreEVM()
     self.mevm.verbosity(0)
     self.worksp = self.mevm.workspace
Exemple #25
0
from manticore.ethereum import ManticoreEVM, Detector

################ Script #######################

m = ManticoreEVM()
m.verbosity(3)
# And now make the contract account to analyze
# https://capturetheether.com/challenges/math/mapping/
source_code = '''
pragma solidity ^0.4.21;

contract MappingChallenge {
    bool public isComplete;
    uint256[] map;

    function set(uint256 key, uint256 value) public payable {
        // Expand dynamic array as needed
        if (map.length <= key) {
            map.length = key + 1;
        }

        map[key] = value;
    }
}
'''
print("Source code:\n", source_code)


class StopAtDepth(Detector):
    ''' This just abort explorations too deep '''
    def will_start_run_callback(self, *args):
from manticore.ethereum import ManticoreEVM
from manticore.core.smtlib import Operators, solver
from manticore.ethereum.abi import ABI

ETHER = 10**18

m = ManticoreEVM()  # initiate the blockchain

# Generate the accounts
user_account = m.create_account(balance=1000 * ETHER)
with open('exercise_2.sol') as f:
    contract = m.solidity_create_contract(f, owner=user_account)

#First add won't overflow uint256 representation
value_0 = m.make_symbolic_value()
contract.add(value_0, caller=user_account)
#Potential overflow
value_1 = m.make_symbolic_value()
contract.add(value_1, caller=user_account)
contract.sellerBalance(caller=user_account)

for state in m.ready_states:
    # Check if input0 > sellerBalance

    # last_return is the data returned
    sellerBalance_tx = state.platform.transactions[-1]
    # retrieve last_return and input0 in a similar format
    seller_balance = ABI.deserialize("uint", sellerBalance_tx.return_data)

    condition = Operators.UGT(value_0, seller_balance)
Exemple #27
0
from manticore.ethereum import ManticoreEVM, ABI
from manticore.core.smtlib import Operators, solver

m = ManticoreEVM() # initiate the blockchain
with open('overflow.sol') as f:
   source_code = f.read()

# Generate the accounts
user_account = m.create_account(balance=1000)
contract_account = m.solidity_create_contract(source_code, owner=user_account, balance=0)

# First add won't overflow uint256 representation
value_0 = m.make_symbolic_value()
contract_account.add(value_0)
# Potential overflow
value_1 = m.make_symbolic_value()
contract_account.add(value_1)
contract_account.sellerBalance()

for state in m.running_states:
    # Check if input0 > sellerBalance

    # last_return is the data returned
    last_return = state.platform.transactions[-1].return_data
    last_return = ABI.deserialize("uint", last_return)

    state.constrain(Operators.UGT(value_0, last_return))

    if state.is_feasible():
        print("Overflow found! see {}".format(m.workspace))
        m.generate_testcase(state, 'OverflowFound')
from manticore.ethereum import ManticoreEVM
from manticore.core.smtlib import solver

m = ManticoreEVM() # initiate the blockchain
source_code = '''
pragma solidity ^0.4.20;
contract UnprotectedWallet{
    address public owner;

    modifier onlyowner {
        require(msg.sender==owner);
        _;
    }

    function UnprotectedWallet() public {
        owner = msg.sender;
    }
    function changeOwner(address _newOwner) public {
       owner = _newOwner;
    }

    function deposit() payable public { }

    function withdraw() onlyowner public {
        msg.sender.transfer(this.balance);
    }
}
'''


# Generate the accounts. Creator has 10 ethers; attacker 0 
Exemple #29
0
from manticore.ethereum import ManticoreEVM, ABI
from manticore.core.smtlib import Operators, solver

###### Initialization ######

m = ManticoreEVM()
with open('my_token.sol') as f:
    source_code = f.read()

# Create one user account
# And deploy the contract
user_account = m.create_account(balance=1000)
contract_account = m.solidity_create_contract(source_code, owner=user_account, balance=0)

###### Exploration ######

# - Call balances[user]
# - Call transfer with symbolic values
# - Call balances[user]
# Later we will compare the result of the first call to balances to the second
contract_account.balances(user_account)

symbolic_val = m.make_symbolic_value()
symbolic_to = m.make_symbolic_value()
# Transfer is called with symbolic values
# Manticore will fork and create state at each condition executed
contract_account.transfer(symbolic_to, symbolic_val)

contract_account.balances(user_account)

# Check of properties ######
Exemple #30
0
 def setUp(self):
     self.mevm = ManticoreEVM()
     self.mevm.register_plugin(KeepOnlyIfStorageChanges())
     self.mevm.verbosity(0)
     self.worksp = self.mevm.workspace
from manticore.ethereum import ManticoreEVM

# initiate the blockchain
m = ManticoreEVM()
source_code = '''
pragma solidity^0.4.20;
contract Simple {
    function f(uint a) payable public {
        if (a == 65) {
            revert();
        }
    }
}
'''

# Initiate the accounts
user_account = m.create_account(balance=1000)
contract_account = m.solidity_create_contract(source_code, owner=user_account, balance=0)

# Call f(a), with a symbolic value
contract_account.f(m.SValue, user_account)

print "Results are in %s" % m.workspace
m.finalize() # stop the exploration
Exemple #32
0
from manticore.ethereum import ManticoreEVM

################ Script #######################

m = ManticoreEVM()
# And now make the contract account to analyze
source_code = """
contract C {
    uint n;
    function C(uint x) {
        n = x;
    }
    function f(uint x) payable returns (bool) {
        if (x == n) {
            return true;
        }
        else{
            return false;
        }
    }
}
"""

user_account = m.create_account(balance=1000)
print("[+] Creating a user account", user_account)

contract_account = m.solidity_create_contract(source_code, owner=user_account, args=[42])
print("[+] Creating a contract account", contract_account)
print("[+] Source code:")
print(source_code)
from manticore.ethereum import ManticoreEVM

m = ManticoreEVM()

with open('example.sol') as f:
    source_code = f.read()

user_account = m.create_account(balance=1000)
contract_account = m.solidity_create_contract(source_code,
                                              owner=user_account)

symbolic_var = m.make_symbolic_value()
contract_account.f(symbolic_var)

print("Results are in {}".format(m.workspace))
m.finalize() # stop the exploration
from manticore.ethereum import ManticoreEVM, evm
from binascii import unhexlify, hexlify
################ Script #######################
# Bytecode only based analisys
# No solidity, no compiler, no metadata

m = ManticoreEVM()
init_bytecode = unhexlify(
    b"608060405234801561001057600080fd5b506101cc806100206000396000f30060806040527f41000000000000000000000000000000000000000000000000000000000000006000366000818110151561003557fe5b905001357f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415610135577fcf34ef537ac33ee1ac626ca1587a0a7e8e51561e5514f8cb36afa1c5102b3bab6040518080602001828103825260088152602001807f476f7420616e204100000000000000000000000000000000000000000000000081525060200191505060405180910390a161019e565b7fcf34ef537ac33ee1ac626ca1587a0a7e8e51561e5514f8cb36afa1c5102b3bab6040518080602001828103825260128152602001807f476f7420736f6d657468696e6720656c7365000000000000000000000000000081525060200191505060405180910390a15b0000a165627a7a72305820fd5ec850d8409e19cfe593b9ee3276cc3ac12b0e3406d965317dc9c1aeb7f2670029"
)

user_account = m.create_account(balance=1000)
print("[+] Creating a user account", user_account)

print("[+] Init bytecode:", hexlify(init_bytecode))
print("[+] EVM init assembler:")
for instr in evm.EVMAsm.disassemble_all(init_bytecode[:-44]):
    print(hex(instr.pc), instr)

contract_account = m.create_contract(owner=user_account, init=init_bytecode)
print("[+] Creating a contract account", contract_account)

print("[+] Now the symbolic values")
symbolic_data = m.make_symbolic_buffer(320)
symbolic_value = m.make_symbolic_value()
m.transaction(caller=user_account,
              address=contract_account,
              data=symbolic_data,
              value=symbolic_value)

#Let seth know we are not sending more transactions
from manticore.ethereum import ManticoreEVM
################ Script #######################

m = ManticoreEVM()
m.verbosity(0)
#The contract account to analyze
contract_source_code = '''
pragma solidity ^0.4.15;

contract Reentrance {
    mapping (address => uint) userBalance;
   
    function getBalance(address u) constant returns(uint){
        return userBalance[u];
    }

    function addToBalance() payable{
        userBalance[msg.sender] += msg.value;
    }   

    function withdrawBalance(){
        // send userBalance[msg.sender] ethers to msg.sender
        // if mgs.sender is a contract, it will call its fallback function
        if( ! (msg.sender.call.value(userBalance[msg.sender])() ) ){
           revert();
        }
        userBalance[msg.sender] = 0;
    }   
}
'''
Exemple #36
0
si_level_address = int(sys.argv[2], 16) if len(sys.argv)>2 else "<SI ctf level address>"
sol_file = sys.argv[3] if len(sys.argv)>3 else "../SI_ctf_levels/Lottery.sol"
gas = 100000

# Set the amount of ETH you want to obtain from the contract
contract_balance = ???

# Set the amount of ETH we need to send in our transaction (msg.value) to play.
msg_value = ???

# Read in the contract source
with open(sol_file, "r") as f:
    contract_src = f.read()

# Instantiate manticore's Ethereum Virtual Machine
m = ManticoreEVM()
# m.verbosity(0)

# Create an account for your wallet address on the EVM with funds to
# both deploy the contract and to play the lottery
user_account = m.create_account(address=from_address, balance=contract_balance+msg_value)

# Create the Lottery CTF level contract on the EVM using wallet
contract_account = m.solidity_create_contract(
    contract_src,
    contract_name="Lottery",
    owner=user_account,
    balance=contract_balance,
    args=(0,0)
)
from manticore.ethereum import ManticoreEVM

m = ManticoreEVM()

with open('example.sol') as f:
    source_code = f.read()

user_account = m.create_account(balance=1000)
contract_account = m.solidity_create_contract(source_code,
                                              owner=user_account)

symbolic_var = m.make_symbolic_value()
contract_account.f(symbolic_var)

## Check if an execution ends with a REVERT or INVALID
for state in m.terminated_states:
    last_tx = state.platform.transactions[-1]
    if last_tx.result in ['REVERT', 'INVALID']:
        print('Throw found {}'.format(m.workspace))
        m.generate_testcase(state, 'ThrowFound')