当前位置:网站首页>智能合约安全——delegatecall (2)
智能合约安全——delegatecall (2)
2022-08-03 18:02:00 【fingernft】
本次,我们来讲一讲运用delegatecall函数时更复杂的合约漏洞案例。
目标合约
漏洞分析这次的攻击目标依然是获得 HackMe 合约中的 owner 权限,我们可以看到两个合约中除了 HackMe 合约中的构造函数可以修改合约的 owner 其他地方并没有修改 owner 的函数,但是却可以修改位置slot0的值,而HackMe 合约中插槽slot0表示的便是Lib的地址,那么我们就先修改Lib的地址为我们的地址,再次调用HackMe 合约时就会运行我们合约中的逻辑,那么想改哪个位置插槽的值不就都由我们控制了吗?
攻击合约下面是我们本次的攻击合约:

接下来我们来看看攻击的整个逻辑:
Attack.attack() 函数先将自己的地址转换为 uint256 类型(这一步是为了兼容目标合约中的数据类型)第一次调用 HackMe.doSomething() 函数;
HackMe.doSomething() 函数使用 delegatecall 函数带着传入的 Attack 合约的地址调用了 Lib.doSomething() 函数;
可以看到 Lib.doSomething() 函数将合约中存储位置为 slot0 的参数改为传入的值,这样当 HackMe 合约使用 delegatecall 调用 Lib.doSomething() 函数时也将改变自己在 slot0 位置存储的变量的值,也就是将 lib 参数(这里存储的是 Lib 合约的地址)改为我们传入的 Attack 合约的地址。此时之前在 HackMe.lib 参数中存储的 Lib 合约的地址就被修改成我们传入的 Attack 合约的地址了;
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 也就是攻击者的地址,至此攻击者完成了他的攻击。
修复建议我们在合约的开发中使用delegatecall要时刻注意其被调用的合约地址要始终在我们设计的逻辑内运行,不能让其有可能超出我们设计时的适用范围,一旦出现了超出我们预期设计的情况,那么合约就有可能被不法之徒利用。
如果想了解更多的智能合约和区块链知识,欢迎到区块链交流社区CHAINPIP社区,一起交流学习~社区地址:https://www.chainpip.com/
边栏推荐
猜你喜欢
随机推荐
“vite”和“vite预览”有什么区别?
图像传感第一章学习心得
Share 14 JS functions you must know
STM32——LCD—FSMC原理简介
Crack: WebKitX ActiveX and WebKitX VHX
5000元价位高性能轻薄本标杆 华硕无双高颜能打
多线程 里面 使用AtomicInteger类,保证线程安全
【白话模电2】二极管特性和分类
使用.NET简单实现一个Redis的高性能克隆版(一)
使用o.execute_sql 查询很很很小的表, 要7/8秒钟, 这个怎么解决
什么是鉴权?一篇文章带你了解postman的多种方式
宝塔搭建企业招聘网站源码实测
常见荧光染料修饰多种基团及其激发和 发射波长数据一览数据
ATM银行系统(对象初级练习)
es6新增-Generator(异步编程的解决方案2)
yaml data format
【技术白皮书】第二章:OCR智能文字识别回顾——自然语言文本发展历程
2021年数据泄露成本报告解读
Unable to start SinkRunner: { policy:org.apache.flume
云图说丨初识华为云微服务引擎CSE









