区块链智能合约安全威胁实时防御框架法

  点击数:169  发布时间:2020-06-16 09:40
区块链是当前炙手可热的技术,其不可篡改、不可伪造、不可抵赖、可追溯、无需第三方可信机构、支持智能合约等特性,为包括医疗、物流、电商、金融、教育等行业赋能。近年来,区块链安全尤其是区块链智能合约安全事件层出不穷。因此,在线监测区块链安全威胁,并对安全威胁做出处置,具有重大研究意义和实用价值。深入研究智能合约运行时信息获取、智能合约虚拟机插桩等技术,提出了一种针对区块链安全威胁的实时防御框架,并利用该框架,以重入攻击、整数溢出攻击为威胁示例开展防御逻辑分析,以期能对该框架的应用提供思路。
关键词:智能合约 ,区块链 ,安全威胁

区块链是当前炙手可热的技术,其不可篡改、不可伪造、不可抵赖、可追溯、无需第三方可信机构、支持智能合约等特性,为包括医疗、物流、电商、金融、教育等行业赋能。近年来,区块链安全尤其是区块链智能合约安全事件层出不穷。因此,在线监测区块链安全威胁,并对安全威胁做出处置,具有重大研究意义和实用价值。深入研究智能合约运行时信息获取、智能合约虚拟机插桩等技术,提出了一种针对区块链安全威胁的实时防御框架,并利用该框架,以重入攻击、整数溢出攻击为威胁示例开展防御逻辑分析,以期能对该框架的应用提供思路。

区块链是当前炙手可热的技术,其不可篡改、不可伪造、不可抵赖、可追溯、无需第三方可信机构、支持智能合约等特性,为包括医疗、物流、电商、金融、教育等行业赋能。然而,作为各种分布式应用(Decentralized Application,DApp)的底层技术,区块链本身的安全性将从根本上决定上层分布式应用的安全性、可用性以及性能。

区块链部署于互联网中,而互联网存在着各种网络威胁。尤其是区块链及其上的分布式应用涉及到大量的金钱,区块链成为黑客的一个重要攻击目标。近年来,区块链安全事件层出不穷,从底层P2P网络、中间层虚拟机到上层的智能合约,都成为黑客们攻击的对象。下面列举一些区块链威胁的例子。

Marcus等人发现以太坊P2P网络节点发现机制的缺陷,利用该缺陷实现了日蚀攻击,导致被攻击节点被隔绝等。由于以太坊虚拟机没有校验地址的位数,并自动补齐缺失的位,将会导致短地址攻击,黑客可以利用该虚拟机漏洞盗取各种代币。

智能合约的漏洞更是层出不穷,其中最著名的是2016年发生的TheDAO合约重入漏洞攻击。TheDAO合约通过众筹,在合约中存储了价值数千万美元的以太币。黑客利用合约的重入漏洞,盗取了高达6千万美元的以太币,并导致以太坊分叉为了ETH和ETC。2018年以来,多款代币合约被爆发现整数溢出漏洞,黑客利用这些漏洞发动了整数溢出攻击,导致了大量代币被盗。

区块链的安全威胁已经成为制约区块链未来发展的关键问题,因此如何在安全威胁进行在线检测,并实时对安全威胁做出处置,具有重大的研究意义和实用价值。

本文以智能合约运行时信息获取、智能合约虚拟机插桩、安全威胁检测技术为基础,提出了一种区块链安全威胁实时防御框架,并基于重入攻击、整数溢出攻击讨论该框架的应用逻辑,为该框架在区块链安全威胁防护研究和实践提供参考思路。

1 区块链安全威胁分析

1.1 区块链层次结构

以以太坊(Ethereum)为例,区块链结构主要包含应用层、数据层、共识层以及网络层4层,如图1所示。

网络层,区块链采用对等(Peer-to-Peer)网络技术组织各个节点,主要包括节点发现、传播机制和验证机制。

