读研整活笔记(3):阅读论文 WANA Symbolic Execution of Wasm Bytecode...

读研整活笔记2:调研编译器soll

  • 需求理解
  • 0.摘要
    • 0.标题
    • 1.摘要
    • 2.关键词
    • 3.个人理解
  • 一.介绍
    • 1.摘要
  • 二.WASM和智能合约的背景
    • 2.1.WASM
    • 2.2.EOSIO智能合约
    • 2.3.以太坊智能合约
  • 三.智能合约漏洞
    • 3.1 EOSIO智能合约漏洞
      • 3.1.1 Fake EOS Transfer
      • 3.1.3 Block Information Dependency
    • 3.2 以太坊智能合约漏洞
  • 四.WANA的设计框架
    • 4.1 WANA的工作流程
    • 4.2符号执行引擎
  • 4.3漏洞检测算法
    • 4.3.1 EOSIO智能合约的漏洞检测
    • 4.3.2以太坊智能合约的漏洞检测

需求理解

书接上回,上回我们整活调研了编译器soll,这回我们要开始阅读论文啦。要求如下:

最近会让你读一下上级学长的论文,开始读代码
后面会让你做wasm字节码的符号执行和漏洞检测
你先对着论文,读读这个代码,尝试跑跑例子,看能否跑得通。

从要求的描述中,应当将它解析成以下几个小任务:

  1. 阅读论文。
  2. 阅读代码
  3. 跑例子。
  4. 后期自己的工作是“做wasm字节码的符号执行和漏洞检测”。

那么接下来就按步骤依次解决吧。由于阅读论文是个工作量较大的事,所以单独成一篇笔记。

0.摘要

0.标题

本论文的题目是WANA: Symbolic Execution of Wasm Bytecode for Cross-Platform Smart Contract Vulnerability Detection
简单翻译一下是WANA:用于跨平台智能合约漏洞检测的Wasm字节码的符号执行

1.摘要

许多流行的区块链平台都支持用于构建去中心化应用程序的智能合约。 但是,智能合约中的漏洞已给最终用户造成严重的财务损失。 对于EOSIO区块链平台,有效的漏洞检测器仍然受到限制。 此外,现有的漏洞检测工具只能支持一个区块链平台。 在这项工作中,我们介绍WANA,这是一种基于WebAssembly字节码符号执行的跨平台智能合约漏洞检测工具。 此外,WANA提出了一组测试Oracle,以基于WebAssembly字节码分析来检测EOSIO和以太坊智能合约中的漏洞。 我们的实验分析表明,WANA可以高效地有效检测EOSIO和以太坊智能合约中的漏洞。

2.关键词

Symbolic execution, WebAssembly, Smart contract, Wasm,
Vulnerability detection, EOSIO, Ethereum

3.个人理解

简单介绍了一下本论文的的应用场景:检测智能合约漏洞。

一.介绍

1.摘要

