Mythril 是一个免费的以太坊智能合约的安全分析工具。Mythril 能检测以太坊和其他兼容 EVM 的区块链构建的智能合约的安全漏洞,包括整数溢出、时间戳依赖、重入攻击等。

注意,Mythril 的目标是找到合约中常见的漏洞,而不能发现应用程序的业务逻辑问题。

因此,如果要对一个商用系统的智能合约进行安全分析,我们建议使用成熟的商用化的安全审计产品,如 MythX、Certik、ChainSulting、OpenZeppelin 等。当然,这些产品不是免费的。

目前,Mythril 支持 MacOS 和 Ubuntu,不支持 Windows。

首先安装 Mythril 的运行环境。我们的操作系统环境是 Ubuntu(版本18.04),它是安装在 Windows 10 系统虚拟机 VMware 环境下的 Linux 系统。

安装 Mythril 有PyPI 库安装和 Docker 安装两种方式,本课程我们以 Docker 安装方式为例来详细介绍 Mythril 工具的安装。

所有的 Mythril 版本,从 v0.18.3 开始,都以 mythril/myth 的名称作为 Docker images 发布到 Docker Hub。

如果你的系统上已安装了 Docker,请忽略。否则,通过下面的命令安装 Docker:

安装完成后默认 Docker 已启动,通过下面的命令查看版本:

如果安装成功,上面的命令会输出 Docker 的版本号,如下图:

docker版本号

如果需要手动启动和停止 Docker,请使用下面的命令:

查看 Docker 服务是否已启动,请使用下面的命令:

如果 Docker 服务已启动,控制台输出如下图:

docker启动状态

安装 Docker 镜像

通过下面的命令安装最新版本的 Mythril:

安装完成后,通过下面的命令查看版本:

如果安装成功,上面的命令会输出 Mythril 的版本号,如下图:

mythril版本号

Mythril 用法

通过下面的命令查看 Mythril 的帮助:

Mythril 的帮助输出如下图:

mythril帮助

通过下面的命令对合约源代码进行安全分析:

下面是一个用于安全分析的智能合约源码,这个合约类似于一个抽奖系统,其逻辑是:(1)玩家向合约发送 1 个以太币;(2)合约进行逻辑判断,在同一个区块中对区块时间戳除以 15 取模,当结果为零时,向玩家发送合约中剩余的以太币作为奖励。

以上这个智能合约有一个时间戳依赖漏洞。时间戳依赖是指智能合约的执行依赖于当前区块的时间戳,如果时间戳不同,那么合约的执行结果也有差别。智能合约中取得时间戳只能依赖某个节点(矿工)来做到。这就是说,合约中取得的时间戳是可以由运行其代码的节点(矿工)决定的。理论上,这个时间是可以由矿工控制的。因此,如果在智能合约中不正确地使用区块时间戳,这将是非常危险的。

接下来,让我们观察 Mythril 工具对这个合约的检测与分析结果。

首先,我们把这个合约文件发送到 Ubuntu 主机的 "/tmp" 目录。

然后,通过以下命令来对合约源码执行检测分析:

耐心等待几分钟后(这个执行时间取决于主机的配置),我们看到检测结果如下:

通过以上的检测分析结果,我们可以看到,Mythril 工具确实检测出了合约中的漏洞。这个合约代码共有两个时间戳依赖安全问题。

第一个安全漏洞

漏洞名称:依赖于可预测的环境变量(时间戳依赖)

SWC ID: 116 —— 表示该漏洞的分类编号

Severity: Low  —— 表示该漏洞的严重性程度

Contract: Roulette —— 表示检测的合约名称

Function name: fallback —— 表示发现漏洞的函数名称

PC address: 70 —— 表示程序计数器地址,Program Counter 的简称

Estimated Gas Usage: 889 - 984 —— 表示估算的 Gas 费用开销

漏洞描述——控制流的决定是基于区块的时间戳环境变量。block.timestamp 环境变量用于确定控制流决策。请注意,coinbase、gaslimit、block number 和 timestramp 等变量的值是可预测的,可以被恶意矿工操纵。还要记住,攻击者知道早期块的哈希值。请注意,不要使用任何这些环境变量作为随机性的来源,并且确保使用的这些变量对矿工是可信任的。

再接下来是漏洞代码在合约代码中的行号,并给出了代码段,以及合约的初始状态和交易序列。

第二个安全漏洞

漏洞名称:依赖与可预测的环境变量(时间戳依赖)

SWC ID: 116

Severity: Low

Contract: Roulette

Function name: fallback

PC address: 102

Estimated Gas Usage: 6105 - 26200

漏洞描述与第一个漏洞相同,均属于时间戳依赖的安全问题。

漏洞分类(SWC ID)详见 智能合约缺陷分类和测试用例

缺省情况下,分析结果以文本形式打印到终端。你可以用 -o 参数改变输出格式:

可用的格式有 text、markdown、json 和 jsonv2。对于与其他工具的集成,通常首选 jsonv2 而不是 json,因为它与其他 MythX 工具保持一致。