当前位置:网站首页>智能合约安全——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/
边栏推荐
- CentOS7 —— yum安装mysql
- 浏览器中的同源策略
- lambda函数用法总结
- MySQL log articles, binlog log of MySQL log, detailed explanation of binlog log
- Embedded system driver primary [3] - _IO model in character device driver foundation
- 自动化运维工具Ansible(7)roles
- Swoole学习(一)
- es6 学习记录
- warning C4251: “std::vector<_Ty>”需要有 dll 接口由 class“Test”的客户端使用错误
- 原型对象及原型链的理解
猜你喜欢
CentOS7 —— yum安装mysql
Set集合与Map集合
Deploy LVS-DR cluster [experimental]
The cost of automated testing is high and the effect is poor, so what is the significance of automated testing?
webrtc中视频采集实现分析(一) 采集及图像处理接口封装
想好了吗?
原型对象及原型链的理解
Web Basics and Exercises for C1 Certification - My Study Notes
自动化运维工具Ansible(3)PlayBook
7.16 Day22---MYSQL (Dao mode encapsulates JDBC)
随机推荐
webrtc中的引用计框架
音视频相关基础知识与FFmpeg介绍
关系型数据库-MySQL:错误日志(log_error)
lambda函数用法总结
跨域问题的解决
Shell(1)简介入门
MySQL database (basic)
TensorRTx-YOLOv5工程解读(二)
JS深复制对象方法(深拷贝)
字符串常用方法
4.3 Annotation-based declarative transactions and XML-based declarative transactions
编程Go:内置打印函数 print、println 和 fmt 包中 fmt.Print、fmt.Println 的区别
12. Paging plugin
C1认证之web基础知识及习题——我的学习笔记
MySql data recovery method personal summary
Cannot read properties of null (reading ‘insertBefore‘)
【论文阅读笔记】无监督行人重识别中的采样策略
自动化运维工具Ansible(6)Jinja2模板
OpenRefine中的正则表达式
对象存储-分布式文件系统-MinIO-2:服务端部署