Page 283 - 《软件学报》2021年第5期
P. 283
田国华 等:区块链系统攻击与防御技术研究进展 1507
技术具备了较高的可编程性和实用性.本节将从智能合约和合约虚拟机两方面对区块链合约层存在的安全威
胁进行分析,并尝试给出应对策略.
5.1 针对智能合约的攻击
智能合约是区块链 2.0 的标志性技术.图灵完备的区块链网络允许用户在区块链网络上开发并部署特定的
代码或应用,但智能合约在编写过程中存在的诸多不足,可能给区块链网络带来以下安全隐患.
(1) 整数溢出漏洞(integer overflow and underflow vulnerability) [86] :智能合约代码中,整数型变量都存在上
限或下限,当变量存储的数值超过上限则称为整数上溢,超过下限则称为整数下溢.当一个整数变量
发生溢出时,可能会从一个很大的数变成很小的数或者从一个很小的数变成很大的数.利用这个漏
洞,攻击者通常通过输入异常参数致使整数溢出,从而达到修改地址指针,实现代码异常调用的目的.
2010 年 8 月,由于验证机制中存在大整数溢出漏洞 [87] ,比特币的第 74 638 块出现了一条包含超过
1 844 亿个比特币的交易.2018 年 4 月,BeautyChain(BEC)智能合约中出现了一个灾难性的整数溢出漏
洞 [88] ,导致约 10 亿美元的损失.
(2) 时间戳依赖攻击(time-stamp dependency attack) [89] :智能合约的执行大多依赖于当前区块的时间戳,不
同的时间戳可能导致智能合约产生不同的执行结果.以抽奖合约为例:假设智能合约需要根据当前时
间戳和其他可提前获知变量计算出一个“幸运数”,以确定获奖人员.攻击者则可以在挖矿过程中提前
尝试使用不同的时间戳来计算“幸运数”,从而将奖品送给自己想给的获奖者.
(3) 调用深度攻击(call deep attack) [90] :合约虚拟机在运行过程中会为合约相互调用的深度设置一个阈值,
即使合约调用不存在任何逻辑问题,但当调用深度超过该阈值后,合约将不再往下执行,即合约调用
失败.例如在以太坊虚拟机中,调用深度被限制为 1 024.如果攻击者发起一系列递归调用让栈的深度
到达了 1 023,之后再调用目标智能合约的关键函数,就会自动导致这个函数所有的子调用失败.因此,
攻击者可以通过控制调用深度,使得某些关键操作无法执行.例如在区块链上实现一个拍卖的智能合
约,由于拍卖过程中可能存在多次竞价,需要反复调用合约中的出价函数,攻击者可以恶意刷出价次
数.当调用深度达到 1 023 次临界值时竞拍结束,此时调用转账函数就会失败,导致拍卖失败.
(4) 误操作异常攻击(misoperation attack):攻击者通过智能合约 A 调用智能合约 B 时,B 可能因为执行异常
而返回合约未执行的状态,若 A 不检查 B 的结果而继续执行,则将导致 A 在 B 未执行的情况下完成调
用.以 KoET 智能合约 [91] 为例:网络中各节点可以通过智能合约买卖“以太币国王”称号来获利,支付金
额由现任国王来决定.当一个节点想购买“国王”称号时,智能合约 A 调用智能合约 B 支付赔偿金给现
任国王,并指定该节点成为新的国王.如果 B 因为操作异常(如调用深度攻击)导致支付失败,而 A 在未
检查 B 执行结果的情况下继续执行,将导致节点在未支付赔偿金的情况下成为新的“国王”,原“国王”
同时失去国王称号和赔偿金.
(5) 重入攻击(re-entrancy attacks) [92] :攻击者针对智能合约代码的重入漏洞发起的攻击,可导致两个智能
合约发生循环调用.其中最具代表性的是 DAO 攻击 [93] :攻击者通过智能合约 A 向智能合约 B 发起提
现请求,B 向 A 转账并调用 A 的回调函数.此时,若 A 的回调函数中被攻击者写入操作“合约 A 向合约
B 发起提现请求”.如此,A 再次向 B 发起提现请求并重复提现过程,直至提现失败(账户余额不足).2016
年 6 月发生了一起史上最严重的智能合约安全事件——“The DAO” [94] ,导致价值 6 000 万美元的以太
币被盗,迫使以太币硬分叉为以太坊 ETH 和以太经典 ETC.
5.2 针对合约虚拟机的攻击
合约虚拟机是智能合约的调用、执行平台,是区块链技术支持多样化应用的载体,提高了区块链的可扩展
性,但仍然可能存在一些安全隐患.
(1) 逃逸漏洞(escape vulnerability) [95] :攻击者在控制一个虚拟机的前提下,通过利用虚拟机和底层监控器
(virtual machine monitor,简称 VMM)的交互漏洞,实现对底层 VMM 或其他虚拟机的控制.虚拟机逃逸