Egis-Security / CTF_Challenge

Repository containing CTF challenges from nmirchev8, deth and bOgO.
14 stars 8 forks source link

b0g0_ctf - ETH cannot be withdrawn if user that minted is contract. #30

Open v-kirilov opened 2 months ago

v-kirilov commented 2 months ago

If user is a contract and calls the withdraw function the call will revert due to the whitespace data provided in the call:

(bool success, ) = msg.sender.call{value: depositRequired}(" ");
  1. Deploy the contract on Remix
  2. Set the address of the CFT contract.
  3. Mint a NFT
  4. Try to withdraw back the ETH spent. POC:
    
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.18;

contract BogoCall { address public toCall; uint256 public id; uint256 public constant MIN_DEPOSIT = 0.1 ether;

constructor(address callme) payable {
    toCall = callme;
}

function mintMe() public {
    (bool success, ) = toCall.call{value: MIN_DEPOSIT}(
        abi.encodeWithSignature("deposit()")
    );
    require(success, "Not deposited");
}

function withdraw() public {
    (bool success, ) = toCall.call(
        abi.encodeWithSignature("withdraw(uint256)", id)
    );
    require(success, "Not withdrawn");
}

function setId(uint256 x) public {
    id = x;
}

}

Impact : High - loss of funds.
Solution : Remove whitespace:

(bool success, ) = msg.sender.call{value: depositRequired}("");

BogoCvetkov commented 2 months ago

Valid! You're the first one to submit - so you'll get a payout for this one