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')
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}')
# 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')
# symbolic_data = m.make_symbolic_buffer(320) # m.transaction( # caller=hacker_account, # address=contract_account, # data=symbolic_data, # value=0) # b2fa1c9e = isComplete() m.transaction(caller=hacker_account, address=contract_account, data=bytes.fromhex("b2fa1c9e"), value=0) bug_found = False # Explore all the forks for state in m.running_states: complete = state.platform.transactions[-1].return_data complete = ABI.deserialize("uint256", complete) print(complete) # Set constraint state.constrain(Operators.UGT(complete, 0)) 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')
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) symbolic_spender = m.make_symbolic_value(name="SPENDER") symbolic_val1 = 25 #m.make_symbolic_value() contract_account.balanceOf(user_account) contract_account.allowance(user_account, symbolic_spender) contract_account.approve(symbolic_spender, symbolic_val1, caller=user_account) symbolic_val2 = m.make_symbolic_value() symbolic_to = m.make_symbolic_value(name="TO") contract_account.transferFrom(user_account, symbolic_to, symbolic_val2, caller=symbolic_spender) contract_account.balanceOf(symbolic_to) contract_account.balanceOf(user_account) contract_account.allowance(user_account, symbolic_spender) print("TEST13! see {}".format(m.workspace)) for state in m.all_states: state.constrain(Operators.UGT(symbolic_val1, symbolic_val2)) if solver.check(state.constraints): m.generate_testcase(state, name="TEST13")
# Transfer is called with symbolic values # Manticore will fork and create state at each condition executed contract.transfer(symbolic_to, symbolic_val) contract.balances(user_account) # Check of properties ###### bug_found = False # Explore all the forks for state in m.ready_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 condition = Operators.UGT(balance_after, balance_before) if m.generate_testcase(state, name="BugFound", only_if=condition): print("Bug found! see {}".format(m.workspace)) bug_found = True if not bug_found: print('No bug were found')
''' # 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 contract_account.add(m.SValue, caller=user_account) #Potential overflow contract_account.add(m.SValue, 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.last_return_data # First input (first call to add) input0 = state.input_symbols[0] # retrieve last_return and input0 in a similar format last_return = Operators.CONCAT(256, *last_return) # starts at 4 to skip function id input0 = Operators.CONCAT(256, *input0[4:36]) state.constrain(Operators.UGT(input0, last_return)) if solver.check(state.constraints): print "Overflow found! see %s"%m.workspace m.generate_testcase(state, 'OverflowFound')