안녕하세요. 개발자 모도리입니다.
오늘은 게임처럼 Ethereum Smart Contract의 취약점을 배울 수 있는 Ethernaut에 대해서 알아보겠습니다.
OpenZeppeline과 Smart Contract Auditing으로 유명한 Zeppeline team에서 제공하고 있는 서비스입니다. 총 15단계로 이뤄져 있고, 각 단계마다 취약점 미션 풀이를 위해 필요한 취약점을 찾아야 합니다.
예전에 대학생 때 보안 공부를 해 보겠다며, 해커스쿨에서 이 외 비슷한 것을 이용해서 공부했던 기억이 납니다.
저도 이제 막 시작해 본 단계라서 앞으로 문제 풀이를 꾸준히 올릴 예정입니다.
The Ethernaut
홈페이지 주소
https://ethernaut.zeppelin.solutions/
접속하면 아래와 같은 화면이 나옵니다.
Ethernaut는 Web3/Solidity 기반의 wargame(가상 전쟁게임)으로 overthewire.org와 만화 El Eternauta에서 영감을 받아서 만들어졌다고 합니다. EVM 안에서 동작하며, 각 level들은 smart contract로 구성 된 문제를 풀어야 넘어갈 수 있습니다.
그러면 아래의 Play now! 버튼을 눌러서 시작해 봅니다.
0.Hello Ethernaut
이 단계는 Ethernaut 문제를 풀기 위한 기본 준비 단계입니다.
MetaMask를 설치합니다.
- MetaMask 설치에 대해 잘 설명 된 글들이 많기 때문에 이 부분은 생략하겠습니다.
- 이 글을 참고 하시면 쉽게 따라하실 수 있습니다. (해당 글에서 Ganache-CLI 설정 부분 전까지만 따라하시면 됩니다.)
- 네트워크는 Main Ethereum Network가 아닌 Ropsten Test Network를 선택해 주세요.
브라우저의 콘솔 창을 열어주세요.
- Chrome 기준으로 도구 메뉴 > 도구 더 보기 > 개발자 도구 또는 F12
- 콘솔창에 아래와 같은 메세지가 나오면 정상적으로 동작하고 있는 것입니다.
- 그리고 콘솔창의 위치를 변경하고 싶으시면 빨간색으로 표시된 버튼을 눌러서 브라우저의 상,하,좌,우에 위치시킬 수 있습니다. 저는 오른쪽에 두는 것이 편해서 그렇게 설정해 놨습니다.
- 이 상태에서 콘솔에
player
라고 입력하면, 아래 처럼 MetaMask에서 생성한 지갑 주소가 출력됩니다.
콘솔의 helper를 사용해 봅니다.
- 현재 ether balance를 확인할 수 있는 명령어 입니다.
getBalance(player)
- 위의 명령어를 입력했을 때 Promise {< pending >}과 같은 메세지가 나온다면 해당 메세지를 펼쳐 보면 원하는 값이 나오긴 합니다. 하지만 보다 깔끔한 값 확인을 위해선 명령어 앞에
await
을 붙여서 실행해야 합니다. help()
명령어는 게임 플레이시 사용 될 유용한 명령어들을 알려줍니다.
The ethernaut contract
ethernaut
명령을 통해서 Ropsten Test Network에 올라가 있는 ethernaut의 contract를 확인할 수 있습니다.- 레벨 클리어 정보 등을 담고 있을 것 같은데, 이 게임을 진행할 때 콘솔을 통해서 직접적으로 사용하진 않습니다. 버튼 등을 통해서 호출하게 됩니다.
ABI를 통해서 정보를 주고 받습니다.
- Ethernaut는 Ethernaut.sol을 포함하고 있는 TruffleContract입니다.
- Web3를 이용해서 Smart Contract와 상호작용을 하려면 ABI가 필요합니다.
- Ethernaut의 ABI는 Ethernaut.sol의 public method에 접급할 수 있게 해줍니다.
owner
명령어가 그 중 하나입니다.
Test ether를 받아 봅니다.
- Test network에서 작업을 하지만, 그래도 transaction을 일으킬 때 gas fee가 필요합니다.
- 그래서 https://faucet.metamask.io/ 에 접속해서 request 1 ether from faucet 버튼을 누르면 잠시 후에 test용 ether가 MetaMask 지갑으로 들어옵니다.
Level instance를 생성합니다.
- Level을 플레이할 때 마다 새로운 level instance를 생성해서 해당 instance를 통해서 문제를 푸는 방식입니다.
- 맨 아래에 Get new instance를 눌러보세요.
- MetaMask 창에 Gas Limit, Gas Price를 넣는 곳과 버튼 3개(RESET, SUBMIT, REJECT)가 있습니다.
- 우리는 test ether가 있으니 Gas price를 넉넉하게 5 Gwei 정도 주고 SUBMIT 버튼을 누릅니다.
- 그러면 콘솔에 Sent transaction 메세지가 뜨고, 잠시 기다리면 Mined transaction 이라는 메세지가 추가로 뜹니다.
- 금방 우리가 submit을 누른 순간 Ropsten test network에 contract를 배포한 것입니다.
- Instance address라고 나오는 것이 배포 된 contract의 주소입니다.
Level contract를 확인합니다.
- 아까
ethernaut
명령을 통해서 contract를 확인한 것 처럼, 방금 우리가 배포한 contract는contract
명령을 통해서 확인할 수 있습니다. - 펼쳐서 보면 abi라는 것이 있는데, 그것을 펼치면 호출할 수 있는 public method를 확인할 수 있습니다.
contract와 메세지를 주고 받으며 Level 임수를 완수합니다.
await contract.info()
명령을 입력하면 이번 level의 임수 완수를 위한 힌트가 나옵니다.- 힌트를 따라서 명령어를 입력하다 보면 임수를 완수하게 되고, 모든 임수 완수 후엔 맨 아래 Submit instance 버튼을 눌러서 임수 완수 트랜잭션을 기록하면 다음 level로 넘어갈 수 있습니다.
오늘은 우선 문제를 풀이 위한 기본 준비 작업을 마쳤습니다. 앞으로 한 문제 한 문제씩 풀어가며 포스팅을 할 예정입니다. 혹시나 직접 풀고 싶으신 분들께는 스포가 될 수 있으니, 앞으로 ethernaut 문제 풀이 편은 읽지 않는 편이 좋으실 것 같습니다.^^;; 앞으로 열심히 한번 풀어 보겠습니다!!
안녕하세요. 관련 과정을 따라하다가 질문이 생겨서 글을 남깁니다. Test Ether를 MetaMask계정에 받았고, Ropsten 테스트넷으로 연결 설정 후 Ethernaut 페이지에 connection까지 생성했는데, GetNewInstance 버튼을 클릭하면 다음과 같은 에러가 발생합니다.
Uncaught (in promise) TypeError: Cannot read property 'address' of undefined
창을 새로고침하면(연결된 상태로) 다음과 같은 에러가 발생합니다.
Uncaught (in promise) TypeError: Cannot read property '_middleware' of undefined
구글링을 해보아도 해당 에러에 대한 정보가 딱히 나오지 않아, 놓친 과정이 있는지 댓글 남깁니다. 브라우저는 크롬 사용하고 있습니다.
좋은 글 감사합니다!
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit