Machine Learning Model for Smart Contracts Security Analysis

Machine Learning Model for Smart Contracts Security Analysis

论文标题:(2019-PST) Machine Learning Model for Smart Contracts Security Analysis——智能合约安全性分析的机器学习模型

论文引用:Momeni P, Wang Y, Samavi R. Machine Learning Model for Smart Contracts Security Analysis[C]//2019 17th International Conference on Privacy, Security and Trust (PST). IEEE, 2019: 1-6.

代码开源:本文代码并未开源

本文发表于2019 17th International Conference on Privacy, Security and Trust (PST),三名作者都是来自加拿大的麦克马斯特大学

一、主要内容

本文介绍了一种机器学习的预测模型(machine learning predictive model )用以检测智能合约中的漏洞。作者采用了SlitherMythril两个静态代码分析器【都已在GitHub上开源】(static code analyzers)来标记1000多个已在以太坊平台上验证并使用的智能合约,然后提取合约中的46种漏洞,对每一种漏洞都采用五重交叉验证(five-fold cross validation)进行建模。使用模型预测了16种类型的漏洞,平均准确度为95%,F1score为79%。

二、智能合约静态代码分析

静态代码分析器无需执行程序即可在计算机软件中搜索bug。静态代码分析有两种:分析源代码和分析目标代码。

智能合约安全挑战

  1. 将智能合约上传到区块链后,任何其他合约或用户都可以调用该合约。这会生成无法在合同的未经测试的执行路径上执行的输入的不可预测的组合。
  2. 因为合约的二进制代码及其状态存储在区块链的不变账本中,智能合约无法修补,如果安全问题严重,则平台管理员可以用分叉来更改或删除分类帐,但是分叉代价极大。

Solidity源代码中提取了抽象语法树(AST)作为程序的中间表示形式,因为AST提供了有关程序代码的信息,这些信息可用作查找漏洞的特征。

抽象语法树(AST)

AST在编译器中广泛使用的代表程序代码结构的数据结构。 AST中的每个节点代表一种编程语言的语法元素,树显示了这些元素的使用顺序。静态代码分析器支持AST,因为AST提供了有关源代码特征的丰富详细信息,例如函数定义或其他合同中的合同的数量。使用Solc(Solidity命令行编译器)从Solidity代码生成AST。

控制流程图(CFG)

CFG表示程序可以表示采取的所有执行路径。可以从AST提取CFG,在AST编译器使用CFG的目的是从程序的语句生成汇编代码。 CFG还常用于静态代码分析工具中,以在程序中定位无法访问的代码。

静态代码分析

为了运行静态分析器,需要首先通过词法分析器(lexer tools)工具解析源代码。然后,从解析的代码生成抽象语法树(AST),并从AST中提取控制流图(CFG)。通过执行这些步骤,静态代码分析器能够检查通过CFG的所有执行路径是否存在潜在的错误。静态代码分析器根据不同类型的漏洞执行不同的分析,例如符号执行和污点分析。

三、基于机器学习的智能合约代码分析

基于机器学习的代码分析器概述

图1 基于机器学习的代码分析器概述

数据收集与预处理

数据集是从Etherscan 收集的,我们总共收集了以Solidity编写的13,745个唯一的活动智能合约源代码。由于Solidity编译器的版本4不向后兼容,因此专注于数据集中版本为0.4.18的智能合约,合格智能合约的数量减少到1,013。将数据集分为80%训练和20%测试集。

建立AST和特征提取

从数据集中,我们从AST中提取了17个特征,如表I所示。这些特征是常见的Solidity代码结构,在我们的数据集中出现了1000多次。这些功能代表了代码的复杂性,可以分为两类:

  1. 代表执行路径(例如,函数调用)并直接添加到控制流程图的特征;
  2. 代表启发式猜测(heuristic guesses)的其他功能代码的复杂性,例如代码行(LOC)。
表1 AST中提取的特征
Feature Name
1 Lines of code (LOC) 10 Bytes
2 Contract definitions 11 Elementary type addresses
3 Function definitions 12 Modifier definitions
5 Binary operations 13 Placeholder statements
6 Function calls 14 Modifier invocation
7 Blocks 15 Approve function definitions
8 Expression statements 16 Constant values
9 Event definitions 17 Hexadecimal addresses

静态代码分析

使用了两个智能合约静态代码分析器Mythril 和Slither。这两个工具在区块链社区中具有很高的影响力和声誉。Mythril Classic:此分析器使用多种技术(例如符号执行和污点分析)来检测Solidity代码中的安全漏洞。Mythril可以检测19种类型的漏洞。如表II所示,在这19个漏洞中,我们的数据集中发现了11个漏洞。

Slither:此分析器使用污点分析来跟踪Solidity代码分析中的值,并且可以找到31种类型的漏洞,它们具有四个不同的影响级别(高,中,低和信息性)。在我们的数据集中,这31种类型的漏洞中有30种存在。在静态代码分析中使用两个不同的分析器时,我们遇到的挑战之一是两个分析器之间的句法和语义上的差异。

表2 静态代码分析器检测到的安全漏洞
Code Security Problem Mythril Slither
1 Integer underflow x
2 Re-entrancy vulnerability with balance change x
3 Unprotected usage of selfdestruct x x
4 Contracts that lock ether x
5 Incorrect ERC20 interface x
6 Multiple calls in a single transaction x
7 Re-entrancy vulnerability without balance change x
8 Unprotected usage of tx.origin x x
9 Unused return x
10 Usage of low level calls x x
11 Exception state x
12 Local variable shadowing x
13 Assembly usage x
14 State variables that could be declared as constant x
15 Unindexed ERC20 event parameters x
16 Usage of complex pragma statement x
17 Built-in symbol shadowing x
18 Calls inside a loop x
19 Conformance to solidity naming conventions x
20 Constant functions changing the state x
21 Dangerous strict equalities x
22 Delegate a proxy call x x
23 External call to a fixed address x
24 Functions that send ether to arbitrary destinations x
25 Integer overflow x
26 Re-entrancy-vulnerability in general x
27 State variable shadowing x
28 State variable shadowing from abstract contracts x
29 Uninitialized local variables x
30 Uninitialized state variables x
31 Unused state variables x
32 Uninitialized storage variables x
33 Unprotected ether withdrawal x
34 Usage of deprecated standards x
35 Usage of different solidity versions x

