contract_account = m.solidity_create_contract(source_code, owner=user_account, balance=0) contract_account.balanceOf(to_account, caller=user_account) contract_account.balanceOf(from_account, caller=user_account) contract_account.balanceOf(user_account, caller=user_account) symbolic_val1 = m.make_symbolic_value() #m.constrain(symbolic_val1 > 100) contract_account.transfer(to_account, symbolic_val1, caller=from_account) contract_account.balanceOf(user_account, caller=user_account) contract_account.balanceOf(from_account, caller=user_account) contract_account.balanceOf(to_account, caller=user_account) for state in m.ready_states: #for tx in state.platform.transactions: # print("From address: (0x%x) \n" % (tx.caller)) #print("********\n") balance_before = state.platform.transactions[1].return_data balance_before = ABI.deserialize("uint", balance_before) balance_after = state.platform.transactions[-1].return_data balance_after = ABI.deserialize("uint", balance_after) state.constrain(Operators.ULT(balance_before, balance_after)) if solver.check(state.constraints): print("Found! see {}".format(m.workspace)) m.generate_testcase(state, "Found")
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) if m.generate_testcase(state, name="BugFound", only_if=condition): print(f'Bug found, results are in {m.workspace}')
print("[+] Creating a attacker account", hex(attacker_account.address)) market.ether_token_contract.deposit(value=attacker_balance, caller=attacker_account) market.ether_token_contract.approve(market.reserve_contract, attacker_balance, caller=attacker_account) market.market_token_contract.approve(market.voting_contract, attacker_balance, caller=attacker_account) #value = m.make_symbolic_value(name="attacker_to_buy") market.reserve_contract.support(100 * ONE_GWEI, caller=attacker_account) market.listing_contract.challenge(user_list_hash, caller=attacker_account) increase_timestamp(m, 32) market.listing_contract.resolveChallenge(user_list_hash, caller=attacker_account) market.voting_contract.getStake(user_list_hash, market.ether_token_owner) for state in m.ready_states: world = state.platform last_tx = world.human_transactions[-1] stake = ABI.deserialize("uint", last_tx.return_data) print("stake:", stake) m.generate_testcase(state, name="BugFound", only_if=stake != 2) print(f"[+] Look for results in {m.workspace}")
def manticore_verifier( source_code, contract_name, maxfail=None, maxt=3, maxcov=100, deployer=None, senders=None, psender=None, propre=r"crytic_.*", compile_args=None, outputspace_url=None, timeout=100, ): """ Verify solidity properties The results are dumped to stdout and to the workspace folder. $manticore-verifier property.sol --contract TestToken --smt.solver yices --maxt 4 # Owner account: 0xf3c67ffb8ab4cdd4d3243ad247d0641cd24af939 # Contract account: 0x6f4b51ac2eb017600e9263085cfa06f831132c72 # Sender_0 account: 0x97528a0c7c6592772231fd581e5b42125c1a2ff4 # PSender account: 0x97528a0c7c6592772231fd581e5b42125c1a2ff4 # Found 2 properties: crytic_test_must_revert, crytic_test_balance # Exploration will stop when some of the following happens: # * 4 human transaction sent # * Code coverage is greater than 100% meassured on target contract # * No more coverage was gained in the last transaction # * At least 2 different properties where found to be breakable. (1 for fail fast) # * 240 seconds pass # Starting exploration... Transactions done: 0. States: 1, RT Coverage: 0.0%, Failing properties: 0/2 Transactions done: 1. States: 2, RT Coverage: 55.43%, Failing properties: 0/2 Transactions done: 2. States: 8, RT Coverage: 80.48%, Failing properties: 1/2 Transactions done: 3. States: 30, RT Coverage: 80.48%, Failing properties: 1/2 No coverage progress. Stopping exploration. Coverage obtained 80.48%. (RT + prop) +-------------------------+------------+ | Property Named | Status | +-------------------------+------------+ | crytic_test_balance | failed (0) | | crytic_test_must_revert | passed | +-------------------------+------------+ Checkout testcases here:./mcore_6jdil7nh :param maxfail: stop after maxfail properties are failing. All if None :param maxcov: Stop after maxcov % coverage is obtained in the main contract :param maxt: Max transaction count to explore :param deployer: (optional) address of account used to deploy the contract :param senders: (optional) a list of calles addresses for the exploration :param psender: (optional) address from where the property is tested :param source_code: A filename or source code :param contract_name: The target contract name defined in the source code :param propre: A regular expression for selecting properties :param outputspace_url: where to put the extended result :param timeout: timeout in seconds :return: """ # Termination condition # Exploration will stop when some of the following happens: # * MAXTX human transaction sent # * Code coverage is greater than MAXCOV meassured on target contract # * No more coverage was gained in the last transaction # * At least MAXFAIL different properties where found to be breakable. (1 for fail fast) # Max transaction count to explore MAXTX = maxt # Max coverage % to get MAXCOV = maxcov # Max different properties fails MAXFAIL = maxfail config.get_group("smt").timeout = 120 config.get_group("smt").memory = 16384 config.get_group("evm").ignore_balance = True config.get_group("evm").oog = "ignore" print("# Welcome to manticore-verifier") # Main manticore manager object m = ManticoreEVM() # avoid all human level tx that are marked as constant (have no effect on the storage) filter_out_human_constants = FilterFunctions(regexp=r".*", depth="human", mutability="constant", include=False) m.register_plugin(filter_out_human_constants) filter_out_human_constants.disable() # Avoid automatically exploring property filter_no_crytic = FilterFunctions(regexp=propre, include=False) m.register_plugin(filter_no_crytic) filter_no_crytic.disable() # Only explore properties (at human level) filter_only_crytic = FilterFunctions(regexp=propre, depth="human", fallback=False, include=True) m.register_plugin(filter_only_crytic) filter_only_crytic.disable() # And now make the contract account to analyze # User accounts. Transactions trying to break the property are send from one # of this senders = (None, ) if senders is None else senders user_accounts = [] for n, address_i in enumerate(senders): user_accounts.append( m.create_account(balance=10**10, address=address_i, name=f"sender_{n}")) # the address used for deployment owner_account = m.create_account(balance=10**10, address=deployer, name="deployer") # the target contract account contract_account = m.solidity_create_contract( source_code, owner=owner_account, contract_name=contract_name, compile_args=compile_args, name="contract_account", ) # the address used for checking porperties checker_account = m.create_account(balance=10**10, address=psender, name="psender") print(f"# Owner account: 0x{int(owner_account):x}") print(f"# Contract account: 0x{int(contract_account):x}") for n, user_account in enumerate(user_accounts): print(f"# Sender_{n} account: 0x{int(user_account):x}") print(f"# PSender account: 0x{int(checker_account):x}") properties = {} md = m.get_metadata(contract_account) for func_hsh in md.function_selectors: func_name = md.get_abi(func_hsh)["name"] if re.match(propre, func_name): properties[func_name] = [] print( f"# Found {len(properties)} properties: {', '.join(properties.keys())}" ) if not properties: print("I am sorry I had to run the init bytecode for this.\n" "Good Bye.") return MAXFAIL = len(properties) if MAXFAIL is None else MAXFAIL tx_num = 0 # transactions count current_coverage = None # obtained coverge % new_coverage = 0.0 print(f"""# Exploration will stop when some of the following happens: # * {MAXTX} human transaction sent # * Code coverage is greater than {MAXCOV}% meassured on target contract # * No more coverage was gained in the last transaction # * At least {MAXFAIL} different properties where found to be breakable. (1 for fail fast) # * {timeout} seconds pass""") print("# Starting exploration...") print( f"Transactions done: {tx_num}. States: {m.count_ready_states()}, RT Coverage: {0.00}%, " f"Failing properties: 0/{len(properties)}") with m.kill_timeout(timeout=timeout): while not m.is_killed(): # check if we found a way to break more than MAXFAIL properties broken_properties = sum( int(len(x) != 0) for x in properties.values()) if broken_properties >= MAXFAIL: print( f"Found {broken_properties}/{len(properties)} failing properties. Stopping exploration." ) break # check if we sent more than MAXTX transaction if tx_num >= MAXTX: print(f"Max number of transactions reached ({tx_num})") break tx_num += 1 # check if we got enough coverage new_coverage = m.global_coverage(contract_account) if new_coverage >= MAXCOV: print( f"Current coverage({new_coverage}%) is greater than max allowed ({MAXCOV}%). Stopping exploration." ) break # check if we have made coverage progress in the last transaction if current_coverage == new_coverage: print(f"No coverage progress. Stopping exploration.") break current_coverage = new_coverage # Make sure we didn't time out before starting first transaction if m.is_killed(): print("Cancelled or timeout.") break # Explore all methods but the "crytic_" properties # Note: you may be tempted to get all valid function ids/hashes from the # metadata and to constrain the first 4 bytes of the calldata here. # This wont work because we also want to prevent the contract to call # crytic added methods as internal transactions filter_no_crytic.enable() # filter out crytic_porperties filter_out_human_constants.enable() # Exclude constant methods filter_only_crytic.disable( ) # Exclude all methods that are not property checks symbolic_data = m.make_symbolic_buffer(320) symbolic_value = m.make_symbolic_value() caller_account = m.make_symbolic_value(160) args = tuple( (caller_account == address_i for address_i in user_accounts)) m.constrain(OR(*args, False)) m.transaction( caller=caller_account, address=contract_account, value=symbolic_value, data=symbolic_data, ) # check if timeout was requested during the previous transaction if m.is_killed(): print("Cancelled or timeout.") break m.clear_terminated_states() # no interest in reverted states m.take_snapshot() # make a copy of all ready states print( f"Transactions done: {tx_num}. States: {m.count_ready_states()}, " f"RT Coverage: {m.global_coverage(contract_account):3.2f}%, " f"Failing properties: {broken_properties}/{len(properties)}") # check if timeout was requested while we were taking the snapshot if m.is_killed(): print("Cancelled or timeout.") break # And now explore all properties (and only the properties) filter_no_crytic.disable() # Allow crytic_porperties filter_out_human_constants.disable( ) # Allow them to be marked as constants filter_only_crytic.enable( ) # Exclude all methods that are not property checks symbolic_data = m.make_symbolic_buffer(4) m.transaction(caller=checker_account, address=contract_account, value=0, data=symbolic_data) for state in m.all_states: world = state.platform tx = world.human_transactions[-1] md = m.get_metadata(tx.address) """ A is _broken_ if: * is normal property * RETURN False OR: * property name ends with 'revert' * does not REVERT Property is considered to _pass_ otherwise """ N = constrain_to_known_func_ids(state) for func_id in map(bytes, state.solve_n(tx.data[:4], nsolves=N)): func_name = md.get_abi(func_id)["name"] if not func_name.endswith("revert"): # Property does not ends in "revert" # It must RETURN a 1 if tx.return_value == 1: # TODO: test when property STOPs return_data = ABI.deserialize( "bool", tx.return_data) testcase = m.generate_testcase( state, f"property {md.get_func_name(func_id)} is broken", only_if=AND(tx.data[:4] == func_id, return_data == 0), ) if testcase: properties[func_name].append(testcase.num) else: # property name ends in "revert" so it MUST revert if tx.result != "REVERT": testcase = m.generate_testcase( state, f"Some property is broken did not reverted.(MUST REVERTED)", only_if=tx.data[:4] == func_id, ) if testcase: properties[func_name].append(testcase.num) m.clear_terminated_states( ) # no interest in reverted states for now! m.goto_snapshot() else: print("Cancelled or timeout.") m.clear_terminated_states() m.clear_ready_states() m.clear_snapshot() if m.is_killed(): print("Exploration ended by CTRL+C or timeout") print(f"Coverage obtained {new_coverage:3.2f}%. (RT + prop)") x = PrettyTable() x.field_names = ["Property Named", "Status"] for name, testcases in sorted(properties.items()): result = "passed" if testcases: result = f"failed ({testcases[0]})" x.add_row((name, result)) print(x) m.clear_ready_states() workspace = os.path.abspath(m.workspace)[len(os.getcwd()) + 1:] print(f"Checkout testcases here:./{workspace}")
print(f'[+] Created contract ', OCEANTOKEN_JSON_PATH[len(ROOT_DIR):]) symbolic_address_1 = m.make_symbolic_value() symbolic_address_2 = m.make_symbolic_value() print(f'[+] Initialized contract ', OCEANTOKEN_JSON_PATH[len(ROOT_DIR):], 'with symbolic parameters') contract_account.initialize(symbolic_address_1, symbolic_address_2, caller=owner_account, value=0, signature='(address,address)') # At this point, it should not revert, unless one of these addresses is 0x0. running_states = list(m.running_states) if not (len(running_states) == 1): raise AssertionError() if m.generate_testcase(running_states[0], '', only_if=(symbolic_address_1 == 0)): raise AssertionError() if m.generate_testcase(running_states[0], '', only_if=(symbolic_address_2 == 0)): raise AssertionError() #print("[+] First symbolic transaction") #symbolic_data = m.make_symbolic_buffer(320) #symbolic_address = m.make_symbolic_value(name="ADDRESS1") #symbolic_caller = m.make_symbolic_value(name="CALLER1") #m.transaction(caller=symbolic_caller, # address=symbolic_address, # data=symbolic_data, # value=0 ) #print("[+] Second symbolic transaction")
from manticore.ethereum import ManticoreEVM, ABI from manticore.core.smtlib import Operators, solver ###### Initialization ###### m = ManticoreEVM() with open('TS1_true.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) contract_account.totalSupply() for state in m.all_states: m.generate_testcase(state, 'TS1')
def __run_manticore(self, trace): self.print('[.] Running Manticore') consts = manticoreConfig.get_group('core') consts.procs = self.procs output_path = self.__create_output_path() manticore = ManticoreEVM(workspace_url=output_path) if self.force_loop_limit: loop_delimiter = LoopDepthLimiter( loop_count_threshold=self.loop_limit) manticore.register_plugin(loop_delimiter) if self.avoid_constant_txs: filter_nohuman_constants = FilterFunctions(regexp=r'.*', depth='human', mutability='constant', include=False) manticore.register_plugin(filter_nohuman_constants) self.print('[...] Creating user accounts') for num in range(0, self.amount_user_accounts): account_name = 'user_account_' + str(num) manticore.create_account(balance=self.user_initial_balance, name=account_name) self.print('[...] Creating a contract and its library dependencies') with open(self.contract_path, 'r') as contract_file: source_code = contract_file.read() try: contract_account = manticore.solidity_create_contract( source_code, owner=manticore.get_account('user_account_0'), args=self.contract_args, contract_name=self.contract_name) except: raise Exception('Check contract arguments') if contract_account is None: raise Exception( 'Contract account is None, check contract arguments') self.print('[...] Calling functions in trace') function_types = {} function_signatures = manticore.get_metadata( contract_account).function_signatures for signature in function_signatures: signature_parts = signature.split('(') name = str(signature_parts[0]) types = str(signature_parts[1].replace(')', '')) function_types[name] = types for function_name in trace: if function_name == '': # FIXME, check VeriSol trace manticore.transaction(caller=manticore.make_symbolic_address(), address=contract_account, value=manticore.make_symbolic_value(), data=manticore.make_symbolic_buffer( self.fallback_data_size)) else: function_to_call = getattr(contract_account, function_name) types = function_types[function_name] if len(types) > 0: function_to_call( manticore.make_symbolic_arguments( function_types[function_name])) else: function_to_call() self.print('[...] Processing output') throw_states = [] for state in manticore.terminated_states: if str(state.context['last_exception']) == 'THROW': throw_states.append(state) if len(throw_states) == 0: raise Exception('Manticore couldn\'t confirm the counterexample') if self.verbose: for state in throw_states: manticore.generate_testcase(state) self.print('[-] Look for full output in:', manticore.workspace)
attacker_account = m.create_account(balance=10*10**18) contract_account = m.solidity_create_contract(source_code, owner=creator_account) # Deposit 1 ether, from the creator contract_account.deposit(caller=creator_account, value=10**18) # Two raw transactions from the attacker symbolic_data = m.make_symbolic_buffer(320) m.transaction(caller=attacker_account, address=contract_account, data=symbolic_data, value=0) symbolic_data = m.make_symbolic_buffer(320) m.transaction(caller=attacker_account, address=contract_account, data=symbolic_data, value=0) for state in m.running_states: # Check if the attacker can ends with some ether balance = state.platform.get_balance(attacker_account.address) state.constrain(balance > 10 * 10 ** 18) if state.is_feasible(): print("Attacker can steal the ether! see {}".format(m.workspace)) m.generate_testcase(state, 'WalletHack') print(f'Bug found, results are in {m.workspace}')
contract_account.transfer(symbolic_to, symbolic_val) contract_account.balances(user_account) # Check of properties ###### bug_found = False # Explore all the forks for state in m.running_states: # state.plateform.transactions returns the list of transactions # state.plateform.transactions[0] is the contract creation # state.plateform.transactions[1] is the first transaction # state.plateform.transactions[-1] is the last transaction balance_before = state.platform.transactions[1].return_data balance_before = ABI.deserialize("uint", balance_before) balance_after = state.platform.transactions[-1].return_data balance_after = ABI.deserialize("uint", balance_after) # Check if it is possible to have balance_after > balance_before state.constrain(Operators.UGT(balance_after, balance_before)) if state.is_feasible(): print("Bug found! see {}".format(m.workspace)) m.generate_testcase(state, 'Bug') bug_found = True if not bug_found: print('No bug were found')
consts.oog = "ignore" # This script checks that MarketToken.setPrivileged can # be called with a zero address, which would brick the # contract. Running this scripts generates sequences of # EVM class that lead to these test cases. m = ManticoreEVM() market_parameters = DEFAULT_PARAMETERS market = initialize(m, parameters=market_parameters, only_create=True) arg_1 = m.make_symbolic_value(name="mt_arg_1") arg_2 = m.make_symbolic_value(name="mt_arg_2") # reserve: address, listing: address market.market_token_contract.setPrivileged(arg_1, arg_2, caller=market.market_token_owner) for state in m.ready_states: m.generate_testcase(state, name="BugFound", only_if=BoolAnd(arg_1 == 0, BoolNot(arg_2 == 0))) m.generate_testcase(state, name="BugFound", only_if=BoolAnd(BoolNot(arg_1 == 0), arg_2 == 0)) print(f"[+] Look for results in {m.workspace}")
balance=0, args=None) #contract_account.balanceOf(spender_account, caller=user_account) contract_account.balanceOf(user_account, caller=user_account) contract_account.allowance(user_account, spender_account) symbolic_approve = m.make_symbolic_value() contract_account.approve(spender_account, symbolic_approve, caller=user_account) #for state in m.ready_states: # val = state.platform.transactions[-1].return_data # val = ABI.deserialize("uint", val) symbolic_val = m.make_symbolic_value() #m.constrain(symbolic_val > val) contract_account.transferFrom(user_account, symbolic_to, symbolic_val, caller=spender_account) contract_account.balanceOf(symbolic_to, caller=user_account) contract_account.balanceOf(user_account, caller=user_account) contract_account.allowance(user_account, spender_account) for state in m.all_states: print("TF1! see {}".format(m.workspace)) m.generate_testcase(state, name="TF1")
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')
symbolic_addr = m.make_symbolic_value() contract_account.balanceOf(symbolic_addr) # check balance after transfer symbolic_val = m.make_symbolic_value() symbolic_to = m.make_symbolic_value() contract_account.transfer(symbolic_to, symbolic_val) contract_account.balanceOf(symbolic_to) contract_account.balanceOf(user_account) print("TEST01_1! see {}".format(m.workspace)) for state in m.all_states: balance_before = state.platform.transactions[1].return_data balance_before = ABI.deserialize("uint", balance_before) balance_after = state.platform.transactions[-1].return_data balance_after = ABI.deserialize("uint", balance_after) m.generate_testcase(state, name="TEST01_1") state.constrain(Operators.UGT(balance_after, balance_before)) if solver.check(state.constraints): m.generate_testcase(state, name="BugFound") # else: # m.generate_testcase(state, name="TEST01")
from manticore.ethereum import ManticoreEVM, ABI from manticore.core.smtlib import Operators, solver m = ManticoreEVM() with open('maxfunction.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, balance=0) symbolic_x = m.make_symbolic_value() symbolic_y = m.make_symbolic_value() symbolic_z = m.make_symbolic_value() #m.constrain(symbolic_x > symbolic_y) #contract_account.maxOf(symbolic_x, symbolic_y, symbolic_z) contract_account.maxOfList(symbolic_x, symbolic_y, symbolic_z) print("maxfunction.py! see {}".format(m.workspace)) for state in m.all_states: m.generate_testcase(state, 'MaxFunction')
print "Creator account: 0x%x (%d)"%(creator_account, creator_account) print "Attacker account: 0x%x (%d)"%(attacker_account, attacker_account) # Deposit 1 ether, from the creator contract_account.deposit(caller=creator_account, value=10**18) # Two raw transactions from the attacker symbolic_data = m.make_symbolic_buffer(320) m.transaction(caller=attacker_account, address=contract_account, data=symbolic_data, value=0) symbolic_data = m.make_symbolic_buffer(320) m.transaction(caller=attacker_account, address=contract_account, data=symbolic_data, value=0) for state in m.running_states: # Check if the attacker can ends with some ether balance = state.platform.get_balance(attacker_account) state.constrain(balance > 1) if solver.check(state.constraints): print "Attacker can steal the ether! see %s"%m.workspace m.generate_testcase(state, 'WalletHack')
from manticore.ethereum import ManticoreEVM, ABI from manticore.core.smtlib import Operators from manticore.core.smtlib.solver import Z3Solver ###### Initialization ###### m = ManticoreEVM() solver = Z3Solver.instance() with open('test08.sol') as f: source_code = f.read() # Create one user account # And deploy the contract user_account1 = m.create_account(balance=100) user_account2 = m.create_account(balance=101) contract_account = m.solidity_create_contract(source_code, owner=user_account1, balance=0) contract_account.balanceOf(user_account1) contract_account.balanceOf(user_account2) for state in m.all_states: print("TEST01! see {}".format(m.workspace)) m.generate_testcase(state, name="TEST01")
market.datatrust_contract.listingAccessed(listing_hash, delivery_hash, delivery_amount, caller=backend_user) print("[+] listingAccessed called") market.listing_contract.claimBytesAccessed(listing_hash, caller=listing) print("[+] claimBytesAccessed called") delivery_url = bytes.fromhex("0001") market.datatrust_contract.delivered(delivery_hash, delivery_url, caller=backend_user) print("[+] delivered called") market.ether_token_contract.balanceOf(market.datatrust_contract.address) for state in m.ready_states: world = state.platform balance_of_tx = world.human_transactions[-1] last_return = ABI.deserialize("uint", balance_of_tx.return_data) m.generate_testcase(state, name="BugFound", only_if=last_return >= 1) print(f"[+] Look for results in {m.workspace}")
m.create_account(balance=1000) m.create_account(balance=1000) from_account = m.make_symbolic_value() to_account = m.make_symbolic_value() m.constrain(from_account != to_account) contract_account = m.solidity_create_contract(source_code, owner=user_account, balance=0) contract_account.balanceOf(to_account) contract_account.balanceOf(from_account) symbolic_val1 = m.make_symbolic_value() contract_account.transfer(to_account, symbolic_val1, caller=from_account) contract_account.balanceOf(from_account) contract_account.balanceOf(to_account) for state in m.ready_states: balance_before = state.platform.transactions[1].return_data balance_before = ABI.deserialize("uint", balance_before) balance_after = state.platform.transactions[-1].return_data balance_after = ABI.deserialize("uint", balance_after) state.constrain(Operators.ULT(balance_before, balance_after)) if solver.check(state.constraints): print("Overflow found! see {}".format(m.workspace)) m.generate_testcase(state, "OverflowFound")
contract_account.balances(symbolic_to) # 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) contract_account.balances(symbolic_to) # Check of properties ###### #bug_found = False # Explore all the forks for state in m.ready_states: print("my_token.py! see {}".format(m.workspace)) m.generate_testcase(state, 'MyToken') """ # state.plateform.transactions returns the list of transactions # state.plateform.transactions[0] is the contract creation # state.plateform.transactions[1] is the first transaction # state.plateform.transactions[-1] is the last transaction balance_before = state.platform.transactions[1].return_data balance_before = ABI.deserialize("uint", balance_before) balance_after = state.platform.transactions[-1].return_data balance_after = ABI.deserialize("uint", balance_after) # Check if it is possible to have balance_after > balance_before state.constrain(Operators.UGT(balance_after, balance_before))
m.register_plugin(skipRequire) TestBpool = m.solidity_create_contract('./manticore/contracts/TBPoolJoinExitNoFee.sol', contract_name='TBPoolJoinExitNoFee', owner=user) print(f'TestJoinExit deployed {hex(TestBpool.address)}') # Call joinAndExitNoFeePool with symbolic values poolAmountOut = m.make_symbolic_value() poolAmountIn = m.make_symbolic_value() poolTotal = m.make_symbolic_value() _records_t_balance = m.make_symbolic_value() TestBpool.joinAndExitNoFeePool(poolAmountOut, poolAmountIn, poolTotal, _records_t_balance) print(f'joinAndExitNoFeePool Called') for state in m.ready_states: m.generate_testcase(state, name="BugFound") # Look over the 10**i, and try to generate more free tokens for i in range(0, 18): print(i) add_value = 10**i condition = Operators.AND(poolAmountOut > poolAmountIn + add_value, poolAmountIn + add_value > poolAmountIn) m.generate_testcase(state, name=f"BugFound{add_value}", only_if=condition) print(f'Results are in {m.workspace}')
from manticore.ethereum import ManticoreEVM, ABI from manticore.core.smtlib import Operators, solver ###### Initialization ###### m = ManticoreEVM() with open('test03.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) contract_account.totalSupply() for state in m.all_states: m.generate_testcase(state, 'TEST03')
from manticore.ethereum import ManticoreEVM m = ManticoreEVM() with open('example.sol') as f: source_code = f.read() user_account = m.create_account(balance=1 * 10**18) contract = m.solidity_create_contract(source_code, owner=user_account) symbolic_var = m.make_symbolic_value() contract.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')
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')
# 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 ###### bug_found = False # Explore all the forks for state in m.running_states: # state.plateform.transactions returns the list of transactions # state.plateform.transactions[0] is the first transaction # state.plateform.transactions[-1] is the last transaction balance_before = state.platform.transactions[0].return_data balance_before = ABI.deserialize("uint", balance_before) balance_after = state.platform.transactions[-1].return_data balance_after = ABI.deserialize("uint", balance_after) # Check if it is possible to have balance_after > balance_before state.constrain(Operators.UGT(balance_after, balance_before)) if state.is_feasible(): print("Bug found! see {}".format(m.workspace)) m.generate_testcase(state, 'Bug') bug_found = True if not bug_found: print('No bug were found')
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')
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, caller=user_account) #Potential overflow value_1 = m.make_symbolic_value() contract_account.add(value_1, caller=user_account) contract_account.sellerBalance(caller=user_account) for state in m.running_states: # Check if input0 > sellerBalance # last_return is the data returned last_return = state.platform.transactions[-1].return_data # retrieve last_return and input0 in a similar format last_return = Operators.CONCAT(256, *last_return) state.constrain(Operators.UGT(value_0, last_return)) if solver.check(state.constraints): print("Overflow found! see {}".format(m.workspace)) m.generate_testcase(state, 'OverflowFound')
with open('AP2.sol') as f: source_code = f.read() user_account = m.create_account(balance=1000) spender_account = m.make_symbolic_value() m.constrain(spender_account != user_account) contract_account = m.solidity_create_contract(source_code, owner=user_account, balance=0, args=None) #contract_account.balanceOf(spender_account, caller=user_account) contract_account.balanceOf(user_account, caller=user_account) for state in m.ready_states: val = state.platform.transactions[-1].return_data val = ABI.deserialize("uint", val) symbolic_val = m.make_symbolic_value() m.constrain(symbolic_val > val) contract_account.allowance(user_account, spender_account) contract_account.approve(spender_account, symbolic_val, caller=user_account) contract_account.allowance(user_account, spender_account) for state in m.all_states: print("AP2! see {}".format(m.workspace)) m.generate_testcase(state, name="AP2")
item = ( world.current_transaction.sort == "CREATE", world.current_transaction.address, pc, ) if not item in reps: reps[item] = 0 reps[item] += 1 if reps[item] > 2: state.abandon() m.register_plugin(StopAtDepth()) owner_account = m.create_account(balance=1000) user_account = m.create_account(balance=1000) target_account = m.create_account(balance=1000) contract_account = m.solidity_create_contract(source_code, owner=user_account) contract_account.set(m.make_symbolic_value(name="A"), 1) contract_account.set(m.make_symbolic_value(name="B"), 1) for st in m.all_states: flag_storage_slot = 0 flag_value = st.platform.get_storage_data(contract_account.address, flag_storage_slot) if st.can_be_true(flag_value != 0): print("Flag Found! Check ", m.workspace) st.constraints.add(flag_value != 0) m.generate_testcase(st, "Flag Found")
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')
def will_decode_instruction_callback(self, state, pc): world = state.platform with self.manticore.locked_context('seen_rep', dict) as reps: item = (world.current_transaction.sort == 'CREATE', world.current_transaction.address, pc) if not item in reps: reps[item] = 0 reps[item] += 1 if reps[item] > 2: state.abandon() m.register_plugin(StopAtDepth()) owner_account = m.create_account(balance=1000) user_account = m.create_account(balance=1000) target_account = m.create_account(balance=1000) contract_account = m.solidity_create_contract(source_code, owner=user_account) contract_account.set(m.make_symbolic_value(name="A"), 1) contract_account.set(m.make_symbolic_value(name="B"), 1) for st in m.all_states: flag_storage_slot = 0 flag_value = st.platform.get_storage_data(contract_account.address, flag_storage_slot) if st.can_be_true(flag_value != 0): print("Flag Found! Check ", m.workspace) st.constraints.add(flag_value != 0) m.generate_testcase(st, 'Flag Found', '')
# contract.setOwner(addr, caller=owner, value=0) # contract.owner() symbolic_value = m.make_symbolic_value() symbolic_data = m.make_symbolic_buffer(320) m.transaction( caller=attacker, address=contract.address, data=symbolic_data, value=symbolic_value ) contract.owner() bug_found = False for state in m.all_states: tx = state.platform.transactions[-1] if tx.result in ["REVERT", "INVALID"]: continue new_owner = ABI.deserialize("address", tx.return_data) print(owner, new_owner) condition = new_owner != owner if m.generate_testcase(state, name="Pwn", only_if=condition): print(new_owner, owner) print(f'Pwn! see {m.workspace}') bug_found = True if not bug_found: print("No bug found")