카테고리 없음

솔리티디 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이 되버리는 것이다.

해커는 결론적으로 엄청난 토큰을 자신에게 전송 할 수 있었다.