A comparison report on formal verification of two tools (VaaS & Mythril)

640?wx_fmt=jpeg

640?wx_fmt=gif

▼This article is transferred from "Bi Express"

640?wx_fmt=jpeg

As the blockchain 2.0 era centered on smart contracts (Smart Contracts) and blockchain applications (DApps) has gradually become mainstream, the security of smart contracts and blockchain applications has increasingly become the focus of attention in the industry.

In particular, after experiencing incidents such as THE DAO and the theft of Binance , how to verify and guarantee the security of smart contracts and blockchain applications has become an urgent pain point in the current blockchain industry.

 

The author has made simple statistics. From September 2017 to September 2018, the related vulnerabilities of smart contracts and blockchain applications showed a pattern of frequent outbreaks , and the consequences were far-reaching. Not only did it directly cause a huge amount of money loss; from the perspective of long-term development, it also affected the sustainable development of the emerging technology of blockchain in the future.

 

In addition, although the potential vulnerabilities of current smart contracts and blockchain applications have not been properly resolved, the status quo is that the number of smart contracts and blockchain applications is still increasing rapidly at an average growth rate of tens of thousands every day.

It is not difficult to see that the growth rate and security of smart contracts and blockchain applications are coexisting in an unhealthy relationship. If we use the analogy of supply and demand (growth rate is "supply"; security is "demand"), the current general status of smart contracts and blockchain applications is the state of "supply exceeds demand " .

 

Based on this, how to ensure the security of massive smart contracts and blockchain applications has become a core issue for forward-looking enterprises and individuals in the blockchain industry. In fact, there are currently special methods in the industry to overcome this pain point, such as feature code matching, automatic auditing based on symbolic execution and symbolic abstraction, and automatic auditing based on formal verification . Among them, after extensive exploration and practice in the industry, "automatic audit based on formal verification" has become a relatively mature and mainstream method in the industry.

 

Therefore, the author specifically focuses on "formal verification", selects two major formal verification tools (VaaS & Mythril) in the current industry , and conducts a simple test comparison. In particular, the version of the Mythril tool used for testing is "0.21.12".

