张 铮,张星娜,吕 卓,易龙杨,陈 岑,杨 文,常 昊,王 伟
(1.国网河南省电力公司电力科学研究院,郑州 450052;2.北京交通大学,北京 100044)
自2009年比特币问世以来,它的底层技术区块链显示出了广阔的应用前景,引起学术界和业界的广泛关注[1]。作为第一种加密货币,比特币在2015年被评为表现最佳的货币,2016年被评为表现最佳的商品,2017年5月,比特币每天的确认交易量超30万笔。与此同时,区块链技术也应用到很多领域,包括医学[2]、经济学[3]、物联网[4-6]、软件工程[7]等。比特币系统的创新之处在于它的共识协议,共识协议旨在使得相互不信任的节点对于执行交易的结果达成共识。比特币通常被称为区块链1.0,只提供支付服务。以太坊引入了图灵完备的编程语言,使得用户能够开发运行在区块链上的智能合约,这被称为区块链2.0时代的开始。不同用途的应用程序都可以建立在智能合约上,例如,商业服务[8]、医疗保健、数据安全交换与传输[9]等。以太坊是目前使用最广泛的支持智能合约的区块链[10],也是除了比特币之外最为成功的区块链应用。Szabo[11]首次提出智能合约,并指出“智能合约就是执行合约条款的可计算交易协议”。智能合约有以下特点:①自动执行,由交易触发,无需手动交互;②自动强制执行,一旦触发,智能合约的执行就无法阻止;③透明性,智能合约对于区块链网络的每个节点都是公开的,因为它们的正确性必须得到大多数节点的验证;④灵活性,智能合约可以满足不同场景的需求。智能合约的相关特性带来众多便利,也引发许多的挑战,其中安全问题是最关键的挑战之一。
以太坊是一种公共区块链平台,支持运行以太坊虚拟机(ethereum virtual machine,EVM),EVM上运行以太坊智能合约[12]。以太坊智能合约是一种自动化执行的合约,买方和卖方之间的交易协议条款可以写入智能合约代码中,其中的代码和协议存在于分布式、去中心化的区块链网络[13],代码控制执行的交易是可跟踪和不可逆的。虽然以太坊在语义上比比特币更丰富,但它也扩大了漏洞威胁面。由于它可以处理大量资金、数字资产或数据,漏洞可能导致重大问题,例如大量资金损失或隐私泄露。著名的以太坊众筹智能合约DAO[14]由于其代码的错误于2016年6月受到攻击,并造成6 000万美元的损失。攻击者利用了智能合约重入漏洞,递归调用simpleDAO函数以将以太坊加密货币ether转移到自己的帐户。已经部署在以太坊区块链上的相当一部分智能合约易受攻击,Luu等[15]使用名为Oyente的工具检测了19 366个以太坊智能合约,报告显示超过45%的合约是易受攻击的。2017年7月,parity钱包合约中的漏洞导致用户损失3 100万美元[16]。众多案件表明,编写安全的智能合约以及智能合约漏洞检测是区块链技术中艰巨且必不可缺的任务[17]。
本文中针对当前智能合约安全漏洞的检测率和检测性能较低的问题,提出了基于深度学习的智能合约漏洞检测方法。将以太坊智能合约源码转化为操作码序列,再对操作码序列进行分析,并设计适用于本方案的深度学习网络结构进行漏洞检测。最后,进行模型训练与测试。针对智能合约6种漏洞的检测,设计了循环神经网络(recurrent neural network,RNN)、长短期记忆神经网络(long short-term memory,LSTM)和卷积神经网络-长短期记忆神经网络(convolutional neural network-long short-term memory,CNN-LSTM)共3种不同的深度学习网络结构,其中,CNN-LSTM的Macro-F1达到了82.1%。大量的实验结果表明,提出的模型和方法可实现高效的智能合约漏洞检测。本文的研究内容及贡献归纳为以下2点。
1)提出了基于操作码序列的深度学习智能合约漏洞检测方法。将以太坊智能合约源码转化为操作码序列再进行数据分析,并设计适用于本方案的RNN,LSTM和CNN-LSTM共3种不同的深度学习网络结构进行漏洞检测,实验结果取得的精度达到有效检测漏洞的目标。
2)通过实时抓取和网上采集构建了多达47 527个以太坊智能合约漏洞数据集,并通过大量实验对智能合约漏洞检测方法进行验证。实验结果证明本文提出的方法可高效准确地检测出智能合约漏洞。
在深度学习领域,神经网络是一种非常具有表现力的学习模型,并且适用于序列数据[18]。针对以太坊智能合约操作码序列,设计了一系列深度学习智能合约漏洞检测方法,包括RNN,LSTM和CNN-LSTM。本文中所提出的基于操作码序列深度学习的智能合约漏洞检测方法的总流程如图1所示。
图1 操作码序列智能合约漏洞检测方法总流程Fig.1 General framework of smart contract vulnerability detection methods
通过爬取、采集、标签标注、源码编译和字节码解析过程得到数据集,再根据以太坊黄皮书中操作码与value对应关系,将操作码映射为16进制数据流,作为深度学习算法的输入。然后设计多种深度学习神经网络模型进行智能合约漏洞检测训练,最终得到漏洞分类模型。
与许多序列学习任务一样,智能合约漏洞检测涉及处理序列操作码数据。更准确地说,操作码是由机器解释的一系列数字,表示要执行的操作类型。在以太坊环境中,操作码是黄皮书中指定的一系列低级人类可读指令。机器指令语言由EVM处理,EVM是一种基于堆栈的体系结构,字长为256位,每个指令都定义了操作码、助记符、δ值、α值和一个描述。对于每条指令,α值是该指令堆栈上的附加项数,δ值是该指令在堆栈上所需的项数。爬取和收集可得到大量的以太坊智能合约solidity源码,经过编译得到智能合约的操作码数据流。以太坊黄皮书中对操作码进行了16进制的定义,该16进制数字值称为操作码的value,然后通过字典对操作码与其value的对应关系进行映射,调用python程序将操作码解析为操作码数据流序列,图2为智能合约16进制操作码样本的示意图。
图2 用作学习模型输入数据的样本操作码序列Fig.2 Sample opcode sequence used as input data to the learning model
根据本文所需场景设计RNN,LSTM和CNN-LSTM 共3种不同的深度模型进行漏洞检测,结构如图3所示。RNN模型[19]能够在输入的数据前后建立联系,并且保留前后输入的上下文,主要适用于文本序列处理。LSTM[20]是RNN的变体,减少了梯度消失或者爆炸发生的可能性,并且能够处理长期依赖问题。CNN[21]使用了核函数形成的权值共享机制,使得CNN的参数数量明显少于类似的全连接的神经网络,因此,CNN与LSTM结合得到的CNN-LSTM模型可以减少参数数量并防止信息丢失。
图3 深度学习漏洞检测模型Fig.3 Vulnerability detection model based on deep learning
1.2.1 循环神经网络模型
本文首先尝试使用RNN进行学习训练,RNN可以接受一系列输入并生成一系列输出值,从而使其对于需要处理序列输入数据的应用程序非常适用,在序列数据方面比CNN更有优势。在RNN中选择了优化算法门限递归单元(gate recurrent unit,GRU),它能更好地解决RNN的短期记忆问题。在本文中的RNN模型中,嵌入层之后连接2个GRU层,然后连接包含sigmoid激活函数的全连接层。
1.2.2 长短期记忆神经网络模型
LSTM是在RNN基础上改进的一种神经网络结构,属于一种特殊的RNN,它可以很好地解决操作码这种长序列在训练过程中的梯度消失问题。本文设计的LSTM与CNN采用了相似的结构,两种首先都是将操作码序列接入嵌入层处理。在RNN中,嵌入层之后连接2个GRU层,接着连接激活函数是sigmoid的全连接层,而在LSTM模型中将GRU层替换为LSTM层。由于每次均进行二分类,故最终的全连接层的输出维度均为1。
1.2.3 卷积神经网络-长短期记忆神经网络模型
在智能合约漏洞检测任务中,CNN和LSTM体现出不同的优势。单独的CNN通过卷积可提升训练速度,但是同时会导致信息丢失。因此,本文采用了CNN-LSTM模型,嵌入层输出不直接与长短期记忆层相连,而是先将其输入到一维卷积层中,再将序列特征输入长短期记忆网络中,由此提取上下文关联信息。由于卷积层的缘故,模型参数个数在原有几种模型上大大减少,降低了训练难度,也避免了参数过多引起的过拟合问题。
在本文中,选择数据集80%作为训练集,20%作为测试集。但是数据集不平衡会影响训练测试效果,可能导致评价指标不能准确体现所用算法模型的分类性能,因此不能将剩余20%直接作为测试集。为了平衡所用测试集,从10 000个智能合约中随机抽样选取样本,在多数类中抽取少数类样本数量的5倍,再将其与原留出的测试集合并在一起作为测试集。
为比较3种多标签分类器性能,我们进行了大量实验。采用F1-score和Macro-F1衡量分类器的性能,F1-score是一种用来评估二值分类器的度量指标,Macro-F1是一种评估多标签分类性能的度量指标。在计算这些指标时,每个类别权重相同,与类别和数量无关,表示所有标签分类各项指标的平均值,定义如下。
(1)
(2)
(3)
除了采用F1-score等评估指标之外,还使用了另一种衡量分类器输出性能的方法,即受试者工作特征(receiver operating characteristic,ROC)曲线。ROC曲线通常用于研究二元分类器的性能,曲线下面积(area under curve,AUC)越大,分类效果越好。横坐标轴为假正例率(false positive rate,FPR),纵坐标轴为真正例率(true positive rate,TPR)。其中,FPR代表所有负例中被错误预测为正样本的概率,即假警报率;TPR代表所有正样本中预测正确的概率,即命中率。数学定义分别为
(4)
(5)
研究以太坊智能合约数据可以产生许多有用的结论,因其承载大量的交易、账户和数据块以及作为智能合约开发的流行应用程序。研究以太坊的数据可以发现许多针对该平台及其智能合约的新攻击,但最近有一些关于以太坊的研究受到数据采集方法的限制,无法提供全面和精确的数据。为研究工作的顺利开展,从以太坊Etherscan网页爬取和网上采集智能合约源码,构建了智能合约漏洞数据集。
从Etherscan收集了47 527条智能合约真实数据,数据包含智能合约源码和合约地址等信息。对于数据集漏洞的标定,本文采用Oyente对所有合约进行漏洞标记,每个合约有6个标签,分别为V1,V2,V3,V4,V5和V6,数据集漏洞详细信息如表1所示。每个合约的6种漏洞标签彼此独立,智能合约样本多标签标注如表2所示,例如,一个具有多标签向量[1,0,1,0,0,0,0]的合约示例它具有第1和第3个漏洞,而一个具有多标签向量[0,0,0,0,0,0,0]的示例没有漏洞。数据集包含6种类型漏洞的以太坊智能合约。
表1 数据集详情Tab.1 Description of data sets
表2 智能合约样本多标签标注Tab.2 Multi-label tagging of smart contract samples
本实验在服务器(320 GByte内存,Xeon E5-2660,Ubuntu 18.04,Python 3.8)上搭建实验环境,深度学习库TensorFlow和深度学习顶层库Keras作为搭建深度学习漏洞检测模型的工具,人工编写训练模型和实验评估代码。基于智能合约操作码16进制数序列的3种深度学习检测模型的性能比较如表3所示,性能指标采用了1.3节介绍的F1-score和Macro-F1,3种深度学习多标签分类模型中取得了较好的性能,这可以归因于深度学习模型在处理长序列时的优势。特别是CNN-LSTM的Macro-F1达到82.1%,意味着可以较准确地识别整数下溢漏洞、整数上溢漏洞、未检查返回值漏洞、时间顺序依赖漏洞、时间戳依赖漏洞和重入漏洞。
表3 基于深度学习的3种分类模型性能比较Tab.3 Performance comparison of four classification models based on deep learning
在训练过程中,经过一维卷积的CNN-LSTM模型执行速度明显快于另外2种模型,性能能提升来自LSTM架构和卷积神经网络降维共同作用,其中网络结构训练参数如表4所示。为进一步分析CNN-LSTM模型,采用了ROC曲线研究分类器的性能,实验结果如图4所示,AUC表明分类效果优异。
从实验结果可以看出,经过训练的CNN-LSTM模型具有良好的检测性能。对于近5万多条智能合约数据中拆分出的的测试集数据,CNN-LSTM模型的测试Macro-F1达到了82.1%,这表明基于操作码序列的深度学习模型在智能合约漏洞检测方面取得了显著的检测效果。由于对序列模型语义信息的捕捉,智能合约漏洞检测可以达到较好的性能,这意味着深度学习可以应用于智能合约中的漏洞检测。
表4 卷积神经网络-长短期记忆神经网络模型结构和参数Tab.4 Structure and parameter of CNN-LSTM
图4 CNN-LSTM模型的ROC曲线Fig.4 ROC curve of CNN-LSTM model
构建了一种基于深度学习的智能合约漏洞检测方案,对智能合约源码编译与解析得到操作码,再根据以太坊黄皮书中操作码的value映射关系构建字典,将操作码转化为16进制数序列,将其作为深度学习分类算法的操作码输入序列。设计RNN,LSTM和CNN-LSTM共3种不同深度学习网络模型进行智能合约漏洞检测多标签分类训练。最终的实验结果表明,基于以太坊智能合约操作码序列的CNN-LSTM分类模型对以太坊智能合约的6种漏洞检测效果最好,整数下溢漏洞、整数上溢漏洞、未检查返回值漏洞、交易顺序依赖漏洞、时间戳依赖漏洞和重入漏洞的F1-score的值分别达到了0.87,0.84,0.83,0.82,0.80和0.75,Macro-F1达到了82.1%。因此,本文中我们提出的基于深度学习的智能合约漏洞检测算法,能够对智能合约漏洞有效检测,可以完成初始目标,使得基于深度学习构建可扩展的智能合约安全漏洞检测工具成为可能,更有助于提升区块链智能合约的安全。
尽管该方案能够取得较高准确率,达到有效检测目标,但仍有改进空间。未来的工作将会把此检测方案应用于其他类型的漏洞检测,并结合更优的检测方案构造更精确的智能合约安全漏洞检测工具。