▼This article is transferred from "Bi Express"
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)
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%。具体见下图。
需要注意的是,命中率和误报率的计算公式为:
命中率 = 命中个数/总问题个数
误报率 = 误报个数/(误报个数+命中个数)
笔者统计,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(重入)
案例:
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);
}
}
VaaS工具测试结果:
Mythril工具测试结果:
▷笔者分析,VaaS工具报出存在重入攻击的位置;而Mythril工具针对外部的call调用作了告警,总共有4处告警,其中2处是正常的外部调用,另1处是明显的误报,误报率较高。
TXOriginAuthentication(tx.origin使用错误)
案例:
contract TxUserWallet {
address owner;
constructor() public {
owner = msg.sender;
}
function transferTo(address dest, uint amount) public {
require(tx.origin == owner);
dest.transfer(amount);
}
}
VaaS工具测试结果:
Mythril工具测试结果:
▷笔者分析,VaaS工具和Mythril工具均能对tx.origin关键字进行检测报警。
Invoke Low Level Calls(call调用,delegatecall调用,自杀函数调用)
案例:
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;
}
}
VaaS工具测试结果:
Mythril工具测试结果:
▷笔者分析,案例有两处delegetacall调用,而Mythril工具仅报了一次,存在漏报风险。
BlockMembers Manipulation(区块参数依赖)
案例:
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;
}
}
VaaS工具测试结果:
Mythril工具测试结果:
▷笔者分析,VaaS工具和Mythril工具均能对区块参数依赖作出检测;但Mythril工具存在漏报风险。
Denial of service(拒绝服务)
案例:
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() {
}
}
VaaS工具测试结果:
Mythril工具测试结果:
▷笔者分析,VaaS工具和Mythril工具均能针对拒绝服务作出风险检测。但在此案例中,highestBidder可能是恶意攻击合约,而导致transfer恒不成功,从而导致合约拒接服务,此案例VaaS工具能够检测出拒绝服务风险,Mythril工具未检出。
Unchecked Call Or Send Return Values(call和send的返回值检测)
案例:
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;
}
VaaS工具测试结果:
Mythril工具测试结果:
▷笔者分析,VaaS工具和Mythril工具均能对未检查call调用的返回值检测;但Mythril工具存在漏报风险。
Integer Overflow(整数溢出)
案例1:
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);
}
}
▷笔者分析,以上案例没有对balances[owner]的值作检测,可能会产生下溢,但Mythrill工具不会报错,说明Mythrill工具对常数的运算不会作检测。
案例2:
contract A {
uint c;
function add(uint8 a,uint8 b){
uint8 sum = a+b;
c=sum;
}
}
VaaS工具测试结果:
Mythril工具测试结果:
▷笔者分析,Mythrill工具对非uint256数据类型的溢出检测不准确。
案例3:
Mythril工具的一些检测结果:
▷笔者分析,Mythrill工具对一些特定变量未作处理,导致误报。比如数组,msg.value,now等。
02.VaaS工具特有检测项案例
案例1:
...
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);
}
测试结果:
案例2:
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;
}
}
测试结果:
▷笔者分析,在案例2中关于合约间的调用问题,在拥有源码的情况下,VaaS工具是可以调用成功并进行测试的;而Mythril工具不行。这也是Mythril工具无法进行业务合约验证的原因之一。
通过以上对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
Beosin Media Matrix
|
https://www.facebook.com/ BeosinChengdu/ |
|
https://twitter.com/Beosin_com |
|
Telegram https://t.me/LiananTech_cn (Chinese) https://t.me/LiananTech_en (English) |
|
https://weibo.com/u/6566884467 |
|
CSDN blog https://blog.csdn.net/CDLianan |
|
Mars Chengdu Chain Security Technology |
|
Know almost Chengdu Chain Security Technology |
|
GitHub https://github.com/Lianantech/VCA |
Click "Read the original text"
Immediately visit the official website of "Beosin Chengdu Lian'an"