opendir是安全重入函数吗_ReGuard:智能合约中可重入漏洞检测

opendir是安全重入函数吗_ReGuard:智能合约中可重入漏洞检测_第1张图片

论文:Chao Liu, Han Liu, Zhao Cao, Zhong Chen, Bangdao Chen, and Bill Roscoe. 2018.

ReGuard: Finding Reentrancy Bugs in Smart Contracts. In Proceedings of the 40th

International Conference on Software Engineering Companion. IEEE Press.

论文摘要:

智能合约为在区块链上执行加密货币交易提供了一种新途径。尽管这种新技术引入了无冲突机制和透明机制,但智能合约本身是脆弱的。智能合约作为一种特殊的计算机程序,它仍然无法避免产生BUG。更糟糕的是,可利用的安全漏洞可能导致灾难性的后果。例如,损失加密货币。在这篇演示文章中,我们主要关注智能合约中最常见的安全漏洞类型——可重入漏洞。可重入漏洞曾经导致了著名的DAO攻击,致使被攻击者损失高达六千万美元。我们提出了一种基于Fuzzing来分析智能合约中可重入漏洞的工具,Reguard。具体来说,ReGuard通过迭代生成随机且不同的交易事务,对智能合约执行模糊测试。基于运行时追踪,ReGuard将动态识别可重入漏洞。在初步评估中,我们分析了现有的5个Ethereum合同,ReGuard自动标记了7个以前未报告的可重入漏洞。

技术介绍:

文中采用了自己编写的例子介绍了智能合约中可重入漏洞是什么,并且如何被利用:

opendir是安全重入函数吗_ReGuard:智能合约中可重入漏洞检测_第2张图片

图1:可被DAO攻击的简单示例

示例代码是用solidity (Ethereum智能合约的一种编程语言)编写的,有两个受害者合约和攻击者。被害人合约具有一个withdraw()函数,它将以太币从被调用方发送到调用方(第4行)。DAO攻击分为一下几步:

(1)攻击者通过调用受害者合约的withdraw函数创建一个事务

(2)受害者转账(第4行)并调用回调函数(10到12行)

(3)回调函数递归调用withdraw函数,即可重入

(4)在一次迭代限制内,额外的亿台币将被转账多次

如上所述,可重入漏洞很容易在已部署的区块链合约上利用,并且已经成为实际中最常见的攻击之一。不幸的是,我们不仅对如何自动准确地捕捉这些bug知之甚少,而且对工具的支持也非常有限。从实践的角度来看,检测智能合约中的可重入漏洞面临以下挑战:

挑战1:覆盖事务的执行场景。智能合约的执行在不同的事务中,可能产生不同的结果。覆盖所有的结果不仅是代价昂贵的,而且在一些情况下是不可能的。

挑战2:代码可重入特征。可重入漏洞的特征在智能合约上下文中缺乏准确的定义。在检测中引入简单的检测模式将产生误报,而严格的检测模式会漏报错误。

opendir是安全重入函数吗_ReGuard:智能合约中可重入漏洞检测_第3张图片

图2:代码到代码的智能合约转换

为了解决这些挑战,我们开发了ReGuard,用于检测智能合约中的可重入漏洞。

ReGuard引入了一个基于翻译的框架,从特定的智能合约编程语言到c++。的检测,

ReGuard扩展了已有的fuzzing引擎(例如,AFL和LibFuzzer)生成随机事务。在运行时期间,ReGuard记录关键的执行跟踪,并将其提供给可重入漏洞自动检测机以识别潜在的bug。

opendir是安全重入函数吗_ReGuard:智能合约中可重入漏洞检测_第4张图片

图3:ReGuard框架图

ReGuard的架构如图3所示。在高级图中,ReGuard将智能合约的代码作为输入。具体来说,它同时支持源代码和二进制代码。就输出而言,ReGuard生成一个错误报告,该报告是在分析的智能合约中发现的可重入错误的集合。对于每一个漏洞检测报告,ReGuard会标记导致漏洞的源代码错误位置并且标记是什么事务导致了这个漏洞。

接下来,我们将介绍ReGuard的工作流程。给定智能合约的代码,ReGuard将其解析为一个中间表示(IR)。对于源代码合约,IR是一个抽象语法树(AST)。对于二进制代码合约,我们使用一个控制流图作为它的IR。然后,ReGuard在合约转换器中执行从IR到c++的源到源的转换。转换后的c++合约保持原来的行为。另一方面,ReGuard嵌入了一个fuzzing引擎,它将使用运行时覆盖信息作为反回信息,迭代地生成随机字节。ReGuard将字节解释为事务请求。结合c++智能合约、事务和运行时库,ReGuard执行合约并转储分析相关操作的运行时跟踪,例如,函数调用和返回、对存储和区块链参数的访问、分支操作等。然后将跟踪传递到核心检测器以进行可重入漏洞分析。最后报告发现的bug。

