[마스터링 이더리움] 스마트 컨트랙트 보안 - 패턴10 레이스 컨디션

in #busy5 years ago

레이스 컨디션 (Race Condition)

  • 경쟁조건: 사용자들이 코드 실행을 경쟁한다.
  • 예를 들어 채굴의 nonce 찾기와 같이 솔루션을 먼저 제출하고자 하는 경쟁.
  • 프런트 러닝 (front running), 누가 먼저 코드를 실행시키나? nonce 문제 해결. 다른 사람보다 앞서서 코드를 실행. 트랜잭션이 블록에 포함되도록 한다.
  • 재진입성은 경쟁조건의 예이다.

취약점

  • 이더리움 노드는 트랙잰션 풀에서 트랙잰션을 선택하여 블록을 생성한다.

  • 트랜잭션은 채굴자가 nonce 문제를 풀고 채굴에 성공해야지만 유효하게 된다.

  • 중요한 것은 채굴자가 어떤 트랜잭션을 블록에 포함할지 결정한다는 것이다.

  • 이 때, 채굴자는 트랜잭션에 할당된 gasPrice가 높은 것을 우선적으로 처리한다.

  • 그런테 해커가 트랜잭션 풀에서 nonce 문제를 풀 수 있는 트랜잭션을 찾아낼 수 있다.

  • 해커는 이 트랜잭션에서 데이터를 얻어서 gasPrice만 더 높여서 트랜잭션을 생성하고, 자신의 트랜잭션이 채굴되도록 할 수 있다. (트랜잭션을 동일하게 구성하고, 오로지 gasPrice만 높여서 트랜잭션 생성)

  • FindThisHash 컨트랙트

1 contract FindThisHash {
2   bytes32 constant public hash =
3     0xb5b5b97fafd9855eec9b41f74dfb6c38f5951141f9a3ecd7f44d5479b630ee0a;
4
5   constructor() public payable {} // load with ether
6
7   function solve(string solution) public {
8     // If you can find the pre-image of the hash, receive 1000 ether
9     require(hash == sha3(solution));
10    msg.sender.transfer(1000 ether);
11  }
12 }
  • 특정 해시를 만드는 문자열을 찾는 것.
  • 사용자는 예상 솔루션을 파라미터로 하여 solve 함수 호출. 해답이라면 이더를 받는다.
  • 해커는 이 사용자가 제출하는 값을 볼 수 있을 수 있다.
  • 먼저 제출한 값이 솔루션인지, 검증하고, 동일한 트랜잭션을 생성할 수 있다. 물론 gasPrice를 크게 해서 말이다.
  • 해커가 채굴자와 다를 것이라는 생각은 하지 않는게 좋다.

예방기법

  • gasPrice의 상한을 두어, 해커가 gasPrice를 높여서 먼저 채굴되지 않도록 할 수 있다.
  • 이렇게 하더라도 채굴자가 해킹을 한다면, 순서를 임의로 조정할 수 있다.
  • 다른 방법은 commit-reveal 방식을 사용하는 것이다.
  • 이것은 사용자가 트랜잭션을 전송할 때, 감춰진 정보(해커도 볼 수 없는 정보)를 추가하여 전송하는 것이다. 트랜잭션이 채굴되어 블록에 기록될 때, 사용자는 다시 트랜잭션을 보내서 감줘친 정보를 드러나게 한다.
  • 이렇게 하면, 앞서 얘기한 프런트 러닝을 막을 수 있다(솔루션이 탈취되는 문제)

Coin Marketplace

STEEM 0.26
TRX 0.11
JST 0.032
BTC 63754.85
ETH 3055.95
USDT 1.00
SBD 3.85