共识层,主要包含共识机制和激励机制。共识机制是用来维护区块链中对等节点间达成一致的策略和方法。典型的共识机制包括工作量证明(Proof of Work,PoW)、权益证明(Proof of Stake,PoS)和股份授权证明(Delegate Proof ofStake,DPoS)等;激励机制主要包括发型机制和分配机制,通过引入奖励和惩罚来引导区块链节点遵循规则,实现区块链系统的良性运行。

数据层,主要包括数据区块、交易以及事件,包含区块链中的各种数据结构。

应用层,包括账户、智能合约以及运行智能合约的虚拟机(Environment VirtualMachine,EVM)。智能合约的出现,为区块链提供了可编程特性。通过编程的方式设计智能合约,预先定义特定行为和触发的状态,从而实现在没有第三方的情况下,智能合约达到触发条件就自动执行。

1.2 基于区块链层次结构的威胁分析

根据区块链层次结构,区块链安全威胁主要分为网络层安全威胁、共识层安全威胁、数据层安全威胁以及应用层安全威胁。

网络层安全威胁。因为区块链网络结构为对等网络,因此P2P网络面临的安全威胁也会对区块链网络层造成安全威胁。这些攻击包括拒绝服务攻击、日蚀攻击等。此外,RPC API漏洞暴露可能导致账户劫持攻击。

共识层算法安全威胁。它主要对共识机制发起攻击,控制区块链按照对攻击者有利的方向发展。目前主要的共识层攻击有51%攻击、自私挖矿攻击、女巫攻击等。

数据层安全威胁。由于区块链的公开、不可篡改、分布等特性,容易导致数据层遭受隐私泄露、恶意信息传播等攻击。

应用层安全威胁。它包括针对虚拟机、智能合约及其他攻击。虚拟机没有校验地址的位数,将会导致短地址攻击。智能合约的攻击包括重入攻击、整数溢出攻击等。其他攻击则包括面向应用提供接口的攻击、Parity多重签名钱包攻击等。

应用层安全威胁种类多样,且已经暴露出来的针对应用层的安全威胁直接造成了巨大的经济损失,因此本文聚焦于对应用层攻击的防御框架的研究。

2 区块链信息获取方法研究

区块链信息是进行实时防御的核心要素,目前在区块链信息获取领域已有大量研究。这些研究主要可以将获取方法分为4类:下载与区块文件解析、调用Web3 API、爬取区块链浏览器以及插桩区块链节点。下面将对这4种方法进一步展开描述。

2.1 下载与区块文件解析

区块链节点在同步过程中会从其他节点下载区块文件,所以可以通过解析区块文件获得区块链信息。Kiffer等人采用这种方法获取数据,用以研究以太坊的硬分叉。MAIAN是一款智能合约安全漏洞自动化发掘工具,该工作也通过此方法获得智能合约字节码用以漏洞发掘。

2.2 调用Web3 API

以太坊提供了一套API,用户可以通过调用这些API获取区块链信息。文献[10]中开发的欠优化智能合约检测系统即是调用API,web3.eth.getCode()获取智能合约字节码。文献[11]是调用API,debug.traceTransaction()获取智能合约的执行轨迹,用以计算虚拟机操作码的执行次数。Bartoletti等人设计了一款针对比特币和以太坊的数据搜集框架,也是通过调用比特币节点和以太坊节点提供的API实现的。EtherQL通过调用以太坊节点名为EthereumJ提供的API来获取数据。

2.3 爬取区块链浏览器

区块链浏览器如Etherscan向网站访问者展示区块链数据,因此可以通过爬取区块链浏览器的网页获取数据。ZEUS通过这种方式爬取智能合约源代码并基于形式化分析检测合约漏洞。两份最新的研究也是通过爬取Etherscan、Etherchain和EtherCamp获取智能合约字节码,然后检测智能合约中的旁氏合约。Huang等人爬取数据用于估计挖矿和投资收益。Bartoletti等人基于两个数据集对智能合约进行统计分析,这两个数据集分别来自于以太坊区块链浏览器和比特币区块文件。