The following is the relevant test report, hoping to throw bricks and spark jade, and bring some intuitive feelings and objective suggestions to readers. If there is anything wrong, please leave a message to point out. (This article only represents the author's personal suggestion after the test, and does not endorse any products and tools)

1

Introduction to VaaS & Mythril Tools

01. Introduction to VaaS tools

The VaaS tool is an automatic formal verification tool independently developed by Beosin Chengdu Lianan using its own intellectual property rights. It can provide "military-level" formal verification services for smart contracts and blockchain applications , and can accurately locate risky codes The position and the cause of the risk are pointed out, and the conventional security loopholes, security attributes and functional correctness of the smart contract are effectively detected, with an accuracy of over 95% .

02. Introduction to Mythril tools

The Mythril tool is a security analysis tool provided by the Ethereum open source community . It can detect security vulnerabilities in Solidity smart contracts and perform in-depth analysis. It is a security analysis tool for analyzing the security of Ethereum smart contracts and blockchain applications and Engine , supports common IDE integration.

2

Test case composition

The contract test case consists of 260 token contracts and 20 business contracts .

 

  • Token contracts include Top200 token contracts and 60 typical token contracts for auditing, covering functions such as ICO, lock-up, minting and burning .

  • Business contracts include 20 business contracts such as auctions, shopping malls, and traceability .

3

Overview of test results

VaaS tools can detect all contract test cases of tokens and business classes; but Mythril tools can only detect token contracts, but cannot detect business contracts. Therefore, it should be noted that this overview of test results is only a comparative analysis of the list of token contracts.

 

VaaS tools have a total of 28 vulnerability checks; but Mythril tool has only 9 vulnerability checks compared to VaaS tools. Therefore, the detection items of VaaS tools are far more than those of Mythril tools. The specific detection items are compared as follows:

Comparison of VaaS & Mythril detection items

Vulnerability detection items

Mythril

Vase

ERC20 standard specification

Fake Recharge Vulnerability

TransferToZeroAddress (target zero address detection)

Re Entrancy

TXOriginAuthentication (tx.origin usage error)

Invoke Low Level Calls (call call, delegatecall call, suicide function call)

BlockMembers Manipulation (block parameter dependency)

Invoke Extcodesize (call Extcodesize function)

Invoke Ecrecover (call Ecrecover function)

Unchecked Call Or Send Return Values ​​(call and send return value detection)

Denial of service

Redefine Variable From Base Contracts (variable coverage in contract inheritance)

Unprotected Ether Withdrawal

Check This Balance (contract funds are strictly limited)

ArbitraryJumpwith Function (arbitrary with function type variables)

Overload Assert (rewrite assert function)

CompilerVersionDeclaration (compiler version declaration)

Constructor Mistyping

Complex Code In Fallback Function (used by fallback function)

Unary Operation (+= written as =+ )

No Return (return value adaptation)

Unchecked Api Return Values ​​(do not check the API return value)

Emit Event Beforeerevert (event triggered before revert)

Integer Overflow

Exception State (abnormal detection, including array out of bounds, division by 0, assert failure, etc.)

Call problem

Function problem

Require Fail

01. The test results of the same test items for both

For the selected 260 token test cases, the Mythril tool can run 184 contract results within 15 minutes, and 76 have no detection results; while the VaaS tool can run all the results. Take the 184 results that both the Mythril tool and the VaaS tool can run for comparison, and the results are as follows.

  • Hit Rate & False Positive Rate

通过检测结果对比,之于相同的检测项,VaaS工具的检测能力是远远高于Mythril工具的检测能力。据计算,VaaS工具的检测精度为96.9%;Mythril工具的检测精度为36.6%;而VaaS工具的误报率为15.3%;Mythril工具的误报率为48.5%。具体见下图。

640?wx_fmt=png

需要注意的是,命中率和误报率的计算公式为:

  • 命中率 = 命中个数/总问题个数

  • 误报率 = 误报个数/(误报个数+命中个数)

 

笔者统计,VaaS工具和Mythril工具两者都进行的检测项共计655个问题:

  • VaaS工具总计检测出635个问题,命中率为96.9%;误报共115个,误报率为15.3%

  • Mythril工具总计检测出240个问题,命中率为36.6%;误报共计226个,误报率为48.5%。其中,Mythril工具重入攻击和拒绝服务误报率较高,占总数的93.3%。

 

检测总数值具体对比如下表:

VaaS

Mythril

检测用例个数

184

184

问题总数

655

655

命中个数

635

240

误报个数

115

226

命中率

96.9%

36.6%

误报率

15.3%

48.5%

针对每项详细结果对比如下表:

漏洞检测项

总数

Mythril

VaaS

命中

误报

命中

误报

Re Entrancy(重入)

14

7

115

14

0

50%

94.2%

100%

0

TXOrigin

Authentication

(tx.origin使用错误)

4

4

0

4

0

100%

0

100%

0

BlockMembers

Manipulation

(区块参数依赖)

116

21

0

116

0

18.1%

0

100%

0

Denial of service

(拒绝服务)

14

7

83

14

0

50%

92.2%

100%

0

Invoke Low Level Calls

(call调用,delegatecall调用,自杀函数调用)

54

7

0

54

0

12.9%

0

100%

0

Unchecked Call Or Send Return Values

(call和send的返回值检测)

25

4

0

25

0

16%

0

100%

0

Integer Overflow

(整数溢出)

356

126

28

336

90

35.3%

18.1%

94.3%

20.1%

Exception State

(assert失败)

72

64

0

72

25

88.8%

0

100%

25.7%

  • 测试时限

Mythril工具的平均测试时间为226.2s;而VaaS工具的平均测试时间为164.4s。说明VaaS工具的运行效率优于Mythril工具。

02.之于VaaS工具特有检测项的检测结果

具体见下表:

VaaS工具特有检测项用例结果展示说明

分类

VaaS log 关键字

说明

ERC20 标准规范

Erc20 Variable

ERC20 变量命名规范

Erc20 Function

Erc20函数命名规范

Erc20 Event

Erc20 event使用规范

Fake Recharge Vulnerability

假充值

Transfer To Zero Address

目标地址非零检查

敏感函数调用

Invoke Extcodesize

调用Extcodesize函数

Invoke Ecrecover

调用Ecrecover函数

不推荐使用

Redefine Variable From Base Contracts

合约继承中的变量覆盖

check_this_balance

合约资金受到严格限制

unused_variables

未使用的变量

Arbitrary Jump with Function Type Variable

具有函数类型变量的任意跳转

Overload Assert

重写assert函数

Solidity编码规范

Compiler Version Declaration

编译器版本声明

Constructor Mistyping

构造函数失配

Complex Code In Fallback Function

fallback函数使用

Unary Operation

+= 写成=+

Constructor Warning

缺少主构造函数

No Return

返回值适配

Unchecked Api Return Values

没检查API返回值

Emit Event Beforerevert

事件在revert前触发了

逻辑验证

Call problem

call调用执行总是revert

Function problem

Function执行总是失败

4

案例演示

01.两者相同检测项案例

  • Re Entrancy(重入)

案例:

640?wx_fmt=png

interface TEST {

    function test123() external view returns (uint256);

    function getBlocknumber() external view returns (uint256);

}

 

contract test2 {

 

    function testCalling(address _testAdddress) public {

        TEST t = TEST(_testAdddress);

t.test123();//mythril 误报

 

    }

 

    function testFormal(address _testAdddress) public view returns(uint256 time){

        TEST t = TEST(_testAdddress);

        t.getBlocknumber();//mythril 误报

        return time;

    }

}

contract Reentrancy {

    mapping(address => uint256) public balances;

 

    event WithdrawFunds(address _to,uint256 _value);

 

    function depositFunds() public payable {

        balances[msg.sender] += msg.value;

    }

 

    function showbalance() public view returns (uint256 ){

        return address(this).balance;

    }

 

    function withdrawFunds (uint256 _weiToWithdraw) public {

        require(balances[msg.sender] >= _weiToWithdraw);

        require(msg.sender.call.value(_weiToWithdraw)());

balances[msg.sender] -= _weiToWithdraw;//mythril 明显的误报

        emit WithdrawFunds(msg.sender,_weiToWithdraw);

    }

}

640?wx_fmt=png

  • VaaS工具测试结果:

640?wx_fmt=png

  • Mythril工具测试结果:

640?wx_fmt=png
640?wx_fmt=png

▷笔者分析,VaaS工具报出存在重入攻击的位置;而Mythril工具针对外部的call调用作了告警,总共有4处告警,其中2处是正常的外部调用,另1处是明显的误报,误报率较高。

  • TXOriginAuthentication(tx.origin使用错误)

案例:

640?wx_fmt=png

contract TxUserWallet {

    address owner;

 

    constructor() public {

        owner = msg.sender;

    }

 

    function transferTo(address  dest, uint amount) public {

        require(tx.origin == owner);

        dest.transfer(amount);

    }

}

640?wx_fmt=png

  • VaaS工具测试结果:

640?wx_fmt=png

  • Mythril工具测试结果:

640?wx_fmt=png

▷笔者分析,VaaS工具和Mythril工具均能对tx.origin关键字进行检测报警。

  • Invoke Low Level Calls(call调用,delegatecall调用,自杀函数调用)

案例:

640?wx_fmt=png

contract Delegatecall{

    uint public q;

    bool public b;

    address addr = 0xde6a66562c299052b1cfd24abc1dc639d429e1d6;

    function Delegatecall() public payable {

 

    }

 

    function call1() public returns(bool) {

b = addr.delegatecall

(bytes4(keccak256("fun(uint256,uint256)")),2,3);

        return b;

    }

 

    function call2(address add) public returns(bool){

b=add.delegatecall

(bytes4(keccak256("fun(uint256,uint256)")),2,3);

        return b;

    }

}

640?wx_fmt=png

  • VaaS工具测试结果:

640?wx_fmt=png

  • Mythril工具测试结果:

640?wx_fmt=png

▷笔者分析,案例有两处delegetacall调用,而Mythril工具仅报了一次,存在漏报风险。

  • BlockMembers Manipulation(区块参数依赖)

案例:

640?wx_fmt=png

function createTokens() payable external {

      if (isFinalized) throw;

if (block.number < fundingStartBlock) throw;

if (block.number > fundingEndBlock) throw;

      if (msg.value == 0) throw;

 

      uint256 tokens = safeMult(msg.value, tokenExchangeRate);  

      uint256 checkedSupply = safeAdd(totalSupply, tokens);

 

      if (tokenCreationCap < checkedSupply) throw;  

 

      totalSupply = checkedSupply;

      balances[msg.sender] += tokens;  

      CreateBAT(msg.sender, tokens);  

    }

 

function finalize() external {

      if (isFinalized) throw;

      if (msg.sender != ethFundDeposit) throw;

      if(totalSupply < tokenCreationMin) throw;      

      if(block.number <= fundingEndBlock && totalSupply != tokenCreationCap) throw;

      // move to operational

      isFinalized = true;

      if(!ethFundDeposit.send(this.balance)) throw;  

    }

 

 

function refund() external {

      if(isFinalized) throw;                       

if (block.number <= fundingEndBlock) throw;

      if(totalSupply >= tokenCreationMin) throw;  

      if(msg.sender == batFundDeposit) throw;    

      uint256 batVal = balances[msg.sender];

      if (batVal == 0) throw;

      balances[msg.sender] = 0;

      totalSupply = safeSubtract(totalSupply, batVal);

      uint256 ethVal = batVal / tokenExchangeRate;     

      LogRefund(msg.sender, ethVal);               

      if (!msg.sender.send(ethVal)) throw;       

    }

}

