智能合约(smart contract)是最早由Szabo[1]于1996年首次引入的概念, 它是一段以计算机指令方式实现的传统合约的自动化处理程序, 旨在以信息化方式传播、验证或执行合约的计算机协议. 智能合约设计的总体目标是满足合约条件, 最大限度地减少对可信中介的依赖. 近年来, 以以太坊[2]为代表的一批智能合约平台得到迅猛发展, 以太坊作为最流行的智能合约平台, 截止到2020年末地址数量已经超过1亿, 总市值超过1 000亿美元[3]. 除了开启全新的数字化经济商业模式, 智能合约已经在数字身份、物联网、供应链等多个领域得到应用, 同时也支持广泛的去中心化应用程序, 如钱包、预测市场、即时消息、博客、众筹等[4], 且前景广阔.
智能合约虽名曰“智能”, 其本质就是双方资产交易时触发执行的一段代码, 且并不“智能”, 其“智能”之处在于: 智能合约程序不只是一个可以自动执行的计算机程序, 它本身就是一个系统参与者, 对接收到的信息进行回应, 可以接收和储存代币, 也可以向外发送信息和代币[5]. 智能合约由高级编程语言(如Solidity[6])编写, 然后编译成支持图灵完备指令集的虚拟机(如EVM、WASM等)字节码, 并发布到支持运行智能合约的系统上[7], 智能合约一旦发布成功, 任何人都无法修改其代码或阻止其执行, 即不可逆性[2]. 智能合约和传统的软件程序一样, 其代码也可能存在漏洞问题[5], 由于智能合约所关联的巨额数字资产和其不可逆性, 其代码中的漏洞容易被攻击, 这将造成不同程度的数字资产损失, 可能会造成灾难性的后果[8]. 2016年, 以太坊上的DAO项目遭到黑客攻击, 攻击者利用项目中存在的重入漏洞窃取了当时市值5 000万美元的360万个以太币[9]; 2017年6月, 攻击者利用Parity签名钱包使用的库合约漏洞, 偷取了当时市值3 000万美元的以太币[10]; 同年11月, Parity钱包新版本的漏洞永久性冻结了当时价值1.5亿美元的以太币[11]; 2021年8月, 黑客通过漏洞盗取了当时价值6 000万美元的加密货币[12].
智能合约的漏洞问题会带来巨大的经济损失, 然而智能合约的不可逆性使得其代码漏洞问题在其发布之后无法被修复, 这对智能合约的可靠性提出了更高的要求. 为此, 智能合约漏洞检测技术应运而生, 其旨在发布智能合约之前, 从智能合约中有效地检测出潜在的代码安全漏洞, 以提高智能合约的可靠性. 近年来, 研究者们探索利用软件测试、程序分析和机器学习等各种前沿技术研究了多种多样的智能合约漏洞检测技术, 并取得了可观的效果. 为了对智能合约漏洞检测技术的研究进展进行系统地归纳总结和分析比较, 本文整理了自2014年以太坊发表以来智能合约漏洞检测研究的相关论文发表情况并进行了梳理. 我们采用知网、谷歌学术、ACM Digital Library、IEEE Explore、Springer、Elsevier与DBLP等文献搜索引擎和数据库, 先使用“smart contract”作为检索关键词查找出所有智能合约相关论文, 而后依据“security”“vulnerability”“vulnerable”“reliability”“reliable”等关于可靠性、安全性的关键词通过对文章题目、摘要、引言等信息的检阅, 人工过滤掉了与智能合约漏洞检测的无关论文, 最后从1 031篇智能合约论文中收集到了84篇智能合约漏洞检测技术的相关论文.
图1展示了2014年至2021年7月每年关于智能合约和智能合约漏洞检测的论文发表统计情况. 图中数据表明, 在2016年出现DAO攻击后, 关于智能合约的研究逐年暴增, 智能合约漏洞检测也成为一大研究热点, 且研究热度在不断增加. 为此, 我们进一步对论文的发表情况进行了统计, 相关论文主要发表在软件工程领域和网络信息安全领域的各类高质量会议和期刊上. 软件工程领域包含会议ICSE (4篇)、FSE/ESEC (2篇)、ASE (4篇)、ISSTA (3篇)、PLDI (1篇)、ISSRE (1篇)、SANER (2篇)、EASE (2篇)、APSEC (1篇)、ATVA (1篇)、ICFEM (1篇)、ICECCS (1篇), 期刊TSE (1篇)、TSC (1篇)、SPE (1篇), 共计23篇会议论文, 3篇期刊论文; 网络信息安全领域包含会议CCS (4篇)、S&P (2篇)、USENIX (3篇)、NDSS (2篇)、ACSAC (2篇), 期刊TIFS (1篇), 共计13篇会议论文, 1篇期刊论文; 另有3篇文章分别发表在人工智能领域的会议IJCAI、数据挖掘领域的期刊IPM和交叉领域的会议FCS上. 依据中国计算机学会(CCF)推荐的学术会议和期刊分类, A类会议24篇、A类期刊2篇、B类会议7篇、B类期刊3篇、C类会议7篇. 其他未被列入CCF推荐期刊/会议文章41篇, 其中有19篇未经同行评审直接公布在开放电子论文库arXiv上, 非CCF推荐期刊/会议(即“other”分类)文章22篇(包括Workshop文章4篇).
图 1 论文年份分布图
目前已有关于智能合约漏洞检测技术研究进展的分析与总结工作, 付梦琳等人[13]在2019年就对智能合约面临的安全威胁与主流的智能合约漏洞检测手段进行了分析和总结, 此后又有多篇相关综述文章发表[14,15]. 上述工作处于智能合约漏洞检测初步阶段, 主要对2020年之前的相关研究进行了调查与介绍, 这些文章主要综述了智能合约的漏洞问题, 对智能合约漏洞检测技术的分析过少, 对智能合约漏洞检测技术中的数据也未进行全面梳理, 尤其没有对国内外的研究现状进行对比分析. 图1中的统计数据表明, 智能合约漏洞检测技术的研究在2019年与2020年得到了迅猛发展, 例如, 采用诸如模糊测试、污点分析、形式化验证等方法的漏洞检测技术不断被提出, 且机器学习也被应用到智能合约漏洞检测中. 因此, 本文旨在对目前已有的智能合约漏洞检测技术进行一个全面的分析与总结, 对已有技术进行系统分类, 并从实现方法、漏洞类型、实验数据等统计信息展开分析, 此外, 基于目前该领域的研究现状, 本文对该领域面临的挑战以及研究的可行思路进行了探讨.
综上所述, 本文的主要贡献如下.
(1) 依据每篇论文作者单位的国别分类, 对国内外智能合约漏洞检测技术的研究进展进行系统的对比分析和介绍.
(2) 根据智能合约漏洞检测的核心技术对已有的研究工作进行了分类.
(3) 总结了该领域的开源工具.
(4) 分析对比了国内外的研究现状, 以促进国内在该领域的研究.
(5) 对当前智能合约漏洞检测技术所面临的挑战进行了系统梳理, 并总结了未来可能的研究方向.
1 相关工作
伴随着智能合约技术的发展及其应用领域的增加, 越来越多的安全漏洞被攻击者发现并利用, 催生了一批关于智能合约生态安全的研究, 目前已有一些关于这批智能合约安全文章的调研与综述, 包括安全漏洞审查[5, 16-20]、设计模式[21-24]、验证方法和工具[13-15, 25-32]、形式化规范与建模技术[33-35]和智能合约平台[36,37]与开发语言[38,39]等方向[40-46], 本节总结了当前关于智能合约安全分析和漏洞检测的调研与综述.
Atzei等人[5]和一些最近的工作[16-20]收集并各自分类了多种可能危及智能合约安全的常见漏洞模式; Permenev等人[47]和Bernardi等人[48]定义了安全分析师在合约审计时应该注意的几类属性; 其他研究人员提出了几种智能合约的设计模式[21-24], 是一种旨在针对特定任务的合约开发过程中, 通用且可重用的解决方案.
Bartoletti等人[36]比较了6种平台: 比特币、以太坊、Counterparty、Stellar、Monax和Lisk; Seijas等人[37]讨论了比特币、Nxt和以太坊等系统采用的语言, 并列出了这些语言的缺陷, 此外, 他们还指出了一些可能有助于扩展智能合约功能并加强其安全性的技术; Parizi等人[38]和Harz等人的最近一份研究[39]则对比现阶段智能合约编程语言之间性能与安全方面的差异, 并简要介绍了一些检测方法.
Durieux等人[30]在两个数据集上运行并对比了SmartCheck、Slither、Securify、Oyente、Osiris、Mythril、Manticore、MAIAN、HoneyBadger这9个工具, 两个数据集一个包含69个带注释的漏洞合约, 另一个数据集则是Etherscan上获取到的47 518份合约. Praitheeshan等人[25]和另外几项研究[26-32]则对智能合约存在的漏洞检测技术进行了调研, 并介绍和对比了部分智能合约漏洞检测技术的各种特性.
同时, 国内也有一些研究[13-15]对智能合约当前漏洞分类、检测技术现状与未来发展进行了调研. 付梦琳等人[13]和倪远东等人[14]分别于2019年和2020年调研分析了智能合约面临的安全威胁, 并讨论了主流的智能合约漏洞检测手段, 钱鹏等人[15]于2020年从形式化验证、符号执行、模糊测试、中间表示和深度学习这5类方法综述了智能合约漏洞检测技术的进展, 并对现有方法的可检测漏洞类型、准确率、时间消耗等方面进行了对比分析.
上述关于智能合约漏洞检测技术的研究存在发表年份过早[13,14]、检测技术过少[13,14]、检测技术信息分析不全面[13-15]等问题, 与上述讨论的综述不同, 我们的调研包含了当前智能合约漏洞检测领域的大多数技术, 并对它们进行了系统性地分类, 同时总结了该领域的开源工具网页链接, 分析了现有技术的实现方法、漏洞类型、实验数据等信息, 并首次对比了国内外技术的研究现状, 最后讨论了智能合约漏洞检测技术当前面临的挑战以及未来可行的研究方向. 我们相信, 这项工作可以帮助研究人员从各方面对现存的漏洞检测技术有一个更为全面的认知.
2 智能合约漏洞检测方法综述
本节基于收集到的84篇智能合约漏洞检测技术论文, 依据其所采用的核心方法, 从已有的智能合约漏洞检测技术中提炼出以下6大类: 基于符号执行、基于模糊测试、基于污点分析、基于形式化验证、基于机器学习的漏洞检测技术和其他技术. 如果一种技术使用了多种方法, 我们根据文章中自己强调的核心方法对其进行分类.
2.1 基于符号执行的智能合约漏洞检测
基于符号执行的智能合约漏洞检测技术将合约程序的变量值抽象成符号输入, 运行过程中的所有变量到达目标代码时都会由符号相关的函数组成符号路径, 每个符号路径都有一个路径约束, 通过约束求解器分析相应的路径约束和约束关系, 从而检测出合约中的漏洞问题[49]. 2016年, Luu等人[50]提出的Oyente是第1个智能合约漏洞检测技术, 也是第1个提出利用符号执行技术进行智能合约漏洞检测. 该工具首先构造出合约的控制流图, 从控制流图的入口节点开始, 执行符号状态, 并利用Z3求解器循环获取要运行的状态, 产生对应的符号路径. 最后根据对4种漏洞定义好的一套属性来分析符号状态和符号路径, 从而检测智能合约中的安全漏洞, 并通过求得的约束进行可达性检验降低误报率. 分布式的区块链计算平台需要一定的计量标准来避免拒绝服务攻击和资源持续占用的交易, 以太坊采用gas机制作为计量标准, 节点在运行智能合约时, 如果gas不足, 智能合约会恢复到运行之前的状态, 该机制同样引进了一些以太坊平台独有的漏洞类型. 2017年, Chen等人[51]针对智能合约的高gas消耗问题, 在Oyente的基础上, 根据预先定义的7种导致额外成本的编程模式, 提出智能合约高gas消耗检查工具Gasper.
2018年, Tsankov等人[52]提出了一种基于符号抽象的轻量级、可扩展合约分析工具Securify, 可根据用户定义的安全属性检测合约的行为是否安全. Securify从字节码开始符号化地分析代码中数据流和控制流依赖等信息, 提取出精确的语义事实, 并使用基于逻辑的编程语言Datalog描述语义事实. 之后, Securify将其与预先定义好的安全属性规则进行检查, 其中安全属性规则分为合规(compliance)模式和违反(violation)模式, 通过语义事实与两种模式的匹配情况检测合约的安全性.
2018年, Krupp等人[53]提出了基于符号执行的漏洞检测与漏洞利用技术teEther. teEther先从字节码构造的控制流图中找出到达4种敏感指令的关键路径, 然后从控制流图根节点进行符号执行获取到达关键路径的路径约束, 最后, 使用Z3约束求解器解决关键路径和状态更改路径的组合约束来产生漏洞利用样例, 并检测出合约中的漏洞. teEther工具同时实现了漏洞检测和漏洞的自动利用, 但其局限性在于只支持检测单个合约内的易受攻击漏洞, 并需要对这些漏洞预先建立通用定义, 而不能发现调用其他合约产生的漏洞.
2018年, Nikolić等人[54]借助符号执行分析与依据具体路径值验证执行的方法, 提出了检测痕迹(trace)漏洞的MAIAN. MAIAN将智能合约划分为贪婪合约(greedy contract)、浪费合约(prodigal contract)和自杀合约(suicidal contract)这3种类型, 并定义了痕迹特性的活性(liveness)与安全性(safety), 再由符号执行引擎对智能合约字节码的所有路径进行符号分析, 检测是否存在违反痕迹特性活性或安全性的路径. 为了有效地降低漏洞检测结果的假阳性, MAIAN还会根据求解出的路径条件具体值执行合约, 依据执行结果消除因路径不可达导致的部分假阳性案例.
2019年, Mossberg等人[55]实现了一款基于符号执行的动态二进制分析工具Manticore. Manticore 将合约的执行过程抽象为: 就绪(ready)、忙碌(busy)、终止(terminated)这3个状态, 状态之间可以进行转换. 当符号变量需要被转换为一个或多个具体值时, 就会有一个相应的就绪状态被创建并处理, 在程序退出或发生异常时终止. 其通过符号执行枚举出合约的所有可到达执行状态以及触发这些路径的输出参数, 达到验证关键功能安全性的效果, 标记出整数溢出、未初始化内存等安全问题. Li等人[56]实现的Solar就是基于Manticore.
蜜罐合约是一种假装将其代币泄露给任意用户(受害者), 用户向其发送额外代币时用户提供的代币将被困住的智能合约. 2019年, Torres等人[57]首次对蜜罐合约进行系统分析, 并提出了基于符号执行和启发式算法的蜜罐合约检测工具HoneyBadger. 其主要由3部分组成: 符号分析、现金流分析和蜜罐分析. 符号分析基于Oyente构造出的控制流图, 由符号执行将程序变量的值表示为符号表达式, 并将分析结果传播到现金流分析组件和蜜罐分析组件; 现金流分析用于检测合约是否能够接收和转移资金; 而蜜罐分析则结合启发式算法和符号分析的结果来检测预定义的蜜罐问题. 这3步都使用Z3 求解器来求解公式.
2020年, He等人[58]提出了第1个用于检测EOSIO平台上智能合约漏洞的系统分析框架EOSAFE. 其先为WASM字节码实现一个符号执行引擎, 然后通过应用启发式引导剪枝方法来缓解路径爆炸问题; 其次, 为了分析EOSIO智能合约并模拟其外部交互环境, 实现了一个模拟器来模拟关键EOSIO库特征的行为; 最后, 提出了一个通用的漏洞检测框架, 并实现了4个扫描器, 旨在检测4个重要的漏洞, 包括虚假EOS, 虚假收据, 回滚(rollback)和缺失权限检查(missing permission check), 该框架同时允许安全分析人员将自己的漏洞扫描器实现为插件.
符号执行是目前智能合约漏洞检测的主要方法之一, 其通常先将合约中的变量值符号化, 然后在逐条解释执行程序中指令的过程中, 更新执行状态、搜集路径约束, 以完成程序中所有可执行路径的探索并发现相应的安全问题, 但也存在路径爆炸与约束求解难等问题[49].
2.2 基于模糊测试的智能合约漏洞检测
基于模糊测试的智能合约漏洞检测技术通过随机地构造出非预期的测试输入数据, 对智能合约进行大量测试来发现其中的漏洞. Jiang等人[59]在2018年提出的ContractFuzzer是第1个采用模糊测试方法的智能合约漏洞检测技术. 其首先对智能合约的应用程序二进制接口(application binary interface, ABI)和字节码(bytecode)进行静态分析, 提取出ABI函数签名和参数数据类型; 同时也对以太坊中收集的智能合约做同样的静态分析; 然后根据分析结果和预定义的测试预言(test oracle)生成测试输入; 最后进行测试并分析EVM记录的合约执行过程中的指令调用、合约状态等信息来检测合约中的漏洞. 2020年, Huang等人[60]利用的类似的技术对EOSIO智能合约提出了黑盒模糊测试技术EOSFuzzer. Ashraf等人[61]提出的GasFuzzer是建立在ContractFuzzer的基础上, 专门面向gas异常的模糊测试检测.
由于以太坊智能合约在接收以太时会触发独特的回调(fallback)机制, 使得存在函数执行结束前再次进入被调函数的可能, 该操作可能导致合约执行危险操作, 此类因以太坊回调机制导致的函数被重复进入的漏洞称为重入漏洞(re-entry). Liu等人[62]针对智能合约中的重入漏洞提出了ReGuard, 利用智能合约的抽象语法树(abstract syntax tree, AST)和控制流信息将合约翻译成行为一致的C++合约, 再依赖成熟的模糊测试引擎生产随机的交易对翻译后的合约进行测试, 并根据有限状态机的机制分析测试过程中的实时运行轨迹来检测重入漏洞.
以太坊网络中每个区块都设定了gas上限, 如果交易花费的gas超过上限会导致交易失败, 这一问题被称为out-of-gas漏洞. Ma等人[63]基于反馈指导的模糊测试技术, 提出了一种依据加权控制流图生成高gas消耗, 进而检测out-of-gas漏洞的技术GasFuzz. GasFuzz为传统控制流图中包含的每个节点赋予一个 gas 消耗权重, 定义为加权控制流图, 然后GasFuzz根据智能合约函数参数生成一个初始变异种子, 在变异策略的指导下从种子生成变异数据, 根据初始变异数据EVM运行时的gas消耗与遍历路径的信息反馈导向选择出新的种子, 并从新的种子生成新的变异数据, 直到用户设置的持续时间结束或用户想要停止该过程.
2019年, Kolluri等人[64]则针对智能合约中的事务顺序bug (event-ordering bug)提出了符号执行和模糊测试相结合的检测技术EthRacer. 其先用符号执行技术分析合约的事件路径, 推理出每个事件的符号路径约束和先行发生关系(happens-before relation), 并通过消除符号路径约束中的不可达路径减小路径约束的假阳性; 然后将分析的事件路径随机模糊出更多的事件路径组合, 通过测试这些事件路径来检测出事务顺序bug.
2020年, Nguyen等人[65]针对智能合约生成高效测试用例的问题(即高效地覆盖更多分支), 提出了基于反馈指导的适应性模糊测试技术sFuzz. sFuzz先从已有的合约交易信息中初始化初始的测试输入, 然后监控初始测试的执行过程, 并根据反馈信息将AFL的适应性函数(fitness function)和一个轻量级的多目标搜索策略相结合, 来优化测试种子的生成, 从而提高测试智能合约的代码覆盖率和效率.
2020年, Grieco等人[66]从方便配置和使用、高覆盖率和高检测速度的角度出发, 根据检测合约是否会违背预先定义的用户自定义属性、断言和gas预估值, 提出了智能合约模糊测试工具Echidna. 测试种子的生成与ContractFuzzer类似, 不同点在于测试预言是预先定义的用户自定义属性、断言和gas预估值.
Wüstholz等人[67]针对智能合约提出了灰盒模糊测试技术Harvey. 它属于定向的灰盒模糊测试技术, 先通过程序插桩技术捕捉更多的合约代码结构信息和逻辑覆盖信息, 并计算最优执行到不同程序点的距离, 该距离用于模糊测试时的种子优先度、能量调度和适应性变异, 预测出满足代码覆盖率高的测试种子, 以达到定向测试的目的.
2020年, Zhang等人[68]提出了一种采用污点分析方法来优化模糊测试种子生产的智能合约漏洞利用技术EthPloit. EthPloit先构造出Solidity源代码的控制流图, 依据污点分析得到源代码中变量数据与变量控制流间的依赖关系; 然后基于SOLC编译出的源代码字节码和ABI产生初步的测试用例; 接下来根据污点分析的依赖关系和上一轮模糊测试产生的反馈结果, 进一步优化模糊测试用例; 最后EthPloit运行测试用例并进行痕迹分析(trace analysis).
尽管模糊测试存在测试用例生成低效、漏洞定位复杂等缺陷, 但因其高效多产的漏洞发掘能力应用广泛, 目前主要研究热点是通过符号执行、污点分析以及新兴的机器学习技术, 获取到更多程序运行时的数据依赖信息, 生成高度结构化的测试用例, 提高模糊测试的路径覆盖率与漏洞发掘的效率[64, 68].
2.3 基于污点分析的智能合约漏洞检测
污点分析的一般流程为: 首先识别污点信息在智能合约中的产生点并对其进行标记; 然后按照实际需求和污点传播规则进行前向或后向数据依赖分析, 得到污点的数据依赖和被依赖关系的指令集合; 最终在一些关键的程序点检查关键的操作是否会受到污点信息的影响[69].
最早使用污点分析方法进行智能合约漏洞检测的是Rodler等人[70]于2018年提出的Sereum, 一种在扩展的EVM客户端保护合约免受重入攻击的技术. Sereum首先修改了geth的字节码解释器, 修改后的解释器会维护一个影子内存以存储与实际数据值分离的污点; 然后污点引擎会检测从存储读取到条件跳转指令中处理条件的任何数据流, 并对于每一次交易的执行, 记录控制流做决策的变量; 最后Sereum通过引入一组锁, 禁止进一步更新这些变量, 如果对合约的调用尝试更新这些变量之一, Sereum会报告重入漏洞并中止交易.
2018年, Torres等人[71]提出了一种结合符号执行和污点分析用于检测以太坊智能合约中整数bug (与整数错误相关的安全漏洞)的框架Osiris. Osiris先基于Oyente的符号执行组件构造出合约的控制流图并执行路径信息, 这些信息被传递给污点分析组件和整数bug检测组件; 污点分析组件检查符号执行的每条指令是否是定义污点源列表的一部分, 并在堆栈、内存和存储之间引入和传播污点; 最终由整数错误检测组件检查在执行的指令中是否可能存在整数错误.
2020年, Brent等人[72]提出了一种利用污点分析的数据无害处理技术Ethainter, 对智能合约中的数据信息流进行分析. 他们设计了一种用于捕获智能合约信息流语义的小型抽象输入语言: 拥有污点源和汇聚点, 通过抽象语言的各种操作进行变量间的数据传输、加载和存储到持久存储上, 最后根据预定义的信息流规则来捕获复合漏洞.
2020年, Ashouri[73]则将污点分析和符号测试结合起来, 提出了一种能够识别智能合约漏洞并利用漏洞触发未知错误的技术Etherolic, 依据污点分析的数据为测试合约中的易受攻击代码段生成触发漏洞的交易来发掘合约中的漏洞.
污点分析的核心是追踪系统中不可信数据或敏感数据是否进入污染汇聚点进而对程序造成危害, 是程序鲁棒性检验与漏洞挖掘的关键技术之一, 但其仍存在一定缺陷, 如污染传播过程中内存存储信息的处理, 信息流分析不全面造成的欠污染与过污染等问题, 因而在实际应用中, 其往往会结合符号执行、模糊测试等其他程序分析技术[69].
2.4 基于形式化验证的智能合约漏洞检测
形式化验证技术是一种验证程序是否符合预期设计的属性和规范的技术, 其使用严谨的数学语言和逻辑描述智能合约, 以便对其进行严格的数学推理和验证[74]. 形式化验证技术中, 对智能合约指令和逻辑形式化描述是验证的前提, Bhargavan等人[75]于2016年的工作最先尝试将以太坊指令形式化描述成具有交互式证明功能的函数编程语言F*, 再基于此语言进行程序验证. 为了对智能合约指令进行形式化描述, 还有多个研究[76,77]致力于构建一个形式化描述的以太坊虚拟机.
对智能合约的形式化描述只是形式化验证的第1步, 一些研究工作已经开始关注在形式化描述的基础上, 对智能合约的安全性展开证明. Grishchenko等人[78]在用F*语言形式化描述以太坊指令的基础上, 定义了外部调用完整性、原子性、可变账户独立性和交易环境独立性4个通用安全属性并进行了证明.
2017年, Grossman等人[79]提出了一种检测有效回调自由合约的技术. 他们先是使用SMAC语言形式化描述了智能合约模型与该模型下的合约属性和行为, 然后在模型中定义的通用客户端对有效回调属性进行了分析, 并使用分析结果动态执行合约, 来验证合约中存在的有效回调属性. 而Wang等人[80]于2019年提出的NPChecker主要关注的是其构造的智能合约模型中不确定因素对合约代币转移的影响, 其主要贡献在于通过分析因不可预测的事务调度与外部被调用者的行为而造成的读写风险, 最终实现检测智能合约中的不确定性支付漏洞.
2018年, Albert等人[81]基于Oyente提出了以太坊字节码分析框架EthIR, 他们将字节码反编译成了一种基于规则的表现形式(rule-based representation, RBR), 以便在高层级上推理EVM字节码的属性. EthIR在Oyente生成的控制流图上定义了一系列的转换规则, 将EVM字节码的高层级控制流图和数据流图重构成了RMR, 再使用SACO分析器[82]推理了字节码的大量属性. 2019年, Albert等人又基于EthIR, 通过推理智能合约上所有公共函数的gas使用上限, 实现了检测out-of-gas漏洞的GasTap[83], 同年, Albert等人提出的SAFEVM[84], 将EthIR生成的RMR递归地翻译成带有SV-COMP格式验证注释的抽象整数C程序, 并使用3个C语言验证器CPAchecker[85]、VeryMax[86]和SeaHorn[87]验证了合约的安全性.
2018年, Kalra等人[88]提出了一个验证智能合约正确性(correctness)和公平性(fairness)的框架Zeus, Zeus结合了抽象解释和符号模型检验的方法对智能合约进行自动的形式化验证. 为了准确地编码字节码的执行语义以及正确地推理合约行为, Zeus先借助污点分析构造出合约正确性与公平性的形式化规范, 再将其抽象解释到低层级的中间表示形式(intermediate representation, IR), 然后通过静态分析IR的特性确定验证谓词需要被断言的点, 最后将插入断言的IR与受约束的霍恩子句作为模型验证引擎的输入, 验证合约的正确性与公平性.
2020年, Permenev等人[47]提出了第1个能验证智能合约函数特性的自动验证器VerX, 为了解决验证智能合约时间属性的难题, VerX将智能合约与要验证的时间属性转换成可达性检验属性, 通过分析用户、函数参数、函数的随机组合, 推理合约行为是否符合归纳的可达性检验属性, 并通过符号执行和谓词抽象组成的延迟谓词抽象技术, 扩大可达性检验属性的状态空间, 达到降低漏洞检测假阳性的效果.
2020年, So等人[89]通过分析智能合约中的交易不变量, 实现了一个针对算术安全的高准确率与高召回率验证器VeriSmart. 其方法是先将程序分解成一系列包含验证条件的基本路径, 再检查当前基本路径中的候选不变量是否具有归纳性并且足够证明其查询的安全性, 然后将未证明安全性的不变量集作为反馈生成新的候选不变量集, 基于该反馈机制就形成一个迭代循环, 不断完善不变量集的分析结果, 直到证明程序是安全的或给定的时间预算用完为止.
2020年, Frank等人[90]针对现存智能合约漏洞检测技术缺少精确的内存模型与仅部分支持合约间分析的问题, 提出了基于符号执行的有界模型检验技术EthBMC. EthBMC针对智能合约分析过程中存在的哈希函数解析、内存操作与合约间调用难题, 构造了以太坊虚拟机的抽象状态机, 再由符号执行引擎搜索该抽象状态机下程序执行的状态空间. 当存在满足状态机停止状态(halting state)与实现攻击模型的路径时, 求解出满足该路径条件的具体输入, 并通过在私人以太坊网络上验证该漏洞的存在, 达到降低智能合约漏洞检测结果假阳性的效果.
2020年, Schneidewind等人[91]基于以太坊虚拟机字节码语义抽象解释出的霍恩子句, 提出了一个分析框架HoRSt, 并在该框架上实现了分析工具eThor. 他们先是基于霍恩子句对字节码进行抽象, 并在抽象解释出的霍恩子句层面形式化描述了智能合约的行为属性, 然后实现了一个基于霍恩子句的分析框架HoRSt, 并依据霍恩子句的数学规范在HoRSt上实现了分析工具eThor.
形式化验证通常在抽象层次上, 以形式化规范语言描述智能合约的行为和属性, 再运用严格的数学逻辑进行推理, 以检测智能合约是否符合预期设计的功能要求, 是最严谨的智能合约安全验证技术, 但其自动化程度相对较低, 且无法动态分析, 缺乏了对漏洞检测结果的可达性检验, 会产生较高的误报率[13].
2.5 基于机器学习的智能合约漏洞检测
机器学习使用已有的数据让计算机模拟或实现类似人类的学习行为, 来不断优化计算机程序的性能, 在智能合约漏洞检测领域也有一定程度的应用. 2018年, Tann等人[92]提出了一种使用长短期记忆网络的机器学习方法对智能合约弱点进行顺序学习的技术. Tann等人使用代码向量对智能合约操作码序列进行建模, 当给定一组智能合约操作码数据时, LSTM模型会学习由嵌入算法初始化后的向量关系. LSTM模型从MAIAN检测的结果中选出相同数量的分别标注为有漏洞合约与无漏洞合约作为训练数据集, 构建好的LSTM模型将会使用二元分类的方法将被检测智能合约标记为有漏洞与无漏洞两种类型. 2021年, Hu等人[93]同样训练了一个用于检测智能合约漏洞的LSTM模型, 不同的是, Hu等人的数据预处理阶段是人工地从以太坊交易行为中提取出4种行为模式与14个基础特征, 并设计了一种数据切片技术解决数据集不足的问题.
2018年, Liu等人[94]提出了一种结合N-gram语言建模和轻量级静态语义标签的语义感知安全审计技术S-gram. S-gram的工作方式由模型构建阶段和安全审计阶段两个阶段组成, 在模型构建阶段, S-gram基于N-gram的训练引擎, 使用从合约数据集中解析出的带有语义元数据标记的字符序列, 训练出S-gram的语言模型. 而在安全审计阶段, 检测器基于上一阶段训练的S-gram语言模型, 扫描审计目标合约的令牌序列以识别不规则的子序列作为候选漏洞. 类似地, 2021年, Hu等人[95]则使用GRU神经网络模型从智能合约字节码的N-gram特征中, 训练了一个检测智能合约是否存在漏洞的分类器.
2019年, He等人[96]为了解决模糊测试种子生成的低效难题, 提出了一种使用神经网络在符号执行的数据集上训练模糊测试策略的技术ILF. ILF通过使用路径覆盖引导的符号执行引擎提高了程序分支的覆盖率, 大量符号执行的结果将作为神经网络架构的训练数据集, 再由训练后的神经网络架构使用学习到的模糊策略为测试程序生成输入序列, 最后, 对该合约进行模糊测试并生成测试结果.
2020年, Gao等人提出了一种基于词嵌入和向量空间的技术SmartEmbed[97], 可用于智能合约的漏洞检测和合约验证. SmartEmbed先从AST中提取出合约的符号流, 再使用词嵌入算法将符号流映射到固定维度的向量, 通过堆叠单个向量可以得到合约代码的嵌入矩阵, 最后通过相似度阈值的设定提高漏洞检测的准确率. SmartEmbed会将合约与数据库中的漏洞合约进行相似度比较, 然后依据检测结果生成漏洞检测报告. 与此类似, 2021年, Huang等人[98]与Ashizawa等人[99]也训练了一个用于漏洞代码相似度检测的机器学习模型, 不同的是, Huang等人使用的合约向量表示形式是借助图嵌入算法从控制流图中获取, 而Ashizawa等人则是通过PV-DM模型[100]得到.
2020年, Zhuang等人[101]提出了一种使用图神经网络进行智能合约漏洞检测的技术. 主要由图生成阶段、图规范化阶段和消息传播网络3个阶段组成: 图生成阶段将智能合约函数公式化为合约图, 并为不同的程序元素分配不同的角色; 而图规范化阶段则通过节点消除算法来规范化不同合约生成的合约图, 以便图神经网络的训练; 消息传播网络阶段时间消息传播网络将按合约图中边的时间顺序依次沿边传递信息, 并使用一个聚合所有节点最终状态的读出函数为整个图计算一个标签, 得到合约漏洞检测结果.
2021年, Eshghie等人[102]提出了一个针对重入漏洞的框架Dynamit, 不同于其他技术, Dynamit不需要智能合约的代码, 只需要来自以太坊系统中的交易元数据和余额数据, 就可以训练出一个检测合约中重入漏洞的分类器. Dynamit从交易信息中提取出机器学习模型需要的交易gas使用、合约余额差额、平均栈调用深度3种特征, 再使用6种机器学习算法训练出了6种分类器, 最后分析了各种机器学习算法下分类器的假阳性、假阴性、召回率和准确率等数据.
2021年, Lutz等人[103]针对当前基于机器学习的检测技术存在的可扩展性能不佳的现状, 提出了通用且可扩展框架Escort, 其基于深度神经网络实现了多种漏洞类型的检测, 并支持轻量级的迁移学习用于检测未知漏洞. 深度神经网络训练阶段, 已标记漏洞类型的智能合约字节码经过编码层、全连接层、Dropout层、GRU/LSTM层等多层神经网络的处理, 最终在分支层实现了多个并行的神经网络层, 每个神经网络层都会训练出一种漏洞类型的检测器. 迁移学习阶段, 则通过在原来的深度神经网络上添加新的分支层, 从新漏洞类型的样本中训练出新的漏洞检测器. 2021年, Mi等人[104]提出了同样基于深度神经网络的智能合约漏洞检测框架VSCL, 相较Escort, VSCL少了一个用于检测未知漏洞的迁移学习阶段.
从2018年以来, 越来越多的机器学习算法应用于智能合约的漏洞检测, 与传统漏洞挖掘方法相比, 引入机器学习技术可以缓解传统方法耗费的大量人力与误报率和漏报率较高的问题, 也适应大规模复杂软件系统的应用场景, 但其对数据集和算法的依赖也带来了源码语义建模不足和检测结果可解释性较差等难题[15].
2.6 其他方法
对合约代码抽象语法树、控制流图或自定义中间表示形式的静态分析以及基于代码克隆检测、攻击向量、入侵检测系统等难以归类的方法被分类为其他. 2018年, Tikhomirov等人[105]对Solidity代码存在的漏洞进行了系统性分类, 并提出了一个可扩展的静态分析工具SmartCheck, 允许用户使用自定义模板分析合约是否存在漏洞. SmartCheck根据Solidity的语法规则使用ANLTR[106]生成了源代码的XML解析树作为中间表示形式, 通过在XML解析树上使用XPath查询语句匹配符合模板的漏洞. Lu等人[107]提出的NeuCheck就是在SmartCheck上的一种拓展. Quan等人[108]的EVulHunter与Argañaraz等人[109]的OpenBalthazar与SmartCheck方法类似. EvulHunter基于EOSIO WASM字节码的控制流图, 使用预定义的规则针对合约中存在的虚假转账漏洞, 而OpenBalthazar则是将预定义的规则应用到AST上检测.
2019年, Nguyen等人[110]基于以太坊上交易被执行时的异常行为, 提出了检测工具ABBE. ABBE为7种漏洞类型分别定义了攻击向量, 同时根据攻击向量的执行轨迹定义了每种攻击向量对应的属性, 最后将获取到的AST、合约地址、交易日志等信息与预定义的攻击向量规则匹配, 通过检测每笔交易中是否存在异常行为, 判断合约是否存在漏洞.
2019年, Wang等人[111]将入侵检测系统嵌入到智能合约中, 用来分析上下文标记的非循环路径, 并采用gas导向的性能模型进行优化, 实现了第1个保护以太坊智能合约的入侵检测系统ContractGuard. ContractGuard先从优秀测试用例的执行轨迹中提取出上下文标记的非循环路径作为入侵检测系统的初始安全路径集, 当配置了入侵检测系统的智能合约接收到一笔交易时, 会分析该交易中的循环路径, 并检验它们是否存在于安全路径集中, 如果不存在则由管理员验证该交易是否存在漏洞, 当不存在漏洞时, 再将该交易的非循环路径加入安全路径集中进一步完善入侵检测系统.
2019年, Li等人提出MuSC[112], 其实现思想是在AST上执行高效精确的变异操作, 再由依据用户定义创建出的测试网络对智能合约进行自动化测试. MuSC先将智能合约的源代码文件转换为AST版本, 并对AST上的数据进行突变, 最后由变异AST反编译出智能合约, 并再测试网络上对该智能合约进行编译、执行和测试. 同年, Akca等人[113]提出的SolAnalyser也是基于变异AST完成智能合约的漏洞检测, SolAnalyser是先在AST上生成相关的断言(assert)语句, 再使用由ABI和字节码信息生成的输入数据, 对带有断言的智能合约进行测试.
2019年, Xue等人[114]使用智能合约的抽象漏洞签名进行代码克隆检测, 提出了一种智能合约漏洞检测技术Doublade, 并通过应用带有防御机制的规则消除了抽象漏洞签名提取过程中带来的假阳性问题. 为了得到假阳性样本更少的漏洞代码数据集, Doublade在Slither、Oyente和SmartCheck的检测结果中添加了各种防御机制, 再经过AST噪声处理、代码块分层聚类、代码块共性分析等步骤, 提取出代码块的抽象漏洞签名, 最后, 通过包含抽象漏洞特征的AST生成控制流图, 并在控制流图上借助基于最长公共序列和子序列检查的代码匹配算法, 检测合约是否包含漏洞. 2020年, Ye等人[115]也提出了一种基于代码克隆检测的智能合约漏洞检测技术, 差别在于, Ye等人从智能合约的AST、程序依赖图和中间表示形式中提取出了用于代码克隆检测的3种特征, 并综合3种特征的匹配结果得出最终的代码相似度.
2019年, Feist等人[116]提出了名为Slither的框架, 用户可以基于该框架实现程序分析技术, 多种技术[66, 68, 117]都是基于Slither实现. Slither先从AST中恢复合约的继承图、控制流图和表达式列表等重要信息, 再分析出合约代码中存在的变量读写、函数保护、变量数据依赖等信息, 最后使用该框架的合约分析程序可以通过API将这些信息用于不同的用途, Slither框架自身已经实现了一些漏洞检测、代码优化和代码审计的工具.
2020年, Chen等人[118]鉴于当前技术无法在线运行和难以扩展新型漏洞的现况, 提出了一种通用的在线检测框架SODA, 用于任何支持EVM智能合约平台的漏洞检测. 被集成到全节点中的SODA从合约层、共识层和数据层分别收集区块、交易和被执行EVM指令的原始信息, 并将其抽象成了11种结构化信息, 基于该框架的应用程序都可以从队列中获取到原始信息和抽象出的结构化信息. 同时, Chen等人基于SODA框架开发了8种检测智能合约漏洞的应用程序, 并在以太坊、Expanse、Wanchain这3个智能合约平台进行了大量实验. 基于类似思想, Wu等人[119]提出了借助重放以太坊上交易来分析智能合约的框架EthScope, 基于数据聚合器收集到的信息, 其可以重放以太坊上的任意交易, 同时允许用户使用给定的API动态检测合约并分析执行过程中的异常行为.
中间表示形式的静态分析, 以及传统软件分析和安全领域迁移到智能合约漏洞检测领域的入侵检测机制、攻击向量、代码克隆检测等方法, 保障了智能合约生态安全发展的同时, 也带来了诸如运行时内存信息缺失、并发检测不足和未知类型漏洞诊断能力较差等缺陷[105, 111, 114,115].
3 数据分析与国内外对比
本节依据前文实现方法的分类, 统计并分析了每篇文章中技术的实现方法、漏洞类型、实验数据等信息, 而Mythril[120]、VaaS[121]等公司开发的技术, 因不存在详细介绍的文章导致大部分数据缺失, 并未在分析范围之内. 同时, 我们还依据每篇论文作者单位的国别分类对国内外智能合约漏洞检测技术进行了比较, 从技术发展趋势、实验漏洞范围以及实验数据分析方面对比分析了国内外在智能合约漏洞检测研究上的差异, 供国内相关研究人员参考, 以期弥补国内在该研究领域的不足之处, 进一步推动国内在智能合约漏洞检测研究领域的研究与发展.
3.1 技术发展趋势
遵循第2节对智能合约漏洞检测技术中采用的方法分类, 我们定义了符号执行、模糊测试、污点分析、形式化验证、机器学习以及其他6种方法标签, 每篇文章在实现文中技术时可能会采用一种或多种方法, 我们为论文集中的每篇文章都标记上了其涉及的方法标签, 当一种漏洞检测技术使用到多种方法时, 则其涉及的每种方法频数都加一. 为了进一步分析各种方法在智能合约漏洞检测技术发展历史中的应用状况, 我们把论文发表年份作为图表的横坐标, 统计结果如图2所示. 一种方法在智能合约漏洞检测技术中可能会以主要方法或辅助方法的形式出现, 如在ILF[96]中, 主要方法是模糊测试, 而机器学习与符号执行则是辅助方法, 我们又分别统计了每种方法作为主要方法与辅助方法的分布, 结果如图3所示.
图 2 6种方法的年份分布图
图 3 主要方法与辅助方法的分布图
从图2和图3可以看出, 自智能合约漏洞检测领域发展以来, 符号执行与形式化验证便作为主流检测方法沿用至今, 同时符号执行因其高效的路径覆盖率, 也可用于辅助生成测试用例、模型状态空间搜索、可达性检验等, 达到提高路径覆盖率、降低假阳性等效果, 符号执行被作为多种检测技术[47, 65, 73, 92, 99]的辅助方法. 模糊测试自2018年的ContractFuzzer[59]与ReGuard[62]发表以来, 也被广泛应用于智能合约漏洞检测领域, 包括检测重入漏洞的GasFuzz[63]、事务顺序漏洞的EthRacer[64], 针对EOSIO的EOSFuzzer[60]等, 也逐渐引入了其他辅助方法[64, 68, 96]来提高模糊测试的效率. 相较于前3种技术, 污点分析在智能合约漏洞检测领域的应用则并不普遍, 更多时候作为一种辅助方法[68, 80, 88, 119]来弥补其他技术的缺陷, 同时也有一批将污点分析作为主要方法[70-73]的漏洞检测技术. 机器学习近些年来快速发展, 作为一种新兴的可用于程序分析的方法, 其在智能合约漏洞检测领域也得到广泛应用, 2021年采用机器学习方法的技术更是急速增长, 多种深度神经网络模型、分类算法等机器学习子方法应用到了智能合约漏洞检测的场景中. 其他分类的方法包含了静态分析, 以及其他传统安全领域与程序分析领域难以归类的程序分析技术, 如入侵检测系统、代码克隆检测、变异测试等, 近些年来其他分类的技术也逐渐增多, 传统安全与程序分析领域的技术也逐步迁移到了智能合约漏洞检测领域. 6种方法中, 污点分析最常作为辅助方法提升漏洞检测技术性能; 符号执行因其高路径覆盖率的优势, 也常用来弥补其他方法自身缺陷, 达到提高覆盖率和降低假阳性等效果; ILF[96]则另辟蹊径, 利用机器学习辅导模糊测试的策略生成.
我们依据每篇文章作者隶属单位的国别进行国内外研究的划分: 如果一篇论文的所有作者单位都在国内(包括港澳台地区), 这篇论文的研究工作直接归类为国内研究(共18篇); 如果一篇论文是由国内外的不同研究机构的研究工作者合作完成时, 则依据该文第一作者隶属单位的国别进行划分, 即如果该文第一作者隶属单位在国内, 这篇文章将会归类为国内研究(共9篇[59, 62, 63, 68, 107, 112, 118, 119, 122]). 需要注意的是, 当一篇研究论文由国内外的研究者共同完成时, 难以十分准确地将该研究工作划分为国内或国外, 一般情况下, 研究论文的第一作者是该研究工作的主要完成者和核心技术完成者, 如果该作者隶属单位在国内, 我们则认为我国掌握了该项研究技术. 同时这9篇文章的数据也佐证了这一点, 这9篇划分到国内研究的合作文章中国外研究作者仅有一到两位且作者顺序靠后. 其他情况则全部归类为国外研究(共57篇, 其中3篇[123–125]是国内外合作研究, 而国内研究者也是仅有一到两位且作者顺序位于末位). 为了展现国内外技术在采用方法方面的差异, 我们依据前述归类方法对国内外技术采用的主要方法进行了分类和对比分析, 如图4所示, 图5则展示了国内技术采用的主要方法年份分布图. 可以发现, 国内技术更集中在模糊测试、机器学习以及其他方法的应用上, 这3种方法相较国外并没有明显差异. 而作为智能合约漏洞检测技术主流方法的符号执行与形式化验证, 国内研究相比国外则呈现不足, 其中2017年采用符号执行的Gasper[51]是基于2016年Luu等人提出的Oyente, 2020年发表的4篇[58,122,126,127]采用符号执行方法的文章中, 3篇是发表在未经同行评审的arXiv上, 但也弥补了近些年国内基于符号执行研究的不足, 而基于形式化验证的检测技术, 国内的成都链安科技公司研发了自动化形式验证平台VaaS[121], 但论文集中国内的研究仍旧空白. 同时以污点分析作为主要方法的智能合约漏洞检测技术, 国内外采用情况都偏低, 国内的EthPloit[68]、EthScope[119]采用污点分析作为辅助方法, 在辅助方法的应用上与国外没有较大差异.
图 4 国内外主要方法分布图
图 5 国内主要方法年份分布图
本节我们统计分析了前文的6种方法分类在智能合约漏洞检测领域的年份分布情况, 并参考检测技术采用主要方法的分布数据, 对比了国内外技术在采用方法上的差异. 在智能合约漏洞检测技术采用方法的分布中, 符号执行与形式化验证一直是主流方法, 其中符号执行也常作为辅助方法用于辅助测试用例生成、可达性检验等, 而目前国内技术在这两种方法的应用上并不充分, 其中形式化验证方法在论文集中的研究依旧空白, 工业界则有成都链安科技公司研发的VaaS; 模糊测试因其漏洞发掘的高效性, 在智能合约漏洞发掘领域也应用广泛, 国内技术在这一方法的研究进展平稳; 采用新兴的机器学习和传统的软件分析等其他方法的技术近些年来也逐渐迁移到智能合约漏洞检测领域, 国内技术目前在这两种方法的应用上也相对前沿; 而污点分析在智能合约漏洞检测领域的应用较其他5种方法并不充分, 但其常作为辅助方法弥补其他方法的不足.
3.2 漏洞涵盖范围
智能合约存在关于整数、算术操作、异常等类似传统应用程序的漏洞, 因其特性也存在与重入、gas、代币等相关的特色漏洞, 我们依据检测技术涵盖的漏洞类型, 将其分为通用漏洞检测技术和专用漏洞检测技术, 其中通用漏洞检测技术指涵盖漏洞类型不止一类的技术, 而专用漏洞检测技术则是仅检测一种漏洞类型的技术, 如检测重入漏洞[128-130]的ReGuard[62], gas相关漏洞的GasTap[83], 算数操作相关漏洞[123,131]的VeriSmart[89]等.
根据上文对漏洞检测技术的划分, 我们统计了论文集中技术的漏洞涵盖类型分布, 如图6所示, 我们将专用漏洞检测技术又分成了两类, 一类是针对智能合约特性的专用漏洞检测技术, 包含gas相关漏洞、重入漏洞、代币转移相关漏洞, 另一类是针对传统漏洞类型的其他专用漏洞检测技术, 如整数漏洞、算术操作相关漏洞等. 可以看到, 在当前智能合约漏洞检测技术的涵盖漏洞层面, 通用漏洞检测技术占据多数, 约为专用技术的两倍, 在专用漏洞检测技术中, 因智能合约实现机制与其代币在现实中存在一定经济价值的特性, 检测智能合约特性的专用漏洞检测技术, 相对其他专用漏洞检测技术明显较多. 智能合约面临的严峻安全问题引起了相关研究人员的关注, 因其特性产生的诸如重入、gas和代币相关漏洞也成为当前智能合约安全研究的重点.
图 6 基于涵盖漏洞类型的技术分类图
自以太坊将智能合约这一概念实现之后, 又出现了EOS、Fabric等一批智能合约平台, 不同平台因底层特性与虚拟机的不同, 检测方法并不统一, 论文集中的技术涵盖了以太坊、EOS、FISCO BCOS等平台, 其中Zhuang等人[101]与Liu等人[124]提出的漏洞检测技术不仅支持以太坊, 这两种技术还分别兼容了VNT Chain和FISCO BCOS, SODA[118]则支持任何使用EVM的平台, 而Seraph[127]除了EVM外还支持任何使用WASM的平台, 我们将这类支持多平台漏洞检测的技术归类在跨平台中.
图7展示了各种技术检测平台的数据, 以太坊作为最受欢迎的智能合约平台, 在智能合约漏洞检测领域依然热门, 与此同时, 针对以太坊之外智能合约平台的漏洞检测研究也成为未来研究趋势, EOS、Fabric、Tezos等平台的漏洞检测吸引了一批研究人员, 针对漏洞检测技术仅支持单一智能合约平台的局限性, 近些年来, SODA、Seraph等跨平台漏洞检测技术也逐渐成为智能合约漏洞检测领域研究的新方向.
图 7 检测平台的分布图
图8、图9展示了国内外漏洞检测技术在漏洞类型涵盖与检测平台两方面的数据, 可以看到, 国内外技术在漏洞类型分布上整体差距并不大, 通用漏洞检测技术的占比都在70%左右, 而在专用漏洞检测技术方面, 国内将研究重心放在了智能合约特性漏洞的研究上, 而国外则同时兼顾了整数操作符等传统漏洞类型. 在智能合约平台的检测层面, 智能合约底层技术的更新迭代与多样化的应用需求, 催生了大量的智能合约平台, 以太坊平台之外的漏洞检测与跨平台漏洞检测技术也都成了新的研究方向, 国内关于以太坊平台智能合约安全问题的研究虽然起步较晚, 但在EOS、跨平台技术的研究上差异已经较小.
图 8 基于漏洞类型的技术分类分布图
图 9 检测平台的分布图
本节我们统计分析了国内外技术在漏洞类型、检测平台两种标准下的分布状况. 在覆盖漏洞类型方面, 我们划分了通用漏洞检测技术以及专用漏洞检测技术, 其中专用漏洞检测技术又包含了智能合约特性与其他两种, 国内外在通用技术和专用技术两方面研究的分布则没有太大差异, 以通用技术的研究为主, 在专用技术中, 智能合约特性相关的漏洞在国内比传统应用程序漏洞引起了更大的关注; 在检测平台方面, 以太坊平台依然是目前的研究热门, 但其他平台的漏洞检测和跨平台技术的研究也成为当下新的趋势, 国内虽然在以太坊平台的漏洞检测起步较晚, 但近年来在以太坊之外的EOS、跨平台检测技术的研究方面则相对前沿.
3.3 实验数据分析
在评判智能合约漏洞检测技术的准确率、误报率、运行效率等性能时, 会使用一定数量的智能合约作为实验数据集, 一些智能合约漏洞检测技术还会存在与其他技术的对比实验, 同时在开/闭源(开源是指研究人员将其研究工作的智能合约漏洞检测技术工具的源代码或二进制码公开在了相关开源平台上, 如GitHub; 闭源则是指没有公开任何关于漏洞检测工具的代码信息)的选择上, 不同技术的选择也不相同. 本节统计分析了论文集中技术的开/闭源状况、实验数据集差异与对比技术的信息, 以及国外技术在这些方面的差异.
论文集中的智能合约漏洞检测技术在源码是否开源的抉择上存在一定程度差异, 一项开源的技术既可以被测试人员用来检测其开发的智能合约是否存在安全隐患, 也可以被其他研究者优化或参与其开发智能合约漏洞检测技术的对比实验, 论文集中还有一些技术源码并未开源, 但提供了使用该技术的网页界面, 智能合约开发人员可以在该页面检测智能合约的安全性能, 我们将这两种情况都归类在开源技术中. 我们收集了论文中提供代码或使用界面的网页链接, 一些在论文中并未找到相关链接的论文, 我们分别以论文名与技术名在GitHub中作为关键词查找, 最后统计出共有闭源技术41个, 其中国内20个, 国外21个, 开源技术43个, 国内7个, 国外36个, 其中部分技术[47, 72, 83, 132,133]并未开放源码, 但提供了网页调用技术进行合约的安全性检测, 最终开源技术的网页链接如表1所示.
表 1 智能合约漏洞检测开源技术信息汇总
图10展示了国内外技术在开/闭源方面的分布现状, 论文集中的漏洞检测技术在开放性上分布的差距不大, 但国内外技术间的差异比较明显, 国内开/闭源技术的在国内技术占比分别为26%、74%, 而国外开/闭源技术的占比则分别为63%、37%, 在开源技术方面, 国内技术明显低于该领域的平均水平, 且远低于国外技术开源的百分比, 国内技术更倾向于选择闭源.
图 10 国内外开/闭源信息分布图
智能合约漏洞检测技术是保障智能合约生态安全发展的屏障, 但目前漏洞检测领域并没有统一的实验数据集或标准, 因而论文集中的技术在衡量性能时采用的数据集各不相同, 我们依据数据集来源将其分为案例分析与平台检测两种类型. 因智能合约平台允许任何人部署与接入, 使得其上存在的智能合约良莠不齐, 一些技术的实验仅检测少量优质样例合约并进行人工分析, 我们将其归类为案例分析[141-143], 如Harvey就是在27个真实世界的智能合约进行的评估, Liu等人则在微众银行的CMA合约与FSolidM的BlindAuction合约上评估ModCon[124]. 由于智能合约去中心化的优势, 智能合约字节码可以接入网络直接获得, 而源代码则可以在Etherscan上获取, 另一类技术则直接测试部署在智能合约平台的字节码或在Etherscan上发布源代码的智能合约集, 再在实验过程中去除掉其中会引起超时、异常等错误的部分合约, 我们则将其归类为平台检测[50-52, 144], 如Oyente[50]将以太坊上截止到2016年5月5日的所有智能合约字节码作为实验数据集. 最终实验数据集的分布如图11所示.
图 11 国内外实验数据分布图
图11数据表明, 智能合约漏洞检测技术整体上更倾向于采用平台检测这种方案, 且国内技术在数据集选择上平台检测的采用率更高. 两种分类的实验数据集各有优劣, 由于智能合约平台开放、不可篡改的特性, 使得平台上充斥了大量项目开发前期功能尚不完善的合约或初学者用于相同学习目的的重复合约等冗余实验数据, 案例分析分类使用少量人工筛选出的符合预期测试目的的优质合约[67], 避免了工具在实验时陷入大量冗余数据的测试中, 但因人的精力受限, 其在筛选过程中不可避免地会遗漏一些典型的漏洞案例, 此时通过平台检测的方式则可以有效地涵盖包含各种漏洞类型的合约, 但也存在冗余合约降低工具运行效率的问题[88]. 目前智能合约漏洞检测技术的数据集并没有统一标准, 也是智能合约漏洞检测领域亟待解决的问题之一.
除了数据集的选择, 部分论文[68, 89, 105]还会对技术性能进行对比实验, 我们统计了论文集中技术是否存在对比实验的数据, 如图12所示, 同时, 我们也统计了参与到论文中对比实验的智能合约漏洞检测技术的频数, 如果一篇论文用到了一个或多个技术进行对比实验, 则这些参与对比实验技术的频数都会加一, 最终结果如图13所示.
图 12 国内外对比实验分布图
图 13 参与对比实验的技术分布图
可以看到, 论文集中有无对比实验的技术数量相近, 且国内外技术在有无对比实验方面并无较大差异, 同时参与对比实验的技术大多数仍是论文集中的技术, 大部分不在论文集中的社区技术(Surya、Remix、VeriSol、Rattle、SMTChecker)频数只有一次, 仅有社区技术Mythril虽不在论文集中, 但其参与对比试验的频数高达13. 以第2节划分的6种方法分类为依据, 参与对比实验的技术主要以采用符号执行(Mythril、teEther等)、其他(SmartCheck、Slither)方法的技术为主, 采用模糊测试、机器学习等方法的技术则很少被用到其他工具的对比实验中. 由于目前国内研究智能合约在符号执行方面的不足以及国内论文集中工具开源率偏低等原因, 使得对比实验中常用到的技术以国外为主, 国内仅有4篇论文[59, 62, 108, 118]在6篇论文的对比实验中被引用过一次或两次.
本节分析了论文集中技术的工具开/闭源、实验数据集、对比实验等数据的分布, 并总结了国内外研究间的异同. 目前智能合约漏洞检测领域有近一半技术选择工具开源, 而国内研究在工具开源的比例则远低于国外; 我们又将论文实验中采用的数据集分为了案例分析和平台检测两种分类, 案例分析中的数据集是人工挑选出的优质智能合约, 但其数据集相对较小在一些典型案例上可能存在疏漏, 而平台检测则是对平台上的智能合约进行全面性的安全检测, 但其上存在大量不成熟与冗余的合约, 一定程度上降低了平台检测的效率; 同时, 对比实验在论文中广泛存在, 我们统计了参与对比实验技术的频数, 发现符号执行和其他分类标准下的技术被广泛应用在对比实验中, 由于国内符号执行的研究不足、智能合约安全研究起步晚、工具开源比例低等原因, 使得国内技术鲜有参与到其他论文的对比实验中, 仅有4项技术在6篇论文的对比实验中被分别使用到了一次或两次.
3.4 国内研究的不足之处与改进方向
第3.1–3.3节从技术发展趋势、漏洞涵盖范围与实验数据分析3个方向分析了当前智能合约漏洞检测研究工作的数据, 并基于此对比了国内外研究工作的异同, 其中国内外研究工作在采用方法、工具开/闭源和对比实验方面存在较多差异, 基于此我们总结了国内研究工作的不足之处与改进方向, 望后续研究人员的研究在促进国内该领域研究发展的同时更有方向性, 弥补国内研究工作的空白.
国内研究工作在漏洞类型涵盖范围与数据集检测方案的抉择上较国外没有太大差异, 其不足之处主要在于采用方法分布不均衡以及技术开放较少, 从而导致国内研究工作在其他技术的对比实验中较为罕见. 国内研究工作采用的方法更集中在模糊测试、机器学习与其他3类, 而作为智能合约漏洞检测技术主流方法的符号执行与形式化验证, 国内研究的采用情况则不太理想, 仅有2017年的符号执行技术Gasper[51]与2020年发表的4篇[58,122,126,127]符号执行文章, 其中Gasper是基于2016年Luu等人提出的Oyente, 而2020年发表文章的中有3篇都是发表在未经同行评审的arXiv上, 在采用形式化验证方法的检测技术方面, 国内的成都链安科技公司研发了自动化形式验证平台VaaS[121], 但论文集中并不存在国内的相关研究; 同时在工具开源方面, 国内研究工作开源相对较少, 更倾向于闭源, 该状况并不利于该领域的进一步发展; 与此同时, 符号执行和其他分类标准下的技术被广泛应用在对比实验中, 鉴于国内符号执行的应用不足与技术开放比例低的现状, 国内技术较少参与到其他研究工作的对比实验中, 仅有4项技术在6篇论文的对比实验中被分别使用到了一次或两次.
目前学术界颇为关注的形式化验证和符号执行安全有效但难度很高, 另外国内智能合约漏洞检测研究起步较晚, 这共同造成了形式化验证和符号执行在国内智能合约漏洞检测技术中的应用相对较少, 希望国内符号执行与形式化验证领域的研究人员将相关研究工作与智能合约漏洞检测结合, 以推动国内该领域研究的全面发展. 同时也希望国内研究人员能够公开相关研究技术的工具代码(具有保密协议的例外), 一项开源的技术不仅可以协助其他研究人员更快地了解该领域, 还对他们的工作有一定的指导启发意义, 并且在技术开源的过程中, 研究者也可以基于社区的反馈情况对开源技术进行进一步的优化. 此后, 随着国内技术采用方法的均衡发展与开放状况的逐渐改善, 国内技术在对比实验中的出现频率会有一定程度的提升.
4 讨论与展望
4.1 现有研究的不足
如前所述, 近些年来涌现了一批智能合约漏洞检测技术, 能够较为准确地检测智能合约上存在的各种漏洞, 降低了智能合约中潜在的安全隐患, 但其还处于发展前期, 存在一定程度的缺陷, 面临着以下待解决的问题.
(1) 多样化的智能合约平台. 随着智能合约底层技术的更新迭代与其在不同应用领域的多样需求, 继以太坊之后, 涌现了Fabric、EOSIO等智能合约平台, 不同平台在虚拟机实现、底层特性、智能合约机制等方面的差异, 给智能合约的漏洞检测带来了新的难题, 而当前智能合约漏洞检测技术则过于集中在以太坊一种平台. 因此, 以太坊之外平台与跨平台的漏洞检测也需要进一步的研究.
(2) 多样化的智能合约编程语言. 现实世界中的编程语言种类繁多且更迭迅速, 目前仅支持编写智能合约的高级编程语言就有几十种(如Solidity、Vyper、Michelson), 不同编程语言在语法语义规则和编译成字节码过程中都存在差异. 智能合约漏洞检测技术如何适配这些高级编程语言特性, 也是一项挑战性的研究.
(3) 漏洞检测方法的局限性. 目前大多数技术依赖的模糊测试、符号执行、形式化验证等漏洞检测方法自身存在一定的局限性. 模糊测试在测试数据生成的过程中会存在路径覆盖率低、测试数据效率低下等缺点; 而符号执行在得到高路径覆盖率的同时, 又引入了路径爆炸与约束求解难等问题; 形式化验证虽然基于严谨的数学推导, 但其自动化程度较低, 且无法动态分析, 缺乏了对漏洞检测结果的可达性检验, 会产生较高的误报率; 污点传播过程中内存存储信息的处理和信息流分析不全面造成的过污染与欠污染也是现阶段面临的难点; 同时, 机器学习对数据集处理与算法选择上的依赖, 造成了源码语义建模不足的难题, 另一方面, 神经网络等算法的黑箱性也导致大多数情况下检测结果的可解释性较差; 中间表示形式的静态分析以及传统软件分析和安全领域迁移而来方法也带来了诸如运行时内存信息缺失、并发检测不足和未知类型漏洞诊断能力较差等缺陷. 因此, 克服现有技术所依赖漏洞检测方法的局限性是亟待解决的关键问题.
(4) 漏洞检测结果中存在的高漏报率和误报率. 由于智能合约漏洞类型的繁多与漏洞特征的复杂性, 以及所采用方法自身的缺陷, 大多数技术在检测漏洞时存在着忽略某种漏洞类型复杂特性部分特征的可能, 仍然存在不同程度的误报和漏报. 降低检测结果的漏报率与误报率也是当前技术的关键挑战.
(5) 较低的漏洞类型覆盖率. 由于智能合约的不断发展与升级, 存在着复杂且数量繁多的漏洞类型, 大部分漏洞检测技术都是提供了一种检测方法并应用在了适应该方法的漏洞类型中, 因而并不一定涵盖智能合约中存在的所有漏洞. 因此, 现阶段有完善技术对漏洞类型更全面检测的需求.
(6) 较低的漏洞利用率[145]. 智能合约通过区块链上的交易来进行交互, 漏洞利用主要关注如何生成恶意的交易数据, 以利用智能合约中的漏洞来完成特定的攻击. 智能合约中的漏洞分类众多, 产生原因也各不相同, 一次成功的攻击往往需要多个漏洞的相互配合, 并可能涉及多个合约之间的相互调用, 多方因素共同造成了当前检测结果中漏洞利用率低下的现状. 检测出更易被利用的高危漏洞或自动化漏洞利用, 也是现阶段需要进一步深入的研究方向.
(7) 较长的漏洞审计时间. 智能合约潜在安全隐患的及时审计也是保障智能合约安全发展的关键要素, 现有技术的高效检测与完全自动化是智能合约开发周期中的重要一环, 而当前技术依然存在较长的漏洞检测时间与人工参与审计的问题. 在面临数目和规模与日俱增的智能合约时, 现阶段低效的审计效率和繁琐的人工审计工作量也是保障智能合约安全的亟需突破的难点.
4.2 未来研究方向与改进思路
基于智能合约漏洞检测技术现阶段的发展与挑战, 本文总结出了以下未来研究方向与改进思路.
(1) 完善智能合约的安全开发流程. 为了减轻智能合约部署之后的漏洞检测负担, 同时为了缓解智能合约平台与高级编程语言多样性带来的问题, 未来研究工作应该首先关注智能合约开发过程中的安全保障工作, 研究如何在智能合约的设计和实现阶段, 针对不同的合约功能需求、编程语言、编译执行环境、区块链平台, 定制合约开发标准, 规范开发流程, 智能合约开发阶段的标准化可以降低部署后合约上存在的漏洞数量, 能一定程度上减小智能合约漏洞检测的负担, 提高智能合约漏洞审计效率.
(2) 改进现有漏洞检测方法. 现有检测方法自身都存在一定程度的局限性, 如模糊测试的低路径覆盖率、符号执行的路径爆炸与污点分析过程中的过污染和欠污染等难题. 我们就它们未来的研究方向与改进思路进行了讨论与分析.
• 模糊测试的关键步骤是测试用例的生成, 传统的模糊测试在生成测试用例时, 往往盲目变异正常测试用例中的某一部分去生成测试用例, 导致测试用例规模庞大, 执行效率并不理想. 因此, 未来需要进一步结合智能合约在区块链、虚拟机、高级语言等不同层面的特性, 采用如遗传、模拟退火、多目标优化等算法, 制定出优秀的测试用例生成策略, 另一个研究方向是通过符号执行、污点分析以及新兴的机器学习技术, 弥补模糊测试过程中语义理解的缺失, 生成能够触发研究人员所关注逻辑的结构化测试用例, 提高模糊测试的路径覆盖率与漏洞发掘的效率.
• 制约符号执行效果的最主要挑战是执行路径爆炸难题, 未来可行的方法是结合现有智能合约的审计经验与已曝漏洞的分析结果, 寻找合约中易产生漏洞的高危指令, 如SUICIDE、CALL、DELETECALL等, 将涉及这些指令的路径定义为重点路径, 只符号执行标记的重点路径并进行漏洞验证, 达到剪枝冗余路径的效果, 有效地缩减符号执行过程中的路径空间, 缓解执行过程中的路径爆炸问题. 与此同时, 符号执行因其高效的路径覆盖率, 能推断出到达特定程序状态的条件, 并约束求解出测试者关注逻辑的输入, 可作为其他漏洞检测方法的辅助方法, 基于符号执行的结果可用于模糊测试的测试输入的优化、形式化验证的模型状态空间搜索与漏洞检测结果的可达性检验等, 达到提高路径覆盖率、降低漏洞检测结果假阳性等效果.
• 形式化验证方法通过数学推演来验证智能合约系统的安全性, 现有的研究工作大多数自动化程度不高, 且检测出来的漏洞不一定存在可达路径. 未来的研究方向应为检测不同漏洞目标的合约定制对应的验证规范描述, 突破验证成本昂贵、大规模合约无法适应等技术限制, 并将应用范围从验证一般合约的功能和安全属性等, 逐步扩展到存在复杂业务逻辑等高阶性质证明的商业场景中. 在定制形式化验证规范阶段, 可借助污点分析与静态分析等方法的源码语义信息, 构造出描述合约正确性与公平性的形式化规范, 而在推理合约行为是否符合归纳的形式化规约时, 则可通过符号执行技术扩大可达性检验属性的状态空间, 达到降低形式化验证成本与漏洞检测假阳性的效果.
• 污点分析通过追踪程序中由污点源引入的数据能否不经无害化处理而直接传播到汇聚点, 来检测智能合约中是否存在漏洞. 污点数据识别的精度与传播策略的优劣, 引发了污点分析过程中的过污染与欠污染问题, 成为污点分析主要的性能瓶颈, 严重影响了智能合约检测的精度与效率. 同时, 动态污点分析过程中也存在精度与效率之间不可调和的矛盾. 基于智能合约性质与已知漏洞特征, 权衡好智能合约执行效率和污点分析精度, 设计更科学的污点识别方法的同时并定制严谨的污点传播策略, 如追踪区块数、时间戳等矿工可以操纵的信息、可操作代币转移的合约函数行为等, 可以尽可能地降低污点传播过程中的过污染与欠污染的出现频率. 除此之外, 污点分析过程中捕获的智能合约信息流中的语义, 对形式化规范的构造、模糊测试策略的制定以及符号执行关键路径的提取, 都能够提供一定程度的深层语义信息, 用于提高智能合约漏洞检测的效果.
• 现有的基于机器学习的智能合约漏洞检测技术大多是通过数据集训练出的漏洞检测模型, 来给出最终的漏洞检测结果, 是典型的黑盒测试流程. 由于机器学习模型固有的“黑箱性”, 其内部检测漏洞的具体工作状态和处理过程是不透明的, 因此缺乏对漏洞检测结果的合理解释, 使得其检测结果无法令人信服. 传统检测工具中定义的规则与提取出的语义信息是分析合约漏洞的利器, 未来的机器学习模型应考虑融合传统检测方法中漏洞相关的规则及语义信息, 有利于提高模型输出结果的可解释性和漏洞检测的准确率. 同时, 机器学习方法使用已有的数据让计算机模拟或实现类似人类的学习行为, 可用于改善现阶段低效的审计效率并减轻繁琐的人工审计工作量.
• 基于表示形式的静态分析方法通常将定义的漏洞规则, 应用到智能合约源码或字节码转换的中间表示形式来检测漏洞. 未来的研究方向应当提高这类检测方法的扩展性和适应性, 专注于中间表现形式的通用性上. 此外, 将静态分析与动态执行的结合也能够显著提高漏洞检测的效果. 而传统软件分析和安全领域迁移而来的方法应更多结合智能合约在区块链、虚拟机、高级编程语言等层面的特性, 最大程度降低自身方法的局限性, 适应到智能合约漏洞检测的背景中.
(3) 构建智能合约的标准实验数据集. 当前关于智能合约的实验数据集尚未有标准的案例集, 本文调研的技术实验部分也都是采用了不同的数据集, 在检测结果上未能反映出技术漏洞检测的各方面性能与不同技术间的差异, 构建出统一规范的、涵盖漏洞类型与智能合约平台全面的实验数据集, 除了可以验证智能合约漏洞检测技术的多方面(漏报率、误报率和漏洞利用率)性能与比较不同技术间的差异, 也可以给智能合约的安全开发和机器学习的模型训练提供参考, 更好地推动该领域的研究.
(4) 制定统一的漏洞检测技术性能评估标准. 根据目前已有的漏洞检测技术以及以往智能合约漏洞的审计经验, 综合考虑漏洞检测结果的漏洞率、误报率、漏洞利用情况、检测时间、涵盖漏洞类型、支持平台等因素, 最终制定统一的智能合约漏洞检测技术性能评价标准, 有利于已有技术的性能评价与对比分析, 并为新的智能合约漏洞检测技术的研发与改进提供参考指导.
5 总 结
智能合约是目前最有前景的技术之一, 提供了丰富、安全、可信的去中心化应用场景, 契合了数字身份、物联网、供应链等领域的现实意义, 但与之而来的安全事故严重阻碍了它的发展, 智能合约漏洞检测技术已成为新的研究热点. 本文梳理了研究者们提出的一系列智能合约漏洞检测技术, 然后将已有技术归纳为基于模糊测试、基于符号执行、基于污点分析、基于形式化验证、基于机器学习和其他方法, 并介绍了目前这6种分类下的智能合约漏洞检测技术, 再统计分析了现有技术的采用方法、涵盖漏洞类型、检测平台、开/闭源信息、实验数据、对比技术信息, 同时对比评估了国内外研究现状的差异, 并总结了国内研究的不足之处与潜在的改进方向, 最后对智能合约漏洞检测技术研究现状的不足之处与未来研究方向和改进思路进行了总结.