2.4 插桩区块链节点

区块链节点同步区块重放所有的交易并在虚拟机中执行智能合约,因此可以通过插桩区块链节点获取信息。文献[19]插桩了节点Geth来获取交易的发送者、接收者和交易金额用于复杂网络的分析。Grossman通过这种方法获取内部交易信息与storage的运行时信息,用以检测智能合约的无回调对象。文献[21]通过GasReducer的方法获取智能合约执行轨迹用于衡量GasReducer的优化效果。

现存的技术或多或少存在以下3个问题:数据获取不完整、数据信息混淆以及数据获取效率低。文献[22]研究设计了一款区块链数据搜集框架,名为DataEther,解决了上述问题。因此,本项目沿用DataEther的方法获取区块链数据,从而为本文的区块链安全威胁实时防御框架提供数据基础。

3 区块链安全威胁实时防御框架

3.1 设计目标

研究高扩展的区块链安全威胁实时防御框架,围绕以下几个目标开展对防御框架的设计:

(1)获取完备的智能合约执行信息;

(2)设计可扩展框架,允许在不修改虚拟机的前提下,检测新类型的安全问题;

(3)基于设计框架讨论对实际攻击的应用逻辑。

3.2 安全框架设计

区块链安全威胁实时防御框架如图2所示,由基于智能合约虚拟机的插桩点、区块链信息获取模块、威胁检测模块以及安全威胁处置模块组成。它主要实现的功能包括智能合约运行时信息获取、威胁检测以及安全威胁处置。

3.2.1 智能合约运行时信息获取

本文设计通过对智能合约虚拟机进行插桩来实现对智能合约运行时信息的完备提取。智合约运行时信息获取的详细设计见3.3节。区块链信息获取模块收集智能合约虚拟机插桩点采集数据,并将数据传递到监测模块中的威胁检测中间件做威胁检测。

3.2.2 威胁检测

威胁检测主要的执行单元是威胁检测模块。威胁检测模块由威胁检测中间件和可扩展检测算法库构成。

威胁检测中间件实现对可扩展检测算法库中检测算法的注册、调度和卸载,实现智能合约运行时信息从区块链信息获取模块到检测算法的数据传递,实现将威胁检测结果发送到安全威胁处置模块。

可扩展检测算法库由多个检测算法组成,算法库自身是可缩减可扩展的弹性架构。根据检测需要,通过威胁检测中间件,注册添加新的检测算法。注册检测算法的同时,将算法所需的数据信息事件注册威胁检测中间件,威胁检测中间件将所需的信息事件内容通知到区块链信息获取模块,信息获取模块根据事件需求将插桩点采集到的智能合约运行时信息处理后上传到威胁检测中间件。

详细的事件通知设计见3.4节。检测算法根据威胁检测中间件提供的数据实现威胁检测,并将结果传递回威胁检测中间件。检测算法库中,检测算法的生命周期包括注册、更新、卸载以及使用调度。这些生命周期管理都在威胁检测中间件完成。

3.2.3 安全威胁处置

安全威胁处置模块收到威胁中间件发出的威胁检测结果,根据结果情况提供不同的安全威胁处置。安全威胁处置跟进一步的设计见3.5节。

3.3 智能合约运行时信息获取

智能合约运行时信息获取是为检测智能合约安全问题做准备,其中的关键点是保障运行时信息的完备性。考虑到未来可能会出现新种类的安全威胁,所以采集部分运行时的信息是不可取的。本文对合约执行的两个阶段进行插桩,从而确保信息获取的完备性。

第一阶段,外部交易提交阶段。由于智能合约执行必须由外部交易触发,所以对外部交易提交阶段插桩,能够准确得知智能合约的初始执行信息,包括交易hash、交易发送方、智能合约地址、以太币数量、汽油上限、汽油定价、调用的函数ID、函数参数以及创建的合约字节码等。