如上所述,ReGuard执行从IR到c++的源代码到源代码的转换。该转换在合约转换器中实现。我们以AST IR为例来解释这个转换,它在概念上相当于遍历AST然后为特定类型的AST节点生成c++代码。考虑图2 a中的代码,这个合约用solidity编写声明和初始化了两个变量flag和amount。除此之外,它定义了两个回调函数update用来更新存储的值和withdraw用来转账以太币。图2b显示了转换后的c++合约。具体来说,两个函数update和withdraw会相应地进行转换。除了原始的函数参数外,还显式地将消息对象传递到c++函数中,以携带事务信息,如发送方的地址和包含的以太币等。在第14-15行,调用了fallback_call函数来模拟调用地址中的fallback函数的操作。总之,转换保持原始行为和接口到fuzzing引擎以生成事务。

智能合约的执行高度依赖于事务。也就是说,不同的事务可能会导致不同的合约状态,其中可能会出现可重入漏洞。为了尽可能地探索智能合约的状态空间,ReGuard利用精心设计的fuzzing引擎生成随机事务并覆盖不同的执行场景,如图4所示。

686f29f7e1cad8775e2bfccd1b198b46.png

图4:将随机字节解释为事务

ReGuard工具利用fuzzing引擎产生随机字节,然后解释为一个三元组集合(from,to,input)。from字段指定消息的发送方地址。to字段指示将事务发送到哪个合约(c++类)(在本例中很简单,如图2a所示)。input字段生成对合约中定义的函数的随机调用(在本例中使用参数10进行更新,如图2a所示)。接下来,三元组将嵌入到执行c++智能合约的主入口中。在执行期间,运行时利用运行时覆盖率优化字节的生成。考虑到图 2c中的情况,fuzzing引擎生成三个事务,这三个事务都是从同一个发送者到Simple合约。并且生成一个调用序{update(10), withdraw(), update(20)}

当fuzzing引擎运行时,ReGuard将执行具有不同事务的智能合约并转储运行时追踪。由核心检测器分析跟踪,以识别可重入漏洞。具体地说,检测是通过在可重入漏洞检测自动机中解析跟踪来实现的,如图5所示。

opendir是安全重入函数吗_ReGuard:智能合约中可重入漏洞检测_第5张图片

图5:可重入漏洞检测自动机。entry/exit:函数的进入和退出。call:EVM的调用操作码。

可重入漏洞检测自动机是有限状态机(FSM)的一种形式,其中的状态指示可重入漏洞的发生,而转换是在跟踪中记录的操作。共指定五种状态,即,START,FUNC, FUNCCALL,RE和ERROR。START是自动机的入口点。ERROR表示发生了可重入漏洞。FUNC为函数调用建模,FUNC CALL进一步细化以太币转账调用。RE标志执行引入可重入函数调用。

本文将ReGuard部署为web服务。图6显示了ReGuard的屏幕截图。为了分析一个智能合约,ReGuard采用了“一键式”设计。用户只需要在浏览器中输入合约代码,ReGuard就会处理所有事情,例如:语法检查、代码转换、模糊化和错误检测。

opendir是安全重入函数吗_ReGuard:智能合约中可重入漏洞检测_第6张图片

图6: ReGuard屏幕截图

以图6中的简单智能合约为运行示例,我们简要描述ReGuard的用法。通过单击“Start”按钮,启动ReGuard进行可重入漏洞分析。检测完成后,将在底部生成一个bug报告,如图7所示。在这种情况下,第8行突出显示了一个可重入漏洞,即,以太币转账操作使用call.value() API在withdraw函数。

opendir是安全重入函数吗_ReGuard:智能合约中可重入漏洞检测_第7张图片

图7:分析结果示例

789ea4bad33422e7d35da7f86cac473c.png

表1:可重入漏洞分析结果

除了报告的错误之外,ReGuard还进一步显示了解释可重入漏洞的调用堆栈信息。具体地说,在执行第8行时,将调用消息发送方的回调函数。在回调函数中,发送方再次调用回调函数。由于第8行没有引入任何保护逻辑,所以可重入调用仍然传递,并传输额外的以太币。调用堆栈信息使开发人员能够更好地理解错误并设计修复补丁。

在这篇论文中,我们介绍了ReGuard,一个智能合约中可重入漏洞的动态分析器。ReGuard利用fuzzing的技术来生成随机且多样的区块链事务,以作为可能的攻击。然后,ReGuard通过运行时跟踪分析执行错误检测。我们已经实现了web工具来实现ReGuard的功能。在5个修改后的智能合约中,ReGuard识别了7个错误,并避免了误报。

本文的主要贡献:

(1)提出了一个新的检测智能合约中可重入漏洞的框架,填补了已有工具对于准确检测可重入漏洞的空白

(2)实现了ReGuard的web端工具

(3)提出了一种由Solidity语言到C++语言的一种漏洞检测策略

致谢

本文由南京大学软件学院2016级本科生徐光耀翻译转述

你可能感兴趣的:(opendir是安全重入函数吗)