From d40df5b7b22f27831fb61b8ce83be1f34fef12ba Mon Sep 17 00:00:00 2001 From: Evan Sultanik Date: Thu, 24 Jan 2019 10:07:12 -0500 Subject: [PATCH 1/6] Updated BrokenMetaCoin contracts to `solc` v0.5.0 (#49) --- examples/BrokenMetaCoin/contracts/ConvertLib.sol | 2 +- examples/BrokenMetaCoin/contracts/MetaCoin.sol | 4 ++-- examples/BrokenMetaCoin/contracts/Migrations.sol | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/BrokenMetaCoin/contracts/ConvertLib.sol b/examples/BrokenMetaCoin/contracts/ConvertLib.sol index 9bbed83..5d83fa9 100644 --- a/examples/BrokenMetaCoin/contracts/ConvertLib.sol +++ b/examples/BrokenMetaCoin/contracts/ConvertLib.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.4; +pragma solidity ^0.5.0; library ConvertLib{ function convert(uint amount,uint conversionRate) public pure returns (uint convertedAmount) diff --git a/examples/BrokenMetaCoin/contracts/MetaCoin.sol b/examples/BrokenMetaCoin/contracts/MetaCoin.sol index a8a7816..25494f2 100644 --- a/examples/BrokenMetaCoin/contracts/MetaCoin.sol +++ b/examples/BrokenMetaCoin/contracts/MetaCoin.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.18; +pragma solidity ^0.5.0; import "./ConvertLib.sol"; @@ -26,7 +26,7 @@ contract MetaCoin { return metadata[key]; } - function backdoor() { + function backdoor() public { selfdestruct(msg.sender); } diff --git a/examples/BrokenMetaCoin/contracts/Migrations.sol b/examples/BrokenMetaCoin/contracts/Migrations.sol index b83fdd0..89b4d5c 100644 --- a/examples/BrokenMetaCoin/contracts/Migrations.sol +++ b/examples/BrokenMetaCoin/contracts/Migrations.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.2; +pragma solidity ^0.5.0; contract Migrations { address public owner; From 76341cbb6fea88ee0cb4647c3731c6ec27ea2cc9 Mon Sep 17 00:00:00 2001 From: Evan Sultanik Date: Thu, 24 Jan 2019 10:55:43 -0500 Subject: [PATCH 2/6] Added a warning when a client is not fully implemented (#49) --- etheno/etheno.py | 1 + 1 file changed, 1 insertion(+) diff --git a/etheno/etheno.py b/etheno/etheno.py index 4667a61..14a97eb 100644 --- a/etheno/etheno.py +++ b/etheno/etheno.py @@ -342,6 +342,7 @@ def post(self, data): kwargs['rpc_client_result'] = ret results.append(function(*args, **kwargs)) else: + self.logger.warn(f"Function {method} of {client} is None!") results.append(None) elif isinstance(client, SelfPostingClient): if method == 'eth_getTransactionReceipt': From 6ce1a5964a460a68c4828019179df845335a2dd3 Mon Sep 17 00:00:00 2001 From: Evan Sultanik Date: Thu, 24 Jan 2019 14:09:18 -0500 Subject: [PATCH 3/6] Bugfix: Escape logger names that contain directory separators --- etheno/logger.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/etheno/logger.py b/etheno/logger.py index 66ca848..6d842cd 100644 --- a/etheno/logger.py +++ b/etheno/logger.py @@ -140,7 +140,7 @@ def _add_child(self, child): raise ValueError("Cannot double-add child logger %s to logger %s" % (child.name, self.name)) self.children.append(child) if self.directory is not None: - child.save_to_directory(os.path.join(self.directory, child.name)) + child.save_to_directory(os.path.join(self.directory, child.name.replace(os.sep, '-'))) else: child._tmpdir = tempfile.TemporaryDirectory() child.save_to_directory(child._tmpdir.name) @@ -219,7 +219,7 @@ def save_to_directory(self, path): raise ValueError("Logger %s's save directory is already set to %s" % (self.name, path)) self._directory = os.path.realpath(path) os.makedirs(path, exist_ok=True) - self.save_to_file(os.path.join(path, "%s.log" % self.name), include_descendants=False, log_level=DEBUG) + self.save_to_file(os.path.join(path, "%s.log" % self.name.replace(os.sep, '-')), include_descendants=False, log_level=DEBUG) for child in self.children: child.save_to_directory(os.path.join(path, child.name)) From 8ca943ccf9c54e64117a6b6535e6a4df07e8cf3b Mon Sep 17 00:00:00 2001 From: Evan Sultanik Date: Thu, 24 Jan 2019 16:52:50 -0500 Subject: [PATCH 4/6] Do not segment Truffle arguments --- etheno/truffle.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etheno/truffle.py b/etheno/truffle.py index 7d76e77..298b999 100644 --- a/etheno/truffle.py +++ b/etheno/truffle.py @@ -19,7 +19,7 @@ def run_migrate(self): def run(self, args): self._running = True - if isinstance(args, Sequence): + if isinstance(args, Sequence) and not isinstance(args, str) and not isinstance(args, bytes): if not isinstance(args, list): args = list(args) else: From 03c347a59c3518844a8672647c58cd840765c96f Mon Sep 17 00:00:00 2001 From: Evan Sultanik Date: Fri, 25 Jan 2019 20:57:05 -0500 Subject: [PATCH 5/6] Truffle now requires the RPC id in the result to be the same one as was requested --- etheno/etheno.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/etheno/etheno.py b/etheno/etheno.py index 14a97eb..041d8f4 100644 --- a/etheno/etheno.py +++ b/etheno/etheno.py @@ -303,7 +303,6 @@ def post(self, data): plugin.before_post(data) method = data['method'] - args = () kwargs = {} if 'params' in data: @@ -316,12 +315,15 @@ def post(self, data): del kwargs['from'] else: args = data['params'] + if self.master_client is None: ret = None else: if method == 'eth_getTransactionReceipt': # for eth_getTransactionReceipt, make sure we block until all clients have mined the transaction ret = self.master_client.wait_for_transaction(data['params'][0]) + if 'id' in data and 'id' in ret: + ret['id'] = data['id'] else: try: ret = self.master_client.post(data) From 5dd8177384a982f372e4156ec6fc84b738748476 Mon Sep 17 00:00:00 2001 From: Evan Sultanik Date: Wed, 6 Feb 2019 11:08:09 -0500 Subject: [PATCH 6/6] Workaround for a Truffle build bug (#49) --- examples/BrokenMetaCoin/run_etheno.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/examples/BrokenMetaCoin/run_etheno.sh b/examples/BrokenMetaCoin/run_etheno.sh index 7504ada..b77bcb4 100755 --- a/examples/BrokenMetaCoin/run_etheno.sh +++ b/examples/BrokenMetaCoin/run_etheno.sh @@ -1,3 +1,10 @@ +# First, remove the Truffle build directory. +# This shouldn't be necessary, but Truffle will often fail with +# confusing error messages if it is upgraded between builds. +# So, we just rebuild everything from scratch each time to ensure +# that it always works. +rm -rf build + echo "Running the custom Manticore script ExploitMetaCoinManticoreScript.py" # Set the max depth for Manticore to 2 because this script only needs to # find a sequence of two transactions to exploit the bug