区块链技术已经在信任有限的各方之间实现了分散的价值转移网络[14]。在智能合约的支持下,开发人员可以在区块链平台之上构建去中心化应用程序(DApp),以便不受信任的各方可以相互合作。流行的DApp包括区块链游戏,去中心化金融(DeFi),在线赌博,去中心化交易所,钱包,供应链管理,物流跟踪等。
以太坊[4]和EOSIO [28]是支持智能的两个最受欢迎的智能合约。但是,以太坊和EOSIO智能合约中的漏洞导致其最终用户蒙受经济损失。对于EOSIO智能合约,“块信息依赖”漏洞,“假EOS转移”漏洞和“伪造转移通知”漏洞已导致总共损失约380K EOS令牌[31] [33]。在攻击时,这些漏洞造成的累计损失约为190万美元。对于以太坊智能合约,DAO合约中的漏洞[22]导致损失了6000万美元。此外,就以太币而言,冻结的以太币和危险的DelegateCall漏洞分别导致损失6000万美元和冻结1.5亿美元[41] [42]。
因此,需要有效的漏洞检测工具来维护区块链平台的生态系统。但是,用于EOSIO智能合约的漏洞检测工具仍然有限。此外,现有的智能合约漏洞检测工具只能支持一个区块链平台。由于区块链平台的多样性,跨平台的漏洞检测工具是实际需要的。
WebAssembly(简称Wasm)[42]是用于基于堆栈的虚拟机的二进制指令格式。 EOSIO区块链平台也采用了它,以提高效率和可靠性。以太坊还计划以Ethereum WebAssembly(EWasm)VM取代EVM,以作为Ethereum 2.0的智能合约执行引擎[12] [18]。结果,EOSIO和以太坊平台上的智能合约都将被编译为WebAssembly,以在相应的Wasm VM实现中执行。因此,WebAssembly级别的符号执行引擎有可能为EOSIO智能合约,以太坊智能合约甚至基于Wasm的Web应用程序提供通用的安全分析框架。
在这项工作中,我们提出了WANA,Wasm字节码的符号执行引擎,以支持跨平台漏洞分析。 WANA可以支持EOSIO和以太坊智能合约的漏洞检测。在我们大约3960个EOSIO智能合约的实验中,WANA有效地检测了400多个漏洞。此外,我们的案例研究表明,WANA还可以有效检测以太坊智能合约的3个典型漏洞。
这项工作的贡献是三方面的。首先,它提出了第一个基于Wasm字节码符号执行的跨平台智能合约漏洞检测框架。其次,它提出了一组测试Oracle,以基于Wasm字节码分析来检测EOSIO和以太坊智能合约中的漏洞。第三,工作评估了EOSIO和以太坊智能合约上的WANA漏洞检测,并且WANA有效地识别了EOSIO和以太坊智能合约中的漏洞。其余部分的组织如下。
在第2节中,我们介绍了Wasm,EOSIO智能合约和以太坊智能合约的基础知识。然后在第3节中,我们回顾EOSIO和以太坊智能合约的典型漏洞。在第4节中,我们详细介绍了WANA框架的设计。之后,在第5节中,我们将进行全面的实验研究,以评估WANA在EOSIO智能合约上的漏洞检测方面的有效性。然后,在第6节中,将提供一个案例研究,以评估WANA在以太坊智能合约上的漏洞检测能力。在第7节中,我们介绍了对WANA检测到的智能合约的成功攻击。最后,在第8节和第9节中,我们介绍了相关的工作和结论。

二.WASM和智能合约的背景

简单介绍下 wasm和智能合约。

2.1.WASM

WebAssembly(简称Wasm)[42] [43]是基于堆栈的虚拟机的二进制指令格式。 WebAssembly虚拟机可以嵌入到Web浏览器或Blockchain平台中执行。 Wasm当前受EOSIO区块链平台支持。计划在Ethereum 2.0中进行以太坊Wasm VM替换以太坊VM(EVM)[12] [18]。 Wasm被设计为可移植目标,用于编译高级语言(如C / C ++ / Rust),从而可以在Web上为客户端和服务器应用程序进行部署。 Wasm旨在快速,安全和调试友好。结果,Wasm得到了所有主要网络浏览器的广泛支持[42]。 WebAssembly有两种等效的可转换表示形式:二进制格式(后缀“ .wasm”)和文本格式(后缀“ .wast”)。 Wasm代码用于执行,而Wast代码用于易于人为阅读和编辑。

2.2.EOSIO智能合约

2.2 EOSIO智能合约的背景EOSIO [23]是一个公共的区块链平台,专注于交易的可扩展性。 EOSIO平台使用委托权益证明(DPoS)共识协议,该协议比工作量证明(PoW)共识协议具有更大的可伸缩性。 EOS代币还代表其所有者持有的股份。 EOSIO平台支持智能合约,以使开发人员能够构建DApp。

在EOSIO平台上,有两种类型的智能合约。第一类是系统合约,是默认情况下部署在EOSIO平台上的智能合约,用于实现核心区块链功能,例如共识,费用表,账户创建和代币经济学[39]。 eosio.token智能合约[30]是这样一种系统智能合约,它定义了数据结构和操作,使用户能够在基于EOSIO的区块链上发行和转移令牌。第二种类型的智能合约是部署在EOSIO平台上的用户定义的智能合约[36],以实现特定的业务需求。

每个EOSIO智能合约都必须将应用功能作为输入功能来处理操作。所有传入的动作都被路由到apply函数[26],apply函数又将动作分派到相应的处理函数以进行处理。要开发EOSIO智能合约,推荐的语言是C ++ [28]。 C ++中的智能合约将被编译成Wasm字节码,以便在EOSIO Wasm VM上执行。 apply函数具有多个输入参数:接收方,代码和操作。接收者是当前正在处理操作的帐户。该代码是操作最初发送到的帐户。动作是动作的ID。当智能合约收到一个动作时,它可以使用require_recipient()函数将该动作转发给其他合约。

2.3.以太坊智能合约

在以太坊区块链平台上,有外部账户(即人为拥有的)和智能合约账户[33]。智能合约负责管理合约账户的余额和永久性私人存储。交易是从一个帐户发送到另一帐户的消息。从概念上讲,以太坊[31]可以被视为基于事务的状态机,其中其状态在每个事务上都会更新。当交易的目标帐户是智能合约帐户时,将执行其代码,并提供有效负载作为输入。在以太坊的现有版本中,智能合约代码在以太坊虚拟机(EVM)上执行。开发人员可以使用高级编程语言[37] Solidity编写智能合约,然后将其编译为EVM字节码。在即将发布的以太坊2.0中,计划将EWasm VM替换为EVM以用作智能合约执行引擎[12] [18]。特别是,EWasm是Wasm的受限子集,可用于以太坊中的合同。例如,它消除了智能合约执行期间的不确定行为。在以太坊区块链平台上,有外部账户(即人为拥有)和智能合约账户[33]。智能合约负责管理合约账户的余额和永久性私人存储。交易是从一个帐户发送到另一帐户的消息。从概念上讲,以太坊[31]可以被视为基于事务的状态机,其中其状态在每个事务上都会更新。当交易的目标帐户是智能合约帐户时,将执行其代码,并提供有效负载作为输入。

在以太坊的现有版本中,智能合约代码在以太坊虚拟机(EVM)上执行。开发人员可以使用高级编程语言[37] Solidity编写智能合约,然后将其编译为EVM字节码。在即将发布的以太坊2.0中,计划将EWasm VM替换为EVM以用作智能合约执行引擎[12] [18]。特别是,EWasm是Wasm的受限子集,可用于以太坊中的合同。例如,它消除了智能合约执行期间的不确定行为。

三.智能合约漏洞

在本节中,我们将回顾EOSIO和以太坊区块链平台中的智能合约漏洞。

3.1 EOSIO智能合约漏洞

我们将在本节中介绍WANA检测到的3个典型EOSIO智能合约漏洞

3.1.1 Fake EOS Transfer

在EOSIO平台中,智能合约必须通过eosio.token系统智能合约将EOS令牌发送到另一个智能合约。 eosio.token系统智能合约管理其内部存储中所有智能合约的EOS帐户。在转移期间,发送方合同必须调用eosio.token系统合同的转移功能。在eosio.token的转移功能内,发送方和接收方合同帐户的余额将进行相应调整。同时,eosio.token将在执行转移时调用require_recipient()来通知发送方和接收方合同。

在安全智能合约的套用功能内,必须确保转移操作的原始接收者(即套用功能的代码参数)为eosio.token。但是,如果受攻击的合同很容易受到攻击,因为在转移操作时,它不检查代码是否在其apply函数中包含eosio.token,则攻击者可以直接对其调用函数进行内联调用,以伪造EOS转让。结果,易受攻击的合同可能错误地认为攻击者已将EOS转移给了它。 EOSBet [24]和EOSCast [25]是两个带有伪EOS转移漏洞的合同,并且都遭受了严重损失。

如图1所示,在EOSBet合同的apply函数中,它仅检查代码是合同本身还是eosio.token(第5行),但不检查操作为时代码是否为eosio.token。转让。结果,攻击者合同可以直接调用易受攻击合同的转移功能进行投注,而无需花费任何EOS。如图2所示,修复漏洞的最佳实践是在apply函数中添加检查,以确保通过eosio.token系统合约(第6行和第7行)执行转移。换句话说,在转移操作时,代码必须是eosio.token。

/…待续…/

3.1.3 Block Information Dependency

在区块链平台上很难获得可靠的随机性来源。开发人员可能会想使用诸如tapos_block_prefixtapos_block_num之类的块信息来生成随机数。随机数可用于确定EOS的转移或彩票的中奖者。不幸的是,tapos_block_prefixtapos_block_num不是可靠的随机性来源,因为它们可以直接从ref_block_num(默认情况下最后一个不可逆块的ID)计算得出。赌博合同可以使用延期行动来确定彩票的赢家。在这种情况下,参考区是下注区之前的区。因此,当智能合约直接将tapos_block_prefixtapos_block_num用于随机数生成时,是可以预测生成的数字的。

EOSRoyale [31]是带有Block Information Dependency漏洞的EOSIO智能合约。如图5所示,它使用块号和块前缀的乘积作为生成随机数的种子(第7至9行)。因此,可以在下注之前计算用于随机数生成的变量。结果,攻击者成功地计算了随机数,赢得了赌博游戏,并获得了EOS奖品。
读研整活笔记(3):阅读论文 WANA Symbolic Execution of Wasm Bytecode..._第1张图片

3.2 以太坊智能合约漏洞

greedy 贪婪的智能合约可以接收以太币,但不包含将以太币发送到其他账户的功能。因此,这种智能合约将冻结发送给他们的任何以太币。对Parity钱包漏洞的第二轮攻击[41]是由于以下事实:许多智能合约仅依赖于 parity wallet 库来通过 delegateCall函数 管理其以太币。当通过初始化将 parity wallet 更改为合约然后被攻击者杀死时,这些依赖于奇偶校验库的钱包智能合约中的所有以太币都将冻结。

Dangerous DelegateCall 危险的DelegateCall。Delegatecall与消息调用类似,不同之处在于代码是通过调用合同的数据执行的[33]。这是在Solidity中实现“库”功能以实现代码重用的方式。但是,当Delegatecall的参数是msg.data时,攻击者可以操纵msg.data,以便攻击者可以使受害方达成协议以调用特定功能。该漏洞导致了第一轮 parity wallet 攻击的爆发[40]。电子钱包合约使用了以msg.data为参数的Delegatecall。结果,攻击者可以调用 _walletLibrary 的任何公共函数。然后,攻击者调用 _walletLibraryinitWallet 函数,并成为钱包合同的所有者。最终,攻击者将钱包中的以太币发送到自己的地址以完成攻击,这导致 parity wallet 用户损失了3000万美元。

Block Information Dependency 当以太坊智能合约使用区块时间戳或区块编号来确定关键操作(例如,发送以太币或确定彩票中奖者)时,存在区块信息依赖漏洞。实际上,区块时间戳和区块编号都是矿工可以操纵的变量,因此它们不能用作关键操作的可靠来源。例如,矿工可以在以太坊中的小间隔[35]内自由设置区块的时间戳。因此,如果以太坊智能合约基于时间戳传输以太币,则攻击者可以操纵区块时间戳来利用此漏洞。

四.WANA的设计框架

在本节中,我们将介绍用于跨平台智能合约漏洞分析的WANA符号执行框架的设计。

4.1 WANA的工作流程

如图6所示。WANA的输入是Wasm字节码。对于EOSIO智能合约,可以从EOSIO公共区块链中收集相应的Wasm字节码,也可以从EOSIO智能合约源代码进行编译。对于以Solidity编写的以太坊智能合约,可以从solidity-to Wasm编译器生成相应的字节码。

读研整活笔记(3):阅读论文 WANA Symbolic Execution of Wasm Bytecode..._第2张图片

