Skip to content
This repository has been archived by the owner on Jul 20, 2023. It is now read-only.

Consensys/smashing-smart-contracts-workshop

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

63 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Smashing Smart Contracts: Automated Vulnerability Detection and Exploitation

In this workshop we'll practice hacking & exploitation of Solidity/EVM smart contracts. During the workshop we'll solve challenges from CaptureTheEther and OpenZeppelin Ethernaut usign Mythril and Scrooge McEtherface and do a little frontrunning exercise. The flattened source code for all challenges is available in the code directory.

Check out the DEF CON 27 writeup for some background.

Preparation

Here's how to get set up for the workshop. It should be super easy except if you're using Windows (you need Node.js and a Python 3 environment).

If you run into insurmountable problems ask the instructors for help. There's also a dedicated Discord channel that we created exclusively for you, the valued workshop participant.

Installing Ganache

Ganache is a local Ethereum development server. Install it with npm:

$ npm i -g ganache-cli

Installing Mythril (Vulnerability Detection)

Install Mythril from Pypi:

$ pip3 install mythril

Make sure you have Mythril v0.21.15 or higher installed.

$ myth version
Mythril version v0.21.15

If you can't get this to work you can use the Docker image instead (see docs, note however that the below tools won't work then.

Mythril uses solc to compile Solidity files, so you'll need to install that as well.

Installing Scrooge McEtherface (Exploit Automation)

To install Scrooge, clone the Github repo to install the required packages into a Python 3 environment:

$ git clone https://github.com/b-mueller/scrooge-mcetherface
$ cd scrooge-mcetherface
$ pip3 install -r requirements.txt

Setup config.ini for Ganache:

[settings]
rpc = http://localhost:7545
sender = 0xf4a60CbD6C43418c71389d8a0D98a9A356609761
symbolic_tx_count = 3
timeout = 300
gasprice = 3000000000

Installing Theo (Frontrunning)

Theo has a PyPI package:

$ pip install --user theo --upgrade

Or you can just clone the repo and install it:

$ git clone https://github.com/cleanunicorn/theo
$ cd theo
$ pip install -e .

Workshop Content and Exercises

Level 1: Capturing the Ether

In the first example we'll focus on killing smart contracts as well as draining Ether from them. Here are a few hints:

$ myth analyze <codefile.sol>

For analysis of on-chain contracts use the --rpc and -a options.

$ myth analyze --rpc localhost:8545 -a <address>
$ myth analyze --rpc infura-ropsten -a <address>

To run Scrooge McEtherface, set up Scrooge's config.ini, then run:

$ ./scrooge <address>

Target Contracts:

Level 2: Integer Arithmetics

In the second example we'll again steal tokens and Ether, but this time with an integer arithmetics flavor.

Level 3: Honeypot

This time, we'll set up a honeypot for others to tap into (VulnerableTwoStep).

To run Theo, start it with available arguments:

$ theo
The account's private key (input hidden)
> 
Contract to interact with
> 0x1df62f291b2e969fb0849d99d9ce41e2f137006e
Scanning for exploits in contract: 0x1dF62f291b2E969fB0849d99D9Ce41e2F137006e
Received an empty response from eth_getCode. Check the contract address and verify that you are on the correct chain.
No exploits found. You're going to need to load some exploits.

Tools available in the console:
- `exploits` is an array of loaded exploits found by Mythril or read from a file
- `w3` an initialized instance of web3py for the provided HTTP RPC endpoint
- `dump()` writing a json representation of an object to a local file

Check the readme for more info:
https://github.com/cleanunicorn/theo

Theo version v0.8.1.

>>>

Protip:

To be safe from frontrunning and errors, wrap your exploit into a wrapper that reverts the transaction if the attack fails:

contract Wrapper {
    
	_target = 0xaAaAaAaaAaAaAaaAaAAAAAAAAaaaAaAaAaaAaaAa

    constructor(bytes memory _data) public payable {
        address proxy = address(this);
        uint256 start_balance = msg.sender.balance + proxy.balance;
        
        address(_target).call.value(msg.value)(_data);
        
        assert(msg.sender.balance + proxy.balance > start_balance);
        selfdestruct(msg.sender);
    }
     
    function() external payable {}
}

CTF Challenges

Mainnet addresses will be announced at the workshop.

    1. Long Range Replay - ABI
    1. YouToken - ABI
    1. Rev Eng -ABI

Advanced Setup

Running a Geth Light Client

Most of the examples work with Infura, but if you want to use Scrooge McEtherface and do things in a block-chainy way you should run your own node. Syncing a full node can take a couple of days but you can set up a light client instead. Install go-ethereum and run:

geth --testnet --syncmode light --rpc

This should sync with the Ropsten network pretty quickly. You can now point Metamask and Scrooge to Localhost 8545.

Getting Testnet ETH

First, you need a web3 capable browser and some testnet ETH. You probably also have both, but if not, get Metamask and grab some ETH from the Ropsten faucets:

Troubleshooting

openssl/aes.h: No such file or directory

If you get this error, you need the libssl source libraries:

    scrypt-1.2.1/libcperciva/crypto/crypto_aes.c:6:10: fatal error: openssl/aes.h: No such file or directory
     #include <openssl/aes.h>
              ^~~~~~~~~~~~~~~
    compilation terminated.
    error: command 'x86_64-linux-gnu-gcc' failed with exit status 1
    
    ----------------------------------------
Command "/usr/bin/python3 -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-5rl4ep94/scrypt/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-mnbzx9qe-record/install-record.txt --single-version-externally-managed --compile" failed with error code 1 in /tmp/pip-build-5rl4ep94/scrypt/

On Ubuntu you can install them with:

$ sudo apt install libssl-dev

mythril - Solc has experienced a fatal error (code 1).

This error may occur if the solidity compiler solc installed in path is incompatible with the provided source code (e.g. installed version is 0.5.x but smart contract requires <=0.4.x)

$ myth analyze <contract_0_4_x.sol>
 mythril.interfaces.cli [ERROR]: Solc has experienced a fatal error (code 1).
 code/RandomNumber.sol:8:1: Error: Source file requires different compiler version (current compiler is 0.5.3+commit.10d17f24.Darwin.appleclang - note that nightly builds are considered to be strictly less than the released version
contract GuessTheRandomNumberChallenge {
^------^
 SolidityVersionMismatch: Try adding the option "--solv <version_number>"

There's a few options how to resolve this:

  • Either try using --solv <solidity_version> as suggested by mythrils error message
  • Or force mythril to use a user-provide solc binary to comiple the code as follows:
$ export SOLC=/usr/local/bin/solc-0.4.26
$ myth analyze <contract_0_4_x.sol>

Solc releases

What to Do Next

A great way to continue learning is playing challenges like Capture the Ether, Security Innovation CTF and Ethernaut.

Credit

Created by ConsenSys Diligence and the Mythril team. Special thanks to Mick Ayzenberg (Security Innovation), Trail of Bits, Steve Marx of CaptureTheEther and ConsenSys fame and Zeppelin Solutions for vulnerable contract samples and challenges. Also, kudos to the Truffle and Guardrails teams for working with us on Mythril Platform integration.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published