当前位置:网站首页>智能合约安全——delegatecall (1)
智能合约安全——delegatecall (1)
2022-08-04 05:27:00 【chainpip】
在之前的内容中,学习到了storage中是使用插槽存储数据的。而delegatecall函数有个有趣的特点:当使用 delegatecall 函数进行外部调用涉及到 storage 变量的修改时是根据插槽位置来修改的而不是变量名。
举个例子:
合约A

合约B
当合约B调用testDelegatecall()函数时,合约B的地址c的值会变为合约A的地址,而地址a则是不变。因为合约A的函数test()改变的是插槽slot1的值,同样的在合约B中运行时,改变的也是插槽slot1的值,即地址c的值。
目标合约

漏洞分析
我们可以看到有两个合约,Lib 合约中只有一个 pwn 函数用来修改合约的 owner,在 HackMe 合约中存在 fallback 函数,fallback 函数的内容是使用 delegatecall 去调用 Lib 合约中的函数。我们需要利用 HackMe.fallback() 触发 delegatecall 函数去调用 Lib.pwn() 将 HackMe 合约中的 owner 改成自己。
攻击合约

现在我们来看看整个攻击的逻辑:
1.攻击者调用attack()发起攻击,attack 函数首先去调用 HackMe.pwn();
2.HackMe 合约中并没有 pwn 函数,此时触发 HackMe.fallback();
3.HackMe.fallback() 使用 deldegatecall 调用 Lib 合约中的函数,函数名取的是 msg.data 也就是 "pwn()",而 Lib 合约中恰好有名为 pwn 的函数,于是便在HackMe 合约中运行了pwn函数;
4.pwn函数修改了插槽slot0位置(即HackMe 合约的拥有者)的值为msg.sender(即攻击者),最终导致了HackMe 合约的拥有者变成了攻击者。
修复建议
1. 在使用 delegatecall 时应注意被调用合约的地址不能是可控的;
2. 在较为复杂的合约环境下需要注意变量的声明顺序以及存储位置。因为使用 delegatecall 进行外部调时会根据被调用合约的数据结构来用修改本合约相应 slot 中存储的数据,在数据结构发生变化时这可能会造成非预期的变量覆盖。
如果想了解更多的智能合约和区块链知识,欢迎到区块链交流社区CHAINPIP社区,一起交流学习~社区地址:https://www.chainpip.com/
边栏推荐
猜你喜欢
![[NSSRound#1 Basic]](/img/0a/b2fc70947e3c76178d2faa86a1085d.png)
[NSSRound#1 Basic]

8. Custom mapping resultMap

canal实现mysql数据同步

7.16 Day22---MYSQL (Dao mode encapsulates JDBC)

MySQL log articles, binlog log of MySQL log, detailed explanation of binlog log

Canal mysql data synchronization

Cannot read properties of null (reading 'insertBefore')

ISCC2021———MISC部分复现(练武)

对象存储-分布式文件系统-MinIO-1:概念

Commons Collections2
随机推荐
音视频相关基础知识与FFmpeg介绍
登录页面js手写
bind和function
webrtc中视频采集实现分析(二) 视频帧的分发
关系型数据库-MySQL:二进制日志(binlog)
关于let var 和const的区别以及使用
关于 for in与for of 的差别以及如何使用
再识关联容器
php将多维数据保存进json文件
箭头函数的使用
phpexcel导出数据为xml
Swoole学习(一)
对象存储-分布式文件系统-MinIO-3:MinIo Client(mc)
跨域问题的解决
编程Go:学习目录
实际开发中,客户要求密码输入框禁止粘贴~
Unity表格配置编辑工具
关于事件捕获和事件冒泡的顺序,以及如何处理事件冒泡带来的影响
自动化运维工具Ansible(5)流程控制
页面刷新没有执行watch?