首先,在我们的Wasm符号执行引擎中解析,加载和初始化Wasm字节码。结果,符号执行引擎的堆栈和内存已准备好执行。其次,符号执行引擎开始使用符号输入遍历Wasm代码的路径。在符号执行期间,符号执行引擎将调用Z3 [13]约束求解器来检查和修剪沿途无法满足的路径。同时,在符号执行期间收集对漏洞分析有用的执行信息。第三,WANA将基于符号执行过程中收集的执行信息执行漏洞分析。当检测到漏洞时,将生成相应的报告。请注意,步骤2和步骤3是迭代过程,其中漏洞分析和符号执行将相互交织。遍历所有代码后,整个工作流程结束。

4.2符号执行引擎

Wasm支持4种数据类型,包括两种整数数据类型和两种符合IEEE 754标准的浮点数据类型。 WANA符号执行引擎支持所有它们进行分析。

WebAssembly程序被组织为模块[34],这是部署,加载和编译的单元。对于EOSIO或以太坊智能合约,生成的Wasm字节码将对应一个模块。在加载和初始化阶段,WANA符号执行引擎将准备内存,表,全局变量和堆栈,作为用于在模块内执行Wasm指令的执行环境。对于模块,exports组件(导出组件?)定义了一组导出函数和数据结构,一旦实例化该模块,主机环境就可以访问它们。换句话说,导出的功能充当Wasm模块的公共接口。因此,WANA框架将通过迭代每个导出的函数来开始符号执行。

在导出的功能中,apply函数是用于为EOSIO智能合约分派操作的输入功能。对于以太坊智能合约,主要功能是用于与以太坊智能合约应用程序二进制接口(ABI)交互的输入功能。

对于模块中指令内的每个Wasm函数调用,WANA首先将准备一个框架作为其执行上下文,其中包括参数,局部变量,返回值以及对其模块的引用。然后,WANA将开始按符号顺序执行该函数的代码部分中的指令。 Wasm指令主要包括数字指令,存储指令,控制指令和函数调用指令。在WebAssembly规范版本1.0 [42]中的185条指令中,WANA实现了171条。

对于数字指令,WANA实现了基于堆栈的执行逻辑。 WANA符号执行引擎将弹出操作数,执行符号计算,并将结果推回堆栈。支持有关整数和浮点值类型的所有数字指令。

对于控制指令,有两种分支指令:无条件分支(例如br)和条件分支(例如br_if)。无条件分支(br)将直接跳至指令参数指定的标签以继续执行,这对于实现循环很有用。但是,当循环深度增加时,由于状态爆炸,符号执行引擎可能会非常缓慢或陷入陷阱。因此,WANA在路径探索过程中为每个标签的循环深度设置了上限。对于br_if指令,执行将取决于条件表达式的评估结果。 WANA将记录每个分支的执行上下文,并分别遍历每个分支以实现路径覆盖。对于每个分支,将在遍历之前将相应的路径约束输入到z3 [13]中以进行约束求解,这可以通过修剪那些不可行的路径来提高执行效率。

共有三种类型的内存操作指令:加载,存储和增加内存大小。 Wasm采用带有连续可变字节数组的线性内存模型[42]。程序可以在任何字节地址从/从线性存储器加载和存储值。由于在Wasm中有许多关于整数和浮点数据类型的位操作指令,因此我们选择在z3中用位向量数据类型表示整数和浮点数据类型。 WANA使用32位(64位)位向量数据类型来表示32位(64位)整数和浮点符号数据类型。由于字节数组无法存储位向量及其表达式,因此WANA使用线性列表存储具体值和符号值的引用来模拟内存。

在Wasm中,有两种类型的函数调用:直接函数调用和间接函数调用。对于间接函数调用,Wasm VM必须首先从堆栈顶部获取索引。然后,VM将使用索引从功能表中获取实际功能地址。有3种类型的函数可以直接调用:正在分析的当前Wasm模块的其他函数,其他Wasm模块的函数,EOSIO的API函数。对于当前Wasm模块中的功能,WANA将进入功能以继续符号执行。对于API函数或其他模块中的函数,WANA仍不支持其符号执行。因此,WANA将根据函数的返回类型随机生成一个具体值,这可能会导致合理但不完整的分析。对其他合同中的功能或API函数进行建模可能有助于改善WANA,这是我们将来的工作。