第二阶段,智能合约解释执行阶段。虚拟机内建了一个解释执行器对智能合约进行解释执行,因此本文对解释执行器插桩能够获得每一条字节码的执行情况。

智能合约包含超过130种字节码,而针对每一种字节码,解释执行器都提供了一个对应的解释执行例程。因此,本文将对所有的解释执行例程插桩,获取的信息包括读/写的栈(stack)内容、读/写的存储器(memory)内容、读/写的仓库(storage)内容。除此以外,本文将对以下6种字节码的解释执行例程进行特别插桩处理,因为这6种字节码会产生内部交易。

CREATE:用于创建新合约,因此本文将额外获取被创建合约的字节码和合约地址。

CALL/CALLCODE/DELEGATECALL/STATICCALL:用于调用合约,因此本文将额外获取被调用合约的字节码、被调函数ID、调用参数以及汽油限制。

SELFDESTRUCT:用于销毁合约,因此本文将额外获取合约被销毁时残留的以太币和以太币的接收合约地址。

此外,本文介绍的方法还将记录智能合约运行时的环境信息,包括区块高度、挖矿难度和时间戳等。

插桩代码和虚拟机原本代码共享计算资源,因此插桩代码的执行会带来运行时开销(runtime overhead)。除了采集信息的完备性,本文提出一种按需(on-demand)的虚拟机插桩方法,降低了运行时开销。这种按需插桩的基本思路并不在一开始就将所有的插桩点全部插桩,而是根据用户编写的检测程序注册的事件通知,在需要的位置插桩。

3.4 事件通知

用户在编写检测程序时,需要注册事件处理例程,只有注册后才会收到相应的事件通知。为了确保检测程序能够接收到完整的智能合约运行时信息,实现字节码级的检测,本文提供了两类事件通知。

(1)交易执行TransApply(INFO):当外部交易或内部交易执行时生成此事件,检测程序将得到交易所有信息和环境信息。

(2)字节码执行ExeOp(INFO):每一条字节码执行时都将生成此事件,检测程序将得到该字节码的运行时信息和环境信息。

虽然通过上面两种事件通知,检测程序能够获得完整的智能合约运行时信息,但两种事件可能过于底层,需要用户对虚拟机有较强的掌握。为了降低用户的使用难度,本文定义如下具有一定语义的事件。

(1)合约创建ContractCreate(INFO):当合约创建时生成此事件,检测程序将得到合约创建时所有的运行时信息,包括被创建合约的字节码和环境信息。

(2)合约调用ContractInvoke(INFO):当合约调用时生成此事件,检测程序将得到合约调用时所有的运行时信息,包括被调用合约的字节码和环境信息。

(3)合约销毁ContractDestruct(INFO):当合约调用时生成此事件,检测程序将得到被销毁合约地址、残留以太币数量、接收残留以太币的账户以及环境信息。

(4)基本块执行ExeBB(INFO):每个基本块第一条字节码执行时生成此事件,检测程序将得到基本块第一条字节码地址和环境信息。

(5)算数操作被执行ExeArith(INFO):当算数操作被执行时生成此事件,检测程序将得到该算数操作的运行时信息和环境信息。

(6)位操作被执行ExeBit(INFO):当位操作被执行时生成此事件,检测程序将得到该位操作的运行时信息和环境信息。

(7)跳转操作被执行ExeJump(INFO):当跳转操作被执行时生成此事件,检测程序将得到该跳转操作的运行时信息,包括跳转目标,以及环境信息。

(8)日志产生LogProduce(INFO):智能合约通过记录日志向区块链外发送信息,当日志产生时生成此事件,检测程序将得到日志信息以及环境信息。

3.5 安全威胁处置

当检测程序检测到安全威胁时,需要处理安全威胁。由于智能合约在虚拟机内运行,而检测程序在虚拟机外,因此本文拟修改虚拟机,在虚拟机中内建多个威胁处理模块。检测检测程序检测到威胁后,给虚拟机的威胁处理模块发送命令,执行用户指定的处理措施。常见的威胁处理措施包括中止当前智能合约的执行、禁止调用危险合约以及禁止创建恶意合约。

