SMT 토큰 무한 복사 해킹 발생
(Apr-24-2018 07:16:19 PM +UTC) 부정한 방법으로 SMT토큰이 발행되는 해킹 사건이 발생했습니다.
이더리움기반의 모든 토큰은 발행수량을 한정하는 방식과 지속적으로 필요한 대로 추가하는 방식이 있는데 사실 내부적으로 보면 별반 차이가 없습니다.
초기 토큰 발행자에 의해 발행수량이 결정되면 이 숫자를 활용하여 주고 받으면서 총 통화를 유지하는 방식인데 특정한 계좌에 숫자를 변경하면 총통화와 개별계좌의 잔액 합산이 달라지는 문제가 발생합니다.
이를 악용한 범죄가 이번에 발생했습니다.
다음은 SMT 토큰의 transferProxy함수 부분입니다.
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;
}
전송하고자 하는 금액이 _value이고 수수료가 _feeSmt인데 이 둘은 unsigned int (256bit)입니다. 해커는 여기서 _value와 _feeSmt를 허용 최대값으로 설정하고 전송요청을 합니다. 여기서 핵심적인 부분은 붉은색 코드입니다.
입력단에서는 허용최대치이지만 둘을 더하는 순간 오버플로우가 발생하며 from의 잔액보다 작다는 평가를 받게되고 따라서 전송가능한 것으로 판단되게 됩니다. 그렇지 않다면 revert됐겠지만 트릭을 써서 통과한 것이죠.
이더스켄에서 보면 0,1 번 파리미터가 동일합니다. 송.수신인이 동일한 것입니다. _from == _to
파란색 윗줄은 _to에 해당금액을 넣는 부분이고 파란색 아랫줄은 _from에서 해당금액을 빼는 부분입니다.
오버플로우가 없다면 동일한 금액을 넣었다 빼게되는 것인데. feeSmt라는 소정의 수수료를 합산하는 과정에서 오버플로우가 나면서 추가할때는 원하는 만큼 추가가 된것이고 뺄때는 최소값이 빠지는 상황이 발생한 것 입니다.
오버플로우를 신경쓰지 않고 smart contract를 만들었다는 점에서 문제가 심각하게 될생했습니다.
'solidity' 카테고리의 다른 글
geth loadScript 확인 할 점 (0) | 2018.03.20 |
---|---|
Fallback Function (0) | 2018.03.14 |
Contracts (0) | 2018.03.14 |
State variable Local variable (0) | 2018.03.14 |
Creating Contract via "new" keyword (0) | 2018.03.14 |