智能合约是一种旨在以信息化方式传播、验证或执行合同的计算机协议。智能合约允许在没有第三方的情况下进行可信交易,这些交易可追踪且不可逆转。智能合约概念于1995年由NickSzabo首次提出。智能合约的目的是提供优于传统合约的安全方法,并减少与合约相关的其他交易成本。
漏洞概述:
因为以太坊智能合约中是可以调用外部的合约代码,外部合约可能是攻击者构造的恶意不安全的合约代码,当在转账操作时执行代码,迫使攻击的合约回调包括自身的代码,和绕过源代码的限制发生了重入攻击事件。
发生重入攻击漏洞有两个原因:
BadgerDAO关于“升级智能合约”的提案BIP 76已开启投票:12月11日消息,BadgerDAO表示,其论坛已上线关于“升级智能合约”的提案BIP 76。该提案旨在覆盖重要的智能合约升级,以拯救用户资金,改进暂停功能,并通过黑名单提供额外的保障。本提案不包括拟议拯救资金功能的执行和解除暂停。这些功能将通过未来的BIP解决。基于社区反馈,为了加快智能合约的重新激活,该提案将直接转向48小时快照投票。
提案称,Badger致力于在安全的情况下重新启动智能合约。考虑到时间锁的因素,一旦最终BIP决定执行拟议的拯救资金和解除暂停,在进行这些升级之前等待标准时间框架将增加至少3天的延迟。因此,该提案将智能合约升级与拯救行动的执行和解除暂停分开,以便执行决策可以遵循Badger的治理流程,同时还确保生成的治理决策能够迅速制定。[2021/12/11 7:32:26]
1.?调用了外面不安全的合约代码
数据:比特币锚定币锁仓量突破32亿美元:Debank数据显示,12月17日,受比特币价格上涨影响,当前比特币锚定币总锁仓量已突破32亿美元,约合32.2亿美元达到历史新高。其中WBTC以26.31亿美元的锁仓量位居第一并刷新自身记录,renBTC和HBTC分别以3.17亿美元以及1.36亿美元排在其后。
截止目前,WBTC的发行量为115,711枚、renBTC为13,984枚、HBTC为6,010枚。[2020/12/17 15:33:36]
2.?外部合约的函数早于状态变量的修改
Twitter CEO:比特币仍是最可行的网络原生代币,但需加强交易效率及使用者体验:Twitter 首席执行官兼 Square Crypto 创始人 Jack Dorsey 在接受路透社采访时表示,他依旧认为比特币是目前最可行的网络原生代币,不过作为支付工具,比特币在交易效率及使用者体验方面,还需要加强,至少要与现在大众已经习惯的支付方式类似,才可能更为普及。[2020/9/11]
动态 | 过去三个月四大PoS币种的比特币交易对平均收益率超49%:1月7日消息,加密研究公司Messari提供的数据显示,过去三个月,四大PoS币种Tezos(XTZ)、Cosmos(ATOM)、VeChain(VET)和NEO的比特币交易对平均收益率已超过49%。目前,VET比特币交易对获得超过58%的收益率暂处于领先地位,而Cosmos,Tezos和NEO分别以55%、48.4%和35.5%的收益率紧随其后。(Decrypt)[2020/1/8]
漏洞分析:
看withdraw函数,我们可以看到它接收了一个_amount参数,将其与发送者的balance进行比较,不超过发送者的balance就将这些_amount发送给sender,同时我们注意到这里它用来发送ether的函数是call.value,发送完成后,它才在下面更新了sender的balances,这里就是可重入攻击的关键所在了,因为该函数在发送ether后才更新余额,所以我们可以想办法让它卡在call.value这里不断给我们发送ether,同样利用的是我们熟悉的fallback函数来实现。
当然,这里还有另外一个关键的地方——call.value函数特性,当我们使用call.value()来调用代码时,执行的代码会被赋予账户所有可用的gas,这样就能保证我们的fallback函数能被顺利执行,对应的,如果我们使用transfer和send函数来发送时,代码可用的gas仅有2300而已,这点gas可能仅仅只够捕获一个event,所以也将无法进行可重入攻击,因为send本来就是transfer的底层实现,所以他两性质也差不多。
2016年6月以太币组织TheDAO被攻击,攻击者利用两个代码漏洞创建子合约提取了360万个以太币。接下来我们简单说一下这个事件
攻击者利用the?DAO函数智能合约中splitDAO()函数,重复对DAO资产进行重入攻击,不断从项目的资产里面分离出DAO资产并转移到自己的账户中
1.?创建钱包,调用splitDAO函数
2.?创建一个分割提案到一个新的钱包地址
3.?等待再调用splitDAO函数
4.?成功获取了ether
?解决方法:
1.?使用其他转账函数
进行以太坊转账时发送给外部地址时使用Solidity的内置函数,这将不足以调用另一份合约.
2.?先修改状态变量
这种方式就是确保状态变量的修改要早于转账操作,即Solidity官方推荐的检查-生效-交互模式(checks-effects-interactions)。
1.?使用互斥锁
互斥锁就是添加一个在代码执行过程中锁定合约的状态变量以防止重入攻击。
2.?使用OpenZeppelin官方库
OpenZeppelin官方库中有一个专门针对重入攻击的安全合约
??本文作者:权星实验室团队
来源:金色财经
郑重声明: 本文版权归原作者所有, 转载文章仅为传播更多信息之目的, 如作者信息标记有误, 请第一时间联系我们修改或删除, 多谢。