Smatcontract を解析する Mythril の使い方 [初心者向け]

# はじめに

Smartcontract を書き始めて気になっているのが、セキュリティがしっかり担保されているかです。[有名な攻撃を再現](https://qiita.com/doskin/items/145c7dcea12066cb7f2e) して理解を深めようとはしているもののやっぱり誰かにチェックしてもらいたいと思ったりしています。

ConsenSys が提供する [Mythril](https://github.com/ConsenSys/mythril) を利用すると自動でスマートコントラクトの脆弱性チェックを行えると聞いたので、実際に試してみました。

# Mythril とは

[Official のレポジトリ](https://github.com/ConsenSys/mythril) によると、

> Mythril is a security analysis tool for Ethereum smart contracts. It uses the LASER-ethereum symbolic virtual machine to detect various types of issues. Use it to analyze source code or as a nmap-style black-box blockchain scanner (an "ethermap" if you will).

との事です。ばっくり言うと、スマートコントラクトのセキュリティ解析ツールで、ソースコードの解析もできるし、nmap のように既に deploy 済みのコントラクトをスキャンしてテストする事も出来ると記載されています。

# Mythril で出来る事

公式に記載があるように、以下の事が可能です。

- solidity のコード解析
- truffle などで build した compile 済みのスマートコントラクト (json 形式) の解析
- Ethereum に Deploy 済みのスマートコントラクトの解析

# 使い方

Docker を利用するか、直接依存関係をインストールして利用するかが選べます。本記事では Docker を利用して truffle プロジェクトを解析する使い方と、Deploy 済みのコントラクトの解析を行って見ます。

## Docker イメージのビルド

まずは github から repository を clone します

```console
$ git clone git@github.com:ConsenSys/mythril.git
$ cd mythril
``` 

Docker image を build します。([Docker for mac](https://docs.docker.com/docker-for-mac/)などは前もって入れておいてください)

```console
$ docker build -t mythril .
```

これで `mythril` という名前のイメージが作られます

```console
$ docker images
REPOSITORY                                      TAG                 IMAGE ID            CREATED             SIZE
mythril                                         latest              a4b7dc3fa4f2        17 hours ago        778MB
```

## コンテナを起動

コンテナの使い方は色々あると思いますが、一番簡単だと思われるボリュームマウントをする方式を試してみます。

まず、解析したい truffle project の root folder に移動します。
この時点では `mythril` コンテナは起動していません。

```console
$ cd /path/to/truffle/project
```

次に truffle project をコンテナにボリュームマウントさせつつ起動してシェルで中に入ります。

```console
$ docker run -it -v $PWD:/var/tmp mythril bash
root@63f76f5ce180:/#
```

ここで `$PWD` は現在のディレクトリを指します。

## 解析

### Truffle で compile したソースコードを解析

`/var/tmp` に host 側のディレクトリをマウントしているので移動しつつ解析をおこないます。

```console
# cd /var/tmp
# myth --truffle
Analysis result for BasicToken:
==== Exception state ====
Type: Informational
Contract: BasicToken
Function name: _function_0xa9059cbb
PC address: 969
A reachable exception (opcode 0xfe) has been detected. This can be caused by type errors, division by zero, out-of-bounds array access, or assert violations. This is acceptable in most situations. Note however that assert() should only be used to check invariants. Use require() for regular input checking.
--------------------
In file: BasicToken.json:44

.
  * @return

--------------------


Analysis result for CustomToken:
==== Exception state ====
Type: Informational
Contract: CustomToken
Function name: _function_0xd73dd623
PC address: 6791
A reachable exception (opcode 0xfe) has been detected. This can be caused by type errors, division by zero, out-of-bounds array access, or assert violations. This is acceptable in most situations. Note however that assert() should only be used to check invariants. Use require() for regular input checking.
--------------------
In file: CustomToken.json:33

es[_to] = bala

--------------------
...
```

こちらは、解析の一部ですが truffle によってコンパイルされたスマートコントラクトの問題点を列挙してくれています。

### 既に deploy 済みのコントラクトを解析

既に ethereum の network に deploy 済みのコントラクトを解析する事も可能です。

```bash
# myth --rpc infura-<network name> -xa <contract address>
```

例えば、私が rinkeby に Deploy した Sauna token を解析するコマンドは以下になります。

```bash
# myth --rpc infura-rinkeby -xa 0x076b38a5cb4423fc872f2617a0812a12fa0bd792
==== Exception state ====
Type: Informational
Contract: 0x076b38a5cb4423fc872f2617a0812a12fa0bd792
Function name: _function_0xa6f2ae3a
PC address: 2263
A reachable exception (opcode 0xfe) has been detected. This can be caused by type errors, division by zero, out-of-bounds array access, or assert violations. This is acceptable in most situations. Note however that assert() should only be used to check invariants. Use require() for regular input checking.
--------------------

==== Message call to external contract ====
Type: Warning
Contract: 0x076b38a5cb4423fc872f2617a0812a12fa0bd792
Function name: _function_0xcae9ca51
PC address: 2603
This contract executes a message call to an address provided as a function argument. Generally, it is not recommended to call user-supplied adresses using Solidity's call() construct. Note that attackers might leverage reentrancy attacks to exploit race conditions or manipulate this contract's state.
--------------------

==== Integer Underflow ====
Type: Warning
Contract: 0x076b38a5cb4423fc872f2617a0812a12fa0bd792
Function name: _function_0x95d89b41
PC address: 1343
A possible integer underflow exists in the function _function_0x95d89b41.
The substraction may result in a value < 0.
--------------------

==== Integer Underflow ====
Type: Warning
Contract: 0x076b38a5cb4423fc872f2617a0812a12fa0bd792
Function name: _function_0x95d89b41
PC address: 436
A possible integer underflow exists in the function _function_0x95d89b41.
The substraction may result in a value < 0.
--------------------

==== Integer Underflow ====
Type: Warning
Contract: 0x076b38a5cb4423fc872f2617a0812a12fa0bd792
Function name: _function_0x95d89b41
PC address: 441
A possible integer underflow exists in the function _function_0x95d89b41.
The substraction may result in a value < 0.
--------------------

==== Integer Underflow ====
Type: Warning
Contract: 0x076b38a5cb4423fc872f2617a0812a12fa0bd792
Function name: _function_0x95d89b41
PC address: 462
A possible integer underflow exists in the function _function_0x95d89b41.
The substraction may result in a value < 0.
--------------------

==== Integer Underflow ====
Type: Warning
Contract: 0x076b38a5cb4423fc872f2617a0812a12fa0bd792
Function name: _function_0x42966c68
PC address: 1618
A possible integer underflow exists in the function _function_0x42966c68.
The substraction may result in a value < 0.
--------------------

==== Integer Underflow ====
Type: Warning
Contract: 0x076b38a5cb4423fc872f2617a0812a12fa0bd792
Function name: _function_0x79cc6790
PC address: 2058
A possible integer underflow exists in the function _function_0x79cc6790.
The substraction may result in a value < 0.
--------------------

==== Integer Underflow ====
Type: Warning
Contract: 0x076b38a5cb4423fc872f2617a0812a12fa0bd792
Function name: _function_0xcae9ca51
PC address: 2602
A possible integer underflow exists in the function _function_0xcae9ca51.
The substraction may result in a value < 0.
--------------------

==== Integer Underflow ====
Type: Warning
Contract: 0x076b38a5cb4423fc872f2617a0812a12fa0bd792
Function name: _function_0xcae9ca51
PC address: 2549
A possible integer underflow exists in the function _function_0xcae9ca51.
The substraction may result in a value < 0.
--------------------

==== Integer Underflow ====
Type: Warning
Contract: 0x076b38a5cb4423fc872f2617a0812a12fa0bd792
Function name: _function_0xcae9ca51
PC address: 2554
A possible integer underflow exists in the function _function_0xcae9ca51.
The substraction may result in a value < 0.
--------------------
```

ダメダメなので精進します(笑)

# 終わりに

スマートコントラクトのセキュリティチェックを行える Mythril を使うと、見えていなかった脆弱性などが発見できるので Deploy する前にはチェックするのが良いかなと思いました。一方でここで全ての脆弱性が洗い出せる訳では無い様な気もするので日々勉強を怠らずに堅牢なスマートコントラクトをかける様になりたいと思います。