640?wx_fmt=png

  • VaaS工具测试结果:

640?wx_fmt=png

  • Mythril工具测试结果:

640?wx_fmt=png

▷笔者分析,VaaS工具和Mythril工具均能对区块参数依赖作出检测;但Mythril工具存在漏报风险。

  • Denial of service(拒绝服务)

案例:

640?wx_fmt=png

contract Auction {

    address public highestBidder = 0x0;

    uint256 public highestBid;

    function Auction(uint256 _highestBid) {

        require(_highestBid > 0);

        highestBid = _highestBid;

        highestBidder = msg.sender;

    }

    function bid() payable {

        require(msg.value > highestBid);

        highestBidder.transfer(highestBid);

highestBidder = msg.sender;

highestBid = msg.value;

    }

    function auction_end() {

    }

}

640?wx_fmt=png

  • VaaS工具测试结果:

640?wx_fmt=png

  • Mythril工具测试结果:

640?wx_fmt=png

▷笔者分析,VaaS工具和Mythril工具均能针对拒绝服务作出风险检测。但在此案例中,highestBidder可能是恶意攻击合约,而导致transfer恒不成功,从而导致合约拒接服务,此案例VaaS工具能够检测出拒绝服务风险,Mythril工具未检出。

  • Unchecked Call Or Send Return Values(call和send的返回值检测)

案例:

640?wx_fmt=png

if (lastTimeOfNewCredit + TWELVE_HOURS < block.timestamp) {

msg.sender.send(amount);

    creditorAddresses[creditorAddresses.length - 1].send(profitFromCrash);

    corruptElite.send(this.balance);

    ...

    return true;

}

else {

msg.sender.send(amount);

return false;

}

640?wx_fmt=png

  • VaaS工具测试结果:

640?wx_fmt=png

  • Mythril工具测试结果:

640?wx_fmt=png

▷笔者分析,VaaS工具和Mythril工具均能对未检查call调用的返回值检测;但Mythril工具存在漏报风险。

  • Integer Overflow(整数溢出)

案例1:

640?wx_fmt=png

function distributeBTR(address[] addresses) onlyOwner {

    for (uint i = 0; i < addresses.length; i++) {

        balances[owner] -= 2000 * 10**8;

        alances[addresses[i]] += 2000 * 10**8;

        Transfer(owner, addresses[i], 2000 * 10**8);

}

    }

640?wx_fmt=png

▷笔者分析,以上案例没有对balances[owner]的值作检测,可能会产生下溢,但Mythrill工具不会报错,说明Mythrill工具对常数的运算不会作检测。

案例2:

640?wx_fmt=png

contract A {

    uint c;

    function add(uint8 a,uint8 b){

uint8 sum = a+b;

        c=sum;

    }

}

640?wx_fmt=png

  • VaaS工具测试结果:

640?wx_fmt=png

  • Mythril工具测试结果:

640?wx_fmt=png

▷笔者分析,Mythrill工具对非uint256数据类型的溢出检测不准确。

案例3:

  • Mythril工具的一些检测结果:

640?wx_fmt=png
640?wx_fmt=png

▷笔者分析,Mythrill工具对一些特定变量未作处理,导致误报。比如数组,msg.value,now等。

02.VaaS工具特有检测项案例

案例1:

640?wx_fmt=png

...

contract ERC20 is ERC20Basic {

  function allowance(address owner, address spender) constant returns (uint);

function transferFrom(address from, address to, uint value);

  function approve(address spender, uint value);

  event Approval(address indexed owner, address indexed spender, uint value);

}

...

 function transfer(address _to, uint _value) onlyPayloadSize(2 * 32) {

    balances[msg.sender] = balances[msg.sender].sub(_value);

    balances[_to] = balances[_to].add(_value);

    Transfer(msg.sender, _to, _value);

  }

640?wx_fmt=png

  • 测试结果:

640?wx_fmt=png
640?wx_fmt=png

案例2:

640?wx_fmt=png

contract A {

    B b;

    uint c;

    function test(uint a){

        b = new B(a);

        c = b.get(200);

    }

}

contract B {

    uint b;

    function B(uint e){

        b=100;

    }

    function get(uint a)returns(uint){

        require(a<100);

        return a;

  }

}

640?wx_fmt=png

  • 测试结果:

640?wx_fmt=png

▷笔者分析,在案例2中关于合约间的调用问题,在拥有源码的情况下,VaaS工具是可以调用成功并进行测试的;而Mythril工具不行。这也是Mythril工具无法进行业务合约验证的原因之一。

640?wx_fmt=jpeg

通过以上对VaaS工具和Mythril工具逻辑、维度、数据进行简单的对比分析,笔者认为,读者在阅后将能够根据自身业务取向和侧重作出相应的判断和评估。

且毋论智能合约和区块链应用,甚至整个区块链行业的安全性,未来都将需要以一种供(增长率)求(安全性)关系平衡的模式向前发展,我们就更需要清楚地知道,当前现状的痛点所在,以及如何针对该痛点进行改进和革新。

 

无论是作为前沿科技拥戴者,还是区块链技术极客,但凡具备去中心化思维以及认可智能合约及区块链应用在未来具备深远影响力的有识之士,都能明白笔者针对『形式化验证』作此篇测试报告的用意。

It is true that although more attention is currently being paid to how to promote the implementation of smart contracts and blockchain applications and the overall construction of the blockchain ecosystem, if there are still various loopholes and risks in the underlying technical architecture that have not been resolved , it would be too ambitious.

 

Therefore, the author suggests that in order to ensure the security of massive smart contracts and blockchain applications, as well as maintain the good operation and maintenance of blockchain ecology, "formal verification" has become an important way of automated auditing.

It is a necessary stage for the development of current smart contracts and blockchain applications to judge the feasibility of a certain verification and audit tool through evaluation dimensions such as false negative rate, false positive rate, hit rate, and test time limit . Chain practitioners need to earnestly implement the mission.

▲Some pictures are from the Internet

more information

640?wx_fmt=gif
640?wx_fmt=jpeg

Beosin Media Matrix

640?wx_fmt=png

Facebook

https://www.facebook.com/

BeosinChengdu/

640?wx_fmt=png

Twitter

https://twitter.com/Beosin_com

640?wx_fmt=png

Telegram

https://t.me/LiananTech_cn (Chinese)

https://t.me/LiananTech_en (English)

640?wx_fmt=png

Weibo

https://weibo.com/u/6566884467

640?wx_fmt=png

CSDN blog

https://blog.csdn.net/CDLianan

640?wx_fmt=png

Mars

Chengdu Chain Security Technology

640?wx_fmt=png

Know almost

Chengdu Chain Security Technology

640?wx_fmt=png

GitHub

https://github.com/Lianantech/VCA

640?wx_fmt=png

Click "Read the original text"

Immediately visit the official website of "Beosin Chengdu Lian'an"

Guess you like

Origin blog.csdn.net/CDLianan/article/details/102559337