4 基于实时防御框架的防御示范

基于本文提出的区块链安全威胁实时防御框架,以整数溢出攻击和重入攻击作为典型攻击,示范讨论该框架的防护逻辑,以期对区块链实时防御框架的进一步研究及应用提供参考思路。

4.1 重入攻击检测

4.1.1 威胁描述

若智能合约A存在重入漏洞,则A在执行过程中会调用合约B,而合约B又会调用合约A,形成一个调用环。若重入漏洞被攻击者利用,可能引起严重的安全问题,尤其是当该调用环在一次外部交易提交过程中被多次执行时。例如:TheDAO合约存在重入漏洞,攻击者攻击该漏洞偷走了价值超过6千万美元的以太币[3]。这次安全事件也是造成以太坊分裂为ETH和ETC的直接原因。

4.1.2 检测思路

检测重入攻击的基本思路是检测外部交易是否使得合约调用出现环结构。为了检测调用环,需要知道外部交易和内部交易信息,所以检测程序需要注册交易执行的事件通知TransApply,并在事件处理函数中实现检测功能。下面首先给出重入攻击的形式化定义,然后给出实时的重入攻击检测方案。首先定义一个结构,称之为单交易图OG,这是由一个外部交易引起的交易图,是一个5元组数据。

(1)ACC,单个外部交易涉及的所有账户的集合。

(2)EOA,外部交易的调用者,EOA ACC。

(3)T,单个外部交易及其触发的所有内部交易的集合。

(4)N,自然数集合,表示T中各交易的相对顺序,其中外部交易的顺序为1。

(5),1.jpg迁移函数,2.jpg,例如3.jpg

在一个单交易图OG中,若存在一个账户4.jpg使得5.jpg,则认为OG中出现了调用环,可认为该交易是重入攻击。为了降低可能的误报,本方案允许用户设置一个阈值,当调用环执行次数大于该阈值才认为是重入攻击。

本方法基于实时的调用环检测,即当调用环即将形成时检测出调用环,而不是外部交易完全执行完后再检测。本方法的优势在于可以在攻击过程中予以检测和阻断;如果等外部交易完全执行后再检测,则一次攻击已经完成,无法做到及时阻断,且可能造成误报。下面基于图2描述本方案的调用环检测过程。

图3中,一个外部账户EOA调用了合约A,A在执行过程中陆续调用了其他5个合约。本例涉及一个外部交易(1)和8个内部交易(2~9),交易的由图中数字按从小到大的顺序执行。如果在外部交易提交完成后检测调用环,将会得到图中3的调用图。从图3可以发现3个调用环,分别为2→3→7、5→6→7和8→9→7。但是,由于交易执行存在顺序,所以只有5→6→7是真正的调用环,其余两个为误报。

本方法设计的检测程序注册了交易执行的事件通知,而事件的获取是通过虚拟机插桩实现的,所以事件通知的顺序完全按照交易执行的顺序。因此,事件处理例程的执行顺序也是按照交易执行的顺序,则本文提出的方法能够获知交易执行顺序。本文设计了交易表用以检测调用环,如图4所示。

发送者集合表示某外部交易执行过程中所有出现的发送者;接收者表示当前(外部或内部)交易的接收者。交易表按照交易执行顺序从上到下排列。当有新的交易产生时,检测当前交易的接收者是否出现在发送者集合中。若出现,说明合约执行出现了调用环,本方法继而回溯到目前为止的交易,匹配交易的发送者和接收者,直到形成闭环。以图3为例,当交易7执行时,本方法检测到调用环,因此在交易8和交易9产生前即可实时采取应对措施。

4.2 整数溢出攻击检测

4.2.1 威胁描述

整数溢出是智能合约的一类出现频率很高的安全问题,可能导致严重的后果,尤其是各种代币被盗。2018年4月的报道披露了8个存在整数溢出漏洞的代币合约[4]。整数溢出是一类传统的安全问题,在x86代码中也普遍存在。但是,在区块链智能合约领域中,整数溢出会带来直接的经济损失,因此检测整数溢出攻击是保障区块链安全的重要措施。

