Analyzing Ethereum smart contracts for vulnerabilities

Bernhard Mueller
HackerNoon.com
5 min readNov 23, 2017

--

Bernhard Mueller, the creator of MythX, shows how to detect vulnerabilities in Ethereum smart contracts.

Below, we’ll be running Mythril on some intentionally vulnerable contracts from the Ethernaut wargame (thanks to the guys from Zeppelin solutions for giving me permission!). If you haven’t tried the wargame yourself, be aware that there are spoilers ahead! I recommend giving it a shot yourself first if you haven’t already.

Token

The objective in level three of Ethernaut is to hack a basic token contract called Token. Check out the code to see if you can spot the bug.

When analyzing the smart contracts with Mythril you can choose from three input options:

  1. Solidity code file: This only works if the solc command line compiler is installed.
  2. Solidity bytecode: If you don’t have solc, you can compile the code with Remix and pass the runtime binary code to Mythril via the -c argument.
  3. Contract address: To scan a contract instance on the blockchain, use the -a ADDRESS option.

I’ll be using option 1 below — for detailed instructions on the other input options check out the README.

Copy/paste the code into a text file and save it as ethernaut-token.sol, then run the myth analyzecommand. Mythril outputs detected issues on the console:

In this case Mythril detectsd one integer overflow and two integer underflow issues in the function transfer. Let’s have a look at the code to see what’s going on:

We can see that balances[msg.sender] — _value will indeed wrap if _value is larger than balances[msg.sender]. In that case the sender will end up with an astronomical amount of tokens!

Fallout

This is level two of the Ethernaut challenge. Have a look at the code first — the problem isn’t that hard to spot!

Here’s what Mythril has to say about it:

Mythril claims that it is possible withdraw ETH from the contract using the function collectAllocations(). But isn’t that function protected by the onlyOwner modifier? Note that two transactions are shown in the “transaction sequence” section. These is the sequence of function calls that trigger the vulnerability. The first transaction calls a function named Fal1out(), the second transaction calls collectAllocations().

With that in in mind, take another careful look at the source code. You might notice that the constructor name is slightly different from the contract name, and thus compiles into a regular public function that anyone can call to set a new owner! This is similar to the Rubixi vulnerability.

Delegation

Level 4 of Ethernaut is a multi-contract scenario. Fortunately, Mythril can process multiple contracts and understands various types of message calls between contracts. When you analyze a contract on the blockchain Mythril can automatically detect and download dependencies during runtime.

To try this out, I deployed the Delegate and Delegation contracts on a local Ganache instance. Linking is accomplished by passing the address of the Delegation instance to the constructor of Delegate.

On-chain analyses are launched using the -a ADDRESS argument. The command shown below also includes three additional flags:

  • --rpc ganache activates the Ganache RPC preset;
  • -l activates the dynamic loader. This tells Mythril to also retrieve and scan any additional referenced contracts;
  • -v4 activates informational debugging output. This will give us some insight into what the loader is doing.

Two issues have been identified here:

  • Unchecked CALL return value in the main (fallback) function. This seems weird, as we can clearly see that the delegatecall() in the fallback function is wrapped into an if-statement. However, if you check the disassembly, you’ll find that the compiler optimizes this out.
  • CALLDATA forwarded with delegatecall(): Mythril also warns about forwarding msg.data through DELEGATECALL and notes that arbitrary functions in the called contract can be executed.

Mythril seems to have missed the the fact that the _owner state variable can be overwritten by calling the pwn() function. Why is that? If you consider the overall logic of both contracts, you’ll note that even though changing the state variable named _owner might appear critical, it doesn’t have any further implications (i.e., it doesn’t allow you to do anything you couldn’t have done anyway), so Mythril doesn’t consider it a vulnerability.

About Mythril and MythX

Mythril is a free and open-source smart contract security analyzer. It uses symbolic execution to detect a variety of security vulnerabilities.

MythX is a cloud-based smart contract security service that seamlessly integrates into smart contract development environments and build pipelines. It bundles multiple bleeding-edge security analysis processes into an easy-to-use API that allows anyone to create purpose-built smart contract security tools. MythX is compatible with Ethereum, Tron, Vechain, Quorum, Roostock and other EVM-based platforms.

--

--

Bernhard Mueller
HackerNoon.com

Hackers (1995) fan • “Best Research” Pwnie Awardee • Retired degen • G≡¬Prov(num(G))