摘要:重入攻击本质上与编程里的递归调用类似,当合约将以太币发送到未知地址时就可能会发生,威胁以太坊智能合约的安全性。知道创宇区块链安全实验室?从转账方法、fallback函数、漏洞代码、源码分析四个方面入手,深入分析攻击原因,详解?The?DAO事件。
前言
智能合约的概念于1995年由NickSzabo首次提出,它是一种旨在以信息化方式传播、验证或执行合同的计算机协议,它允许在没有第三方的情况下进行可信交易,这些交易可追踪且不可逆转。
然而智能合约也并非是安全的,其中?重入(Re-Entrance)攻击?漏洞是以太坊中的攻击方式之一,早在2016年就因为TheDAO事件而造成了以太坊的硬分叉。
漏洞概述
在以太坊中,智能合约能够调用其他外部合约的代码,由于智能合约可以调用外部合约或者发送以太币,这些操作需要合约提交外部的调用,所以这些合约外部的调用就可以被攻击者利用造成攻击劫持,使得被攻击合约在任意位置重新执行,绕过原代码中的限制条件,从而发生重入攻击。重入攻击本质上与编程里的递归调用类似,所以当合约将以太币发送到未知地址时就可能会发生。
全国政协委员刘尚希:激励推动银行在区块链等领域深入合作:全国政协委员、中国财政科学研究院院长刘尚希建议,在政策上支持开放银行构建,激励银行业善用我国金融科技领先和更本土化的优势,快速发展技术能力:发展线上服务能力和数字风控技术,实现线上线下业务融合;大力推动银行业部署下一代分布式金融信息系统,建设性能稳定、智能化运营的开放式系统架构,为开放银行建好硬件底座;激励推动银行在人工智能、区块链等核心关键技术领域进行深入合作。(中国经营报)[2020/5/23]
简单的来说,发生重入攻击漏洞的条件有2个:
调用了外部的合约且该合约是不安全的
外部合约的函数调用早于状态变量的修改
下面给出一个简单的代码片段示例:
上述代码片段就是最简单的提款操作,接下来会给大家详细分析重入攻击造成的原因。
漏洞分析
在正式的分析重入攻击之前,我们先来介绍几个重点知识。
转账方法
由于重入攻击会发送在转账操作时,而Solidity中常用的转账方法为
山西深入推进跨境金融区块链服务平台应用:国家外汇管理局山西省分局深入推进跨境金融区块链服务平台应用,为中小微外贸企业跨境结算与融资扩渠道、增便利。目前,山西省已有17家银行加入该平台,为16家企业办理融资业务116笔,累计放款7.67亿美元。(中国新闻网)[2020/5/3]
.transfer(),.send()和.gas().call.vale()(),下面对这3种转账方法进行说明:
.transfer():只会发送2300gas进行调用,当发送失败时会通过throw来进行回滚操作,从而防止了重入攻击。
.send():只会发送2300gas进行调用,当发送失败时会返回布尔值false,从而防止了重入攻击。
.gas().call.vale()():在调用时会发送所有的gas,当发送失败时会返回布尔值false,不能有效的防止重入攻击。fallback函数
接着我们来讲解下fallback回退函数。
回退函数(fallbackfunction):回退函数是每个合约中有且仅有一个没有名字的函数,并且该函数无参数,无返回值,如下所示:
动态 | 《加快推进上海金融科技中心建设实施方案》:推动区块链等技术深入研发攻关:1月15日,上海市地方金融监督管理局会同国家在沪金融管理部门共同召开新闻通气会,宣传介绍《加快推进上海金融科技中心建设实施方案》(以下简称《实施方案》)。《实施方案》指出,全速推进金融科技关键技术研发。积极推动大数据、人工智能、区块链、5G等新兴技术深入研发攻关,推动技术创新与金融创新的融合发展。深化芯片、算法、云计算等基础技术攻关,提升金融创新的基础技术支撑能力。统筹布局安全、稳定、高效的信息基础设施,积极争取国家级金融科技重大项目和平台在沪落地。(第一财经)[2020/1/15]
function()publicpayable{???
???...
}
回退函数在以下几种情况中被执行:
调用合约时没有匹配到任何一个函数;
没有传数据;
智能合约收到以太币。
漏洞代码
下面的代码就是存在重入攻击的,实现的是一个类似于公共钱包的合约,所有的用户都可以使用deposit()存款到Reentrance合约中,也可以从Reentrance合约中使用withdraw()进行提款,当然了所有人也可以使用balanceof()查询自己或者其他人在该合约中的余额。
声音 | 大连港:将继续开拓区块链技术 深入开展创新工作:金色财经报道,大连港(601880)被提问“除了区块链电子放货平台之外,接下来还有什么区块链项目落地”时表示,目前,大连港利用区块链的去中心化、不可篡改、共享账本等特征所建立的区块链信任机制,使业务信息公开透明公正,借助区块链的数据加密作用强化数据信息安全功能,确保数据的安全性、完整性和一致性,使船、轮驳公司、智慧港口平台各方都能实时、安全、无缝地传递拖轮作业信息,实现全程留痕和全程可追溯,满足轮驳业务的安全性和准确性要求。未来大连港还将继续开拓区块链技术业务实现场景,深入开展创新工作,在全港口领域推行区块链技术应用落地。(上证e互动)[2019/10/30]
首先使用一个账户(0x5B38Da6a701c568545dCfcB03FcB875f56beddC4)扮演受害者,将该合约在RemixIDE?点击Deploy按钮进行部署。
在部署合约成功后在VALUE设置框中填写5,将单位改成ether,点击deposit存入5个以太币。
点击wallet查看该合约的余额,发现余额为5ether,说明我们的存款成功。
动态 | 2019年7月国内一级市场区块链融资10强发布 区块链行业的发展不断向产业端深入:据中国金融信息网报道,8月8日,中国金融信息网与烯牛数据联合发布2019年7月份国内一级市场区块链项目融资10强榜单。从榜单来看,在整体融资大幅下滑的趋势下,2019年7月份国内区块链项目融资数量出现回升。监测数据显示,数字货币和交易平台类融资项目明显增多,天秤币白皮书的发布在一定程度上提振了市场预期,但是此类项目将面临与天秤币的直接竞争,其商业逻辑未来或将受到天秤币严酷打压。与实体经济结合的项目依然占据着榜单的主流,分别涉及金融、大数据、交通运输、电商、传媒、产权、房地产和游戏领域。从连续发布的榜单来看,区块链行业的发展不断向产业端深入,应用端的开发落地越来越具体,与实体经济结合发展的想象空间逐渐立体化。从技术角度来看,加密、数据库、共识、P2P和智能合约的发展日益成熟,区块链作为集成性创新技术的发挥边界正在逐步拓展。[2019/8/8]
而下面的代码则是针对上面存在漏洞的合约进行的攻击:
使用另外一个账户(0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2)扮演攻击者,复制存在漏洞的合约地址到Deploy的设置框内,点击Deploy部署上面的攻击合约。
部署成功后先调用wallet()函数查看攻击合约的余额为0。
攻击者先存款1ether到漏洞合约中,这里设置VALUE为1ether,之后点击攻击合约的deposit进行存款。
再次调用合约的wallet函数查看漏洞合约的余额,发现已经变成了6ether。
攻击者(0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2)调用攻击合约的attack函数模拟攻击,之后调用被攻击合约的wallet函数去查看合约的余额,发现已经归零,此时回到攻击合约查看余额,发现被攻击合约中的6ether已经全部提款到了攻击者合约中,这就造成了重入攻击。
源码分析
上面讲解了如何进行重入攻击已经漏洞原因,这里梳理了漏洞源码和攻击的步骤,列出了关键代码。
相关案例
2016年6月17日,TheDAO项目遭到了重入攻击,导致了300多万个以太币被从TheDAO资产池中分离出来,而攻击者利用TheDAO智能合约中的splitDAO()函数重复利用自己的DAO资产进行重入攻击,不断的从TheDAO项目的资产池中将DAO资产分离出来并转移到自己的账户中。
下列代码为splitDAO()函数中的部分代码,源代码在TokenCreation.sol中,它会将代币从theparentDAO转移到thechildDAO中。平衡数组uintfundsToBeMoved=(balances*p.splitData.splitBalance)?/p.splitData.totalSupply决定了要转移的代币数量。
下面的代码则是进行提款奖励操作,每次攻击者调用这项功能时p.splitData都是一样的,并且p.splitData.totalSupply与balances的值由于函数顺序问题,发生在了转账操作之后,并没有被更新。
paidOut=reward更新状态变量放在了问题代码payOut函数调用之后。
对_recipient发出.call.value调用,转账_amount个Wei,.call.value调用默认会使用当前剩余的所有gas。
解决办法
通过上面对重入攻击的分析,我们可以发现重入攻击漏洞的重点在于使用了fallback等函数回调自己造成递归调用进行循环转账操作,所以针对重入攻击漏洞的解决办法有以下几种。
使用其他转账函数
在进行以太币转账发送给外部地址时使用Solidity内置的transfer()函数,因为transfer()转账时只会发送2300gas进行调用,这将不足以调用另一份合约,使用transfer()重写原合约的withdraw()如下:
先修改状态变量
这种方式就是确保状态变量的修改要早于转账操作,即Solidity官方推荐的检查-生效-交互模式(checks-effects-interactions)。
使用互斥锁
互斥锁就是添加一个在代码执行过程中锁定合约的状态变量以防止重入攻击。
使用?OpenZeppelin官方库
OpenZeppelin官方库中有一个专门针对重入攻击的安全合约:
https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/security/ReentrancyGuard.sol
参考文献
1.以太坊的几次硬分叉:
https://zhuanlan.zhihu.com/p/111446792
2.以太坊智能合约安全漏洞(1):重入攻击:
https://blog.csdn.net/henrynote/article/details/82119116
3.?区块链的那些事—THEDAO攻击事件源码分析:
https://blog.csdn.net/Fly_hps/article/details/83095036
DeFi资产管理平台Zapper已正式推出其积分奖励机制,用户可以通过完成交易、提供流动性等任务获得奖励积分,并在积分达到特定数量与等级后领取ZapperNFT,以将DeFi体验游戏化.
1900/1/1 0:00:00今日马斯克发布推文,内容为比特币标签和“心碎”表情。配图是一对情侣之间产生矛盾,马斯克在发出心碎推文后表示“我也要激光眼.
1900/1/1 0:00:00基本信息:英文全称:Livepeer英文简称:LPT项目简介:Livepeer是一个开放式的视频直播基础结构联网.
1900/1/1 0:00:00截止到北京时间12:00,比特币现货价格收于37700.32美元,以太坊现货价格收于2738.43美元。在小时级别上,比特币价格在昨日19:00后,迎来五连涨,价格一度逼近38000美元.
1900/1/1 0:00:00一、项目介绍BitBook是一个旅游平台,人们可以在此预订住宿,并在此过程中赚取代币。通过我们的Token奖励计划,我们不仅通过激励用户不断带来新的用户一起推动平台的使用,但我们也可以通过奖励创.
1900/1/1 0:00:00尊敬的用户:BiKi余币宝将于06月03日23:00开启第89期USDT机池理财,预期年化收益14%.
1900/1/1 0:00:00