4.2.2 检测思路

整数溢出由算数操作引起,所以检测程序本应注册算数操作被执行的事件ExeArith。当事件处理例程被调用时,将会收到算数操作的信息,包括算数操作类型和操作数。检测算数操作是否会产生溢出是容易的,但只要溢出就认为发生了整数溢出攻击会带来大量的误报,在实际应用中是不能接受的。

图5是一个算数运算库的代码,作用是防止整数溢出。当加法溢出时(语句2),中止执行智能合约(语句3)。所以,如果智能合约调用该库中的函数,即使发生了整数溢出,也不会带来安全问题。所以,认为图5的加法函数存在整数溢出漏洞是误报。

为了解决整数溢出检测的高误报问题,本方案提出基于污点分析排除误报。污点分析是安全领域常用的技术,由污点源、污点传播和污点槽(taint sink)3大组件组成。本方案将整数溢出的运算结果和操作数标记为污点源,如图5中的a、b、c;监控所有的EVM操作,追踪污点传播;如果污点传播到污点槽即一些关键位置,则认为发生了整数溢出攻击。典型的污点槽包括仓库、内部交易的参数以及合约返回值。下面给出整数溢出攻击检测时用到的污点分析规则。

6.jpg

其中,8.jpg7.jpg的操作结果;9.jpg表示操作结果有溢出;10.jpg表示任意操作本身是污点;Arith表示算术运算;11.jpg表示所有操作数和结果都被标记为污点;

式(1)是算数运算采用的污点分析规则,如果任意操作数本身就是污点或者算数运算的结果溢出,那么算数运算的所有操作数和结果都被标记为污点。

12.jpg

其中,OP表示EVM操作;13.jpg表示将操作结果标记为污点。

式(2)是通用的污点分析规则,当EVM操作不是算数操作也不是污点槽操作时匹配此规则。当EVM操作的某个操作数是污点,那么操作的结果也被标记为污点。

14.jpg

其中,SSTORE/INVOKE/RET表示污点槽操作,分别对应写仓库、内部交易和合约返回值操作。

式(3)是污点槽采用的污点分析规则,如果污点槽操作(写仓库、内部交易、合约返回值)的操作数是污点,则检测到了整数溢出攻击。

采用污点分析后,由于图5中的污点源没有传播到污点槽,所以本方案可以排除误报。图5是CVE-2018-13746披露的智能合约整数溢出漏洞,有漏洞的合约叫kBit。图6中,语句2的加法运算存在溢出漏洞,溢出后的结果将会存储在balances[target]中,而balances是位于仓库中的全局变量,所以语句2执行时,检测程序认为是整数溢出攻击。

为了实现污点分析,检测程序需要监控每条EVM操作的执行情况,因此检测程序注册字节码执行事件ExeOp。这样每条字节码执行时,事件处理例程都将得到通知,检测程序在事件处理例程里实现对污点源的标记与跟踪。

5 结语

本文针对区块链应用层安全威胁,深入研究智能合约运行时信息获取、智能合约虚拟机插桩和安全威胁检测技术,提出了一种检测算法可扩展的区块链安全威胁实时防御框架。该框架设计了基于虚拟机插桩智能合约运行时信息全面采集方式,威胁检测算法注册、管理、调度机制以及检测结果与处置方法联动机制,利用本文提出的实时防御框架,开展基于重入攻击、整数溢出攻击的防御逻辑讨论,为该框架在区块链安全威胁防护研究和实践提供了参考思路。

作者简介 >>>

白杨(1988—),女,硕士,工程师,主要研究方向为信息安全、数据安全、云计算安全。

选自《通信技术》2020年第六期 (为便于排版,已省去原文参考文献)

来源:信息安全与通信保密杂志社

相关文章


热点新闻
推荐产品