前言
智能合约的概念于1995年由NickSzabo首次提出,它是一种旨在以信息化方式传播、验证或执行合同的计算机协议,它允许在没有第三方的情况下进行可信交易,这些交易可追踪且不可逆转。然而智能合约也并非是安全的,其中重入(Re-Entrance)攻击漏洞是以太坊中的攻击方式之一,早在2016年就因为TheDAO事件而造成了以太坊的硬分叉。漏洞概述
在以太坊中,智能合约能够调用其他外部合约的代码,由于智能合约可以调用外部合约或者发送以太币,这些操作需要合约提交外部的调用,所以这些合约外部的调用就可以被攻击者利用造成攻击劫持,使得被攻击合约在任意位置重新执行,绕过原代码中的限制条件,从而发生重入攻击。重入攻击本质上与编程里的递归调用类似,所以当合约将以太币发送到未知地址时就可能会发生。简单的来说,发生重入攻击漏洞的条件有2个:调用了外部的合约且该合约是不安全的外部合约的函数调用早于状态变量的修改下面给出一个简单的代码片段示例:
上述代码片段就是最简单的提款操作,接下来会给大家详细分析重入攻击造成的原因。漏洞分析
在正式的分析重入攻击之前,我们先来介绍几个重点知识。01转账方法
由于重入攻击会发送在转账操作时,而Solidity中常用的转账方法为<address>.transfer(),<address>.send()和<address>.gas().call.vale()(),下面对这3种转账方法进行说明:<address>.transfer():只会发送2300gas进行调用,当发送失败时会通过throw来进行回滚操作,从而防止了重入攻击。<address>.send():只会发送2300gas进行调用,当发送失败时会返回布尔值false,从而防止了重入攻击。<address>.gas().call.vale()():在调用时会发送所有的gas,当发送失败时会返回布尔值false,不能有效的防止重入攻击。02fallback函数
声音 | 河北辛集副市长:大力推进“区块链+智能制造”的深入融合:12月27日,河北省钢铁行业“区块链+智能制造”主题峰会在石家庄辛集市举行,峰会由河北省冶金行业协会、中国电信河北分公司、长城新媒体集团主办。辛集市副市长牛军波表示,冶金行业的发展对于辛集市的经济建设起到举足轻重的作用,目前钢铁行业的自动化、信息化的发展已具有良好的基础。大力推进“区块链+智能制造”的深入融合,可以为钢铁行业带来全面的提升,在提高企业竞争力、打造优质产品方面提供有力支持。(长城网)[2019/12/27]
接着我们来讲解下fallback回退函数。回退函数(fallbackfunction):回退函数是每个合约中有且仅有一个没有名字的函数,并且该函数无参数,无返回值,如下所示:
回退函数在以下几种情况中被执行:调用合约时没有匹配到任何一个函数;没有传数据;智能合约收到以太币。03漏洞代码
下面的代码就是存在重入攻击的,实现的是一个类似于公共钱包的合约,所有的用户都可以使用deposit()存款到Reentrance合约中,也可以从Reentrance合约中使用withdraw()进行提款,当然了所有人也可以使用balanceof()查询自己或者其他人在该合约中的余额。
动态 | ZB 创新智库深入欧洲爱沙尼亚进行调研访问:ZB 创新智库正在持续深入欧洲各国进行区块链调研,本周到访爱沙尼亚的首都蒂兰,深入了解行业最新发展动态。北欧小国爱沙尼亚在区块链开发方面引领欧洲大陆。爱沙尼亚是欧洲第一个对数字经济发展采取激进政策的国家,凭借其现已知名的电子居留计划,该国为数字经济和区块链公司颁发了最多的许可证。 据 Bitcoin.com 网站报道,截至 2018 年 11 月,爱沙尼亚发放的许可证已经超过 900 张。
据 ZB 创新智库当地调研显示,近期这个数字现在已翻了一番。目前在爱沙尼亚获得数字资产许可证已变得较为困难,2019 年 5 月 3 日爱沙尼亚政府财政部对数字资产许可程序进行修改,增加了一系列正式义务,将处理时间从 30 天延长至 90 天,并确定了在爱沙尼亚注册成立公司或分支机构的要求。[2019/12/12]
首先使用一个账户(0x5B38Da6a701c568545dCfcB03FcB875f56beddC4)扮演受害者,将该合约在RemixIDE点击Deploy按钮进行部署。
在部署合约成功后在VALUE设置框中填写5,将单位改成ether,点击deposit存入5个以太币。
声音 | 国家医疗保障局副局长:国家医疗保障局将深入研究引入区块链等先进技术:金色财经报道,国家医疗保障局副局长施子海表示,国家医疗保障局将不断探索创新,深入研究引入5G和区块链等先进技术,加快完善电子凭证功能和推广应用,不断优化设计、完善功能、简化流程,提升群众使用体验,加强业务协同。[2019/11/26]
点击wallet查看该合约的余额,发现余额为5ether,说明我们的存款成功。
而下面的代码则是针对上面存在漏洞的合约进行的攻击:
使用另外一个账户(0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2)扮演攻击者,复制存在漏洞的合约地址到Deploy的设置框内,点击Deploy部署上面的攻击合约。
部署成功后先调用wallet()函数查看攻击合约的余额为0。
声音 | 中国互金协会副秘书长:我国区块链在金融领域应用总体处于早期尝试向深入探索转变的过渡阶段:金色财经报道,11月20日,“金融进化论:2019新京报金融科技论坛”上,中国互金协会副秘书长杨农表示,当前,我国区块链在金融领域应用,已在供应链金融、金融数据共享和金融信息存证等场景中形成了一些落地案例,总体处于早期尝试向深入探索转变的过渡阶段,且呈现出探索性应用数量较多、参与主体较为多元、底层技术原创有待加强等特点。同时,区块链在我国金融领域的应用探索也面临着如下几个方面的挑战:技术层面仍难以兼顾部分金融应用场景对安全、功能和性能的要求;研发层面自主创新有待加强,对国外开源程序的广泛应用可能导致技术依赖风险;业务层面部分金融应用环节尚存在模糊地带,部分机构在开展区块链应用创新时缺少权威的第三方评估意见作为参考;治理层面存在法律规制困难,如链上资产和智能合约等方面的法律有效性界定不清晰。[2019/11/22]
攻击者先存款1ether到漏洞合约中,这里设置VALUE为1ether,之后点击攻击合约的deposit进行存款。
声音 | Evolution capital创始合伙人:熊市有更多时间做深入思考:11月16日, Evolution capital 创始合伙人老葛在“499加油站第二十期”接受火币英才CEO张晓媛和节点资本合伙人及贝壳公关CEO姜晓玉的采访时表示, 熊市过冬宝典一,是意识的升级,慢慢对这个行业的理解跟上了,自然比隔岸观火的人理解更深。熊市过冬宝典二,是多宣传,PR成本低;好好做社群,做精,有更优质的用户;扎实的做合规。花时间在这些领域提升,积累经验和技能的小伙伴,下一波行情来的时候,就有了更多的优势。保持敏锐,等下一波机会大批涌来的时候,肯定是观念超前,行动在一线的人,最有机会把握住。[2018/11/17]
再次调用合约的wallet函数查看漏洞合约的余额,发现已经变成了6ether。
攻击者(0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2)调用攻击合约的attack函数模拟攻击,之后调用被攻击合约的wallet函数去查看合约的余额,发现已经归零,此时回到攻击合约查看余额,发现被攻击合约中的6ether已经全部提款到了攻击者合约中,这就造成了重入攻击。
04源码分析
上面讲解了如何进行重入攻击已经漏洞原因,这里梳理了漏洞源码和攻击的步骤,列出了关键代码。
相关案例
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等函数回调自己造成递归调用进行循环转账操作,所以针对重入攻击漏洞的解决办法有以下几种。01使用其他转账函数
在进行以太币转账发送给外部地址时使用Solidity内置的transfer()函数,因为transfer()转账时只会发送2300gas进行调用,这将不足以调用另一份合约,使用transfer()重写原合约的withdraw()如下:
02先修改状态变量
这种方式就是确保状态变量的修改要早于转账操作,即Solidity官方推荐的检查-生效-交互模式(checks-effects-interactions)。
03使用互斥锁
互斥锁就是添加一个在代码执行过程中锁定合约的状态变量以防止重入攻击。
04使用OpenZeppelin官方库
OpenZeppelin官方库中有一个专门针对重入攻击的安全合约:https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/security/ReentrancyGuard.sol
参考文献
1.以太坊的几次硬分叉:https://zhuanlan.zhihu.com/p/1114467922.以太坊智能合约安全漏洞(1):重入攻击:https://blog.csdn.net/henrynote/article/details/821191163.区块链的那些事—THEDAO攻击事件源码分析:https://blog.csdn.net/Flyhps/article/details/83095036
作者:一棵杨树4月22日,Square公布了和投资机构ARK的一份联合白皮书,提出了和主流认知相反的观点:比特币实际上是可再生能源未来的关键驱动力,比特币开采和可再生能源一样,促进了能源转型.
作者:凯尔;编辑:文刀2010年5月22日,美国程序员LaszloHanyecz花费1万枚比特币购买了两张披萨劵,使BTC第一次有了价格和购买力.
灾难女孩NFT表情包——灾难女孩Yuga Labs:将启动Otherdeed Expanded NFT铸造,以解锁LOTM等游戏体验:4月4日消息.
Odaily星球日报译者|Moni 6月17日凌晨,鲍威尔出现在为期两天的联邦公开市场委员会(FOMC)会议结束后的新闻发布会上.
事件起因 2021年6月23日,基于币安智能链的稳定币交易平台NerveFinance发推表示,收益聚合器ElevenFinance中与Nerve相关的机池或遭闪电贷攻击.
出处:比推Bitpush.News;作者:ChenZou当比特币在2009年突然出现在舞台上时,比特币追随者们将这种加密货币誉为在传统金融体系之外.