-
솔리티디 smt 취약점 분석카테고리 없음 2018. 7. 17. 13:52
function transferProxy(address _from, address _to, uint256 _value, uint256 _feeSmt, uint8 _v,bytes32 _r, bytes32 _s) public transferAllowed(_from) returns (bool){ if(balances[_from] < _feeSmt + _value) revert(); uint256 nonce = nonces[_from]; bytes32 h = keccak256(_from,_to,_value,_feeSmt,nonce); if(_from != ecrecover(h,_v,_r,_s)) revert(); if(balances[_to] + _value < balances[_to] || balances[msg.sender] + _feeSmt < balances[msg.sender]) revert(); balances[_to] += _value; Transfer(_from, _to, _value); balances[msg.sender] += _feeSmt; Transfer(_from, msg.sender, _feeSmt); balances[_from] -= _value + _feeSmt; nonces[_from] = nonce + 1; return true; }
문제가 되는 SmartMesh 스마트 컨트랙트의 transferProxy 함수를 살펴보도록 한다.
if(balances[_from] < _feeSmt + _value) revert();
이 함수에서 문제가 되는 함수는 _from 주소가 가지고 있는 토큰의 양보다
_feeSmt , _value 값이 크면 전송을 중단하는 제어문을 가지고 있었으나
uint256에 덧셈에 대한 Overflow 처리가 안되있었다.
uint는 이더리움이 표기하는 unsinged int의 변수 생성자 명인데
뒤에 숫자값은 256bit란 얘기이다
즉 최대값은 2^256-1 값이되나 여기서 1을 더하게 되면
그 이상을 표기하지 못하고 0을 표현하게 되버리는 것이다 .
overflow가 발생한다면 실제 결과값은 작은 숫자가 되어
해당 함수를 넘어가 트랜잭션이 발생할수 있다는 것을 포착해
해커는 그 것을 이용하여 약 1경개의 코인을 자신의 erc 지갑으로 입금하였다 .
해결방안
SafeMath 라는 Zeppine사에서 만든 해결방안을 이용한다.
해당 취약점은 블록체인, 이더리움 자체의 문제가 아니라
개발자의 코딩버그이다 ,
개요
smt코인의 총발행량 31억개보다
1경개의 코인이 후오비 ERC 지갑으로 입금되는걸 포착하였다 .
Apr-24–2018 07:16:19 PM +UTC
해커가 발생시킨 트랜잭션을 살펴보자면
[2] 에 해당하는 값이_value 값이고
[3] 에 해당하는 값이 _feeSmt 이다
해커는 해당 토큰은 0개 가지고 있었고
[2]에 해당하는 값과 [3]에 해당하는 값을 더하면
overflow가 발생하게 위애서 서술했듯이 0이 되버리는 것이다.
해커는 결론적으로 엄청난 토큰을 자신에게 전송 할 수 있었다.