标记Labeling

在此步骤中,使用先前静态代码分析器提取的36种漏洞被用来标记智能合约。如果静态代码分析器检测到漏洞,则我们将该漏洞标记为存在,否则标记为不存在。为了捕获差异,创建了五个新的安全漏洞,作为两个分析器检测到的安全漏洞的组合值。当任一分析工具报告存在该漏洞时,我们将组合值标记为存在;否则,我们将其标记为不存在。

分类Classification

选择了四个常用的监督二元分类器:支持向量机(Support Vector Machine,SVM),神经网络(Neural Network,NN),随机森林(Random Forest,RF)和决策树(Decision Tree,DT)来训练模型。由于安全漏洞彼此独立,因此分别为每个漏洞训练了二进制分类器,总共训练了184(4 * 46)个二元分类器。

四、结果和讨论

评估指标

  1. 首先定义以下几个概念

    1. TPTP(True Positive)真阳性:预测为正,实际也为正
    2. FPFP(False Positive)假阳性:预测为正,实际为负
    3. FNFN(False Negative)假阴性:预测与负、实际为正
    4. TNTN(True Negative)真阴性:预测为负、实际也为负
  2. 通过第一步的统计值计算每个类别下的precision和recall

    1. 精准度 / 查准率(precisionk=TPTP+FPprecision_k=\frac{TP}{TP+FP}):指被分类器判定正例中的正样本的比重
    2. 召回率 / 查全率 (recallk=TPTP+FNrecall_k=\frac{TP}{TP+FN}):指的是被预测为正例的占总的正例的比重
    3. 准确率(accuracy=TP+TNTP+FN+TN+FPaccuracy=\frac{TP+TN}{TP+FN+TN+FP}):代表分类器对整个样本判断正确的比重
  3. 计算结果计算每个类别下的F1-score,计算方式如下

    1. F1k=2×precisionkrecallkprecisionk+recallkF1_{k}=2\times \frac{precision_k·recall_k}{precision_k+recall_k}
  4. 通过对第三步求得的各个类别下的F1-score求均值,得到最后的评测结果,计算方式如下

    1. score=1nF1kscore=\frac{1}{n}\sum F1_k

评价结果

我们在表III中报告了实验结果。在此表的每一行中,我们列出了一个漏洞和基于上述指标产生最佳结果的机器学习算法。例如,Integer下溢由决策树算法识别,F1分数为86%,准确性为99%,准确性为100%,召回率为75%。模型在发现漏洞方面的合理准确性和精确度表明了利用机器学习在智能合约中查找安全漏洞的可能性。根据我们模型的结果,我们得出以下结论。

表3 安全漏洞检测的准确性
Code Security Problem Severity Method TN FP FN TP F1 Accuracy Precision Recall
1 Integer underflow High SVM 163 0 1 3 86% 99% 100% 75%
2 Re-entrancy vulnerability with balance change High NN 129 10 6 22 73% 90% 69% 79%
3 Unprotected usage of selfdestruct High DT 166 0 0 1 100% 100% 100% 100%
4 Contracts that lock ether Medium RF 130 0 6 31 91% 96% 100% 84%
5 Incorrect ERC20 interface Medium SVM 133 12 4 18 69% 90% 60% 82%
6 Multiple calls in a single transaction Medium DT 159 2 2 4 67% 98% 67% 67%
7 Re-entrancy vulnerability without balance change Medium DT 144 5 7 11 65% 93% 69% 61%
8 Unprotected usage of tx.origin Medium SVM 166 0 0 1 100% 100% 100% 100%
9 Unused return Medium DT 128 11 6 22 72% 90% 67% 79%
10 Usage of low level calls Medium DT 164 1 0 2 80% 99% 67% 100%
11 Exception state Low SVM 128 6 13 20 68% 89% 77% 61%
12 Local variable shadowing Low SVM 144 7 5 11 65% 93% 61% 69%
13 Assembly usage Informational NN 152 4 1 10 80% 97% 71% 91%
14 State variables that could be declared as constant Informational SVM 70 28 17 52 70% 73% 65% 75%
15 Unindexed ERC20 event parameters Informational NN 164 0 1 2 80% 99% 100% 67%
16 Usage of complex pragma statement Informational SVM 165 0 0 2 100% 100% 100% 100%

五、总结与评价

本篇论文对我蛮有启发的,其提出了一个很中肯的方案将机器学习的方法与智能合约结合起来。心理预想了一遍,感觉实现过程比较清晰:

  1. 从Etherscan上爬取合约,然后通过一些限制条件去除大部分智能合约。
  2. 对这些智能合约使用开源的SlitherMythril两个静态代码分析器检测是否存在漏洞。
  3. Solc(Solidity命令行编译器)从Solidity代码生成AST,然后从AST中提取特征,不过本文中并没有详细提到如何提取特征,只是提到了哪些特征。
  4. 再使用几种机器学习的方法进行建模,这里本中并没有详细提及如何建模:比如输入的特征是什么,怎么输入,输出是什么。只是把抄了一遍方法的最基本定义,不禁让人怀疑本文是如何做的。
  5. 其文中结论部分,精挑细选了一些结果,有些穿凿附会。