读者:对于API函数或其他模块中的函数,WANA仍不支持其符号执行。这个是WANA暂时的不足。

4.3漏洞检测算法

在本节中,我们将介绍EOSIO和以太坊智能合约的漏洞检测算法。

4.3.1 EOSIO智能合约的漏洞检测

待续
Block Information Dependency 检测块信息依赖漏洞的算法相对简单,我们将使用Wast表示进行说明。 WANA首先检查是否有对 $ env.tapos_block_prefix$env.tapos_block_num 函数的调用,以通过静态分析获取块信息。 然后WANA进一步检查是否有对 $env.send_inline$env.send_deferred 函数的调用,以在正在分析的智能合约中发送EOS。 在分析期间,将标记收集块信息和发送EOS的位置。 最后,WANA执行符号执行以检查从块信息收集到EOS转移是否至少存在一条可行路径。 如果存在一个或多个这样的可行路径,则该合同被报告为具有“块信息依赖”漏洞。

4.3.2以太坊智能合约的漏洞检测

在本节中,我们将介绍检测以太坊智能合约中的 greedyDangerous DelegateCallBlock Information Dependency 漏洞的算法。为了便于理解,我们还将在Wast表示中使用函数名称来描述本节中的漏洞检测算法。在Wasm中,每个函数名称都对应一个32位整数。函数名称和32位整数之间的映射可以在符号执行引擎内的智能合约加载期间收集。

greedy 如果以太坊智能合约可以接收以太币但不能发送以太币,则被视为贪婪。贪婪的智能合约将冻结其收到的任何以太币。

为了检查以太坊智能合约是否可以接收以太币,WANA会检查在 main 函数中是否有至少一项 payable 函数。 WANA计算函数总数和non-payable函数的总数,以计算payable 函数的数量。特别是,以太坊中的non-payable函数将使用*$ethereum.getCallValue*进行初始化,这很容易识别。

读者疑问:为什么不能直接计算payable函数的数量呢?也许是因为$ethereum.getCallValue可以直接计算non-payable函数的数量

为了检查智能合约不能发送以太币,WANA首先检查智能合约的字节码中是否有 $ethereum.call 函数。如果智能合约的字节码中没有任何 $ethereum.call 函数,则合约无法发送任何以太币。但是,如果有一些 $ethereum.call 函数,则WANA将通过符号执行进一步检查从 main 函数到任何 $ethereum.call 函数的可行路径。如果没有通向其中任何人的可行途径,则合同也将无法发送任何以太币。

读者总结:判断逻辑如下:
if(存在payable函数且没有转钱的路径):发生了greedy
疑问,如果存在payable且有转钱路径,那么一定没有greedy错误吗?

Dangerous DelegateCall 为了检测Dangerous DelegateCall漏洞,WANA通过入口函数检查是否可以调用DelegateCall()函数(即Wast中的$ ethereum.callDelegate),以及是否可以通过攻击合同来操纵指定由DelegateCall()调用的函数的输入参数。
为了确定所调用的函数是否可操纵,WANA会检查 $ethereum.callDelegate 的第一个参数(即要调用的函数)是否为常数。如果不是恒定值,则检测到漏洞。

Block Information Dependency 以太坊智能合约的阻止信息依赖漏洞检测与EOSIO智能合约相似。 WANA还根据符号执行检查从块信息收集到以太坊传输的至少一条可行路径的存在。唯一的区别在于实现细节。在以太坊中,区块信息收集函数 是$ethereum.getBlockNumber$ethereum.getBlockTimestamp$ethereum.getBlockHash ,而以太币传递函数是 $ethereum.call

你可能感兴趣的:(读研,区块链,区块链)