区块链合约安全系列(二):如何认识及预防公链合约中的重入攻击漏洞

Connor 币安下载 2022-09-05 230 0

背景:由于公链环境下所有的信息都是共享的,智能合约相当于是完全透明化,任何人都可以调用,外加一些利益的驱动,导致引发了很多hacker的攻击块链智能合约。其中重入 (Re-Entrance) 攻击是以太坊中的攻击方式之一,例如The DAO 事件被盗取了大量的以太币从而造成了以太坊的硬分叉。

目标:将目标合约里的所有资金(ether)进行盗取,从而认识以及预防重入攻击漏洞块链智能合约

对象:适用于用Solidity语言开发的智能合约,例如BSN中的武汉链(基于ETH)和泰安链(基于 fisco bcos)上运行的智能合约块链智能合约

前言

在进入今天的正题之前块链智能合约,我们先来看一段典型的有重入漏洞的代码:

区块链合约安全系列(二):如何认识及预防公链合约中的重入攻击漏洞

上述方法的业务也很简单,提取调用者存入的钱,成功后将其余额设为零块链智能合约

不知道大家脑海里有没有发出这样的疑问:这怎么就存在重入漏洞了呢块链智能合约

如果你存在这样的疑惑,那么请由我来讲解一下其中的知识块链智能合约。在开始之前需要大家清楚几个知识点:

什么是重入块链智能合约?官方的解释如下:

区块链合约安全系列(二):如何认识及预防公链合约中的重入攻击漏洞

为方便记忆,暂且可以简单的理解为我们开发者传统印象中的递归块链智能合约

2.特殊函数

展开全文

这里的特殊函数是指在合约交互发送ether转账时,会隐式触发调用的函数,包含receive和fallback块链智能合约。官方的解释如下:

区块链合约安全系列(二):如何认识及预防公链合约中的重入攻击漏洞

通俗的来说就是当你的合约接收ether时,必须至少包含这俩函数中的一个块链智能合约

3.转账操作

什么是转账???对,没错,就是你脑子里想的那样块链智能合约。在这里是指在两个以太坊账户之间的发送和接收ether的操作。但需要知道的一点是以太坊上的账户分为两种,即普通账户和合约账户。

在以太坊上转账操作常见的函数包括三种.transfer()、.send()和.call{value:xxx}("")

在各位了解了基本的知识后,下面我们开始进入今天的正题:我将通过一个示例来进行演示,通过重入漏洞,盗取一个“银行”里的全部资金块链智能合约

示例涉及到两个合约,一个为资金管理合约,一个为攻击者合约块链智能合约。其完整代码如下:

区块链合约安全系列(二):如何认识及预防公链合约中的重入攻击漏洞

合约部署

为其方便演示在此使用remix进行测试环境准备块链智能合约。首先,部署资金管理合约,并初始化存入100Wei(为显示方便,其金额任意)。结果如下:

区块链合约安全系列(二):如何认识及预防公链合约中的重入攻击漏洞

然后块链智能合约,部署攻击者合约,结果如下:

区块链合约安全系列(二):如何认识及预防公链合约中的重入攻击漏洞

重入攻击

首先,存入ether块链智能合约。因为资金管理合约的提款逻辑为提取自己已存入的,所以我们需要先存入。结果如下图:

区块链合约安全系列(二):如何认识及预防公链合约中的重入攻击漏洞

然后,提取ether,利用重入漏洞将额外的资金进行盗取块链智能合约。交易执行成功后,查询提取的资金信息,结果如下图:

区块链合约安全系列(二):如何认识及预防公链合约中的重入攻击漏洞

该笔交易的事件日志信息如下:

区块链合约安全系列(二):如何认识及预防公链合约中的重入攻击漏洞

另外块链智能合约,我们查看一下资金管理合约的余额信息,查询结果如下图:

区块链合约安全系列(二):如何认识及预防公链合约中的重入攻击漏洞

解决方案

通过上面的示例块链智能合约,细心的朋友可能已经大概明白,其实重入攻击漏洞是因为触发了特殊函数(receive或者fallback)造成递归调用转账,目前常用的解决方案有下面几种:

方案一、 使用安全的转账函数

使用内置的 transfer或send 函数,因为transfer和send在转账时会传递2300Gas,不足以执行重入调回合约操作,而.call会传递所有可用的Gas(当然也可以设置传递可用的Gas)块链智能合约

方案二、使用官方推荐的检查-生效-交互模式 (checks-effects-interactions)

区块链合约安全系列(二):如何认识及预防公链合约中的重入攻击漏洞

方案三、使用专门针对重入攻击的安全合约

例如OpenZeppelin 官方库中的安全合约ReentrancyGuard.sol

区块链合约安全系列(二):如何认识及预防公链合约中的重入攻击漏洞

今天的讲解到此结束,感谢大家的阅读,如果你有其他的方案,欢迎一块交流块链智能合约

评论