当前位置:网站首页>智能合约安全——delegatecall (1)
智能合约安全——delegatecall (1)
2022-08-02 16:30:00 【fingernft】
在之前的内容中,学习到了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 合约的拥有者变成了攻击者。修复建议
- 在使用 delegatecall 时应注意被调用合约的地址不能是可控的;
- 在较为复杂的合约环境下需要注意变量的声明顺序以及存储位置。因为使用 delegatecall 进行外部调时会根据被调用合约的数据结构来用修改本合约相应 slot 中存储的数据,在数据结构发生变化时这可能会造成非预期的变量覆盖。
如果想了解更多的智能合约和区块链知识,欢迎到区块链交流社区CHAINPIP社区,一起交流学习~社区地址:https://www.chainpip.com/
边栏推荐
猜你喜欢
随机推荐
亲戚3.5W入职华为后,我也选择了转行……
JZ32 从上往下打印二叉树
Timestamp formatting "recommended collection"
Summary of CNN classic models [easy to understand]
synchronized已经不在臃肿了,放下对他的成见之初识轻量级锁
exness:欧元区经济意外向好,欧元震荡蓄势等待突破
记一次内部分享——瞎扯淡
[LeetCode]剑指 Offer 32 - II. 从上到下打印二叉树 II
解析并执行 shell 命令
JZ71 跳台阶扩展问题
图像质量评价指标
JZ9 用两个栈实现队列
8大软件供应链攻击事件概述
锁定和并发控制(一)
#yyds干货盘点# 面试必刷TOP101: 删除链表的倒数第n个节点
乌总统解除乌克兰国家安全局信息和情报分析部负责人职务
FPGA 20个例程篇:10.遍历DDR3内存颗粒读写循环校验
时间戳格式化「建议收藏」
金仓数据库KingbaseES安全指南--6.12. BSD身份验证
1.NVIDIA Deepstream开发指南中文版--欢迎使用 DeepStream 文档









