# 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 m.finalize() print("[+] Look for results in %s" % m.workspace)
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"]
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 with open("winnerlog.bin", "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 symbolic buffer and call logWinner() with that symbolic buffer symbolic_data = m.make_symbolic_buffer(64) calldata = ABI.function_call('logWinner(address,uint256,bytes)',
source_code = f.read() bytecode = m.compile(source_code, # contract_name="GuessTheNumberChallenge" ) # Add hacker's address hacker_account = m.create_account(balance=1000 * 10**18, address=42) # bytecode = bytecode + bytes.fromhex("000000000000000000000000000000000000002a") # Create one user account # And deploy the contract user_account = m.create_account(balance=1000 * 10**18) contract_account = m.create_contract(init=bytecode, owner=user_account, balance=10**18) ###### Exploration ###### symbolic_data = m.make_symbolic_buffer(36) m.transaction(caller=hacker_account, address=contract_account, data=symbolic_data, value=10**18) # symbolic_data = m.make_symbolic_buffer(320) # m.transaction( # caller=hacker_account, # address=contract_account, # data=symbolic_data,
from manticore.ethereum import ManticoreEVM m = ManticoreEVM() m.verbosity(3) # And now make the contract account to analyze with open("coverage.sol") as f: source_code = f.read() user_account = m.create_account(balance=1000) bytecode = m.compile(source_code) # Initialize contract contract_account = m.create_contract(owner=user_account, balance=0, init=bytecode) m.transaction( caller=user_account, address=contract_account, value=m.make_symbolic_value(), data=m.make_symbolic_buffer(164), ) # Up to here we get only ~30% coverage. # We need 2 transactions to fully explore the contract m.transaction( caller=user_account, address=contract_account, value=m.make_symbolic_value(), data=m.make_symbolic_buffer(164), ) print(f"[+] There are {m.count_terminated_states()} reverted states now")