전형적인 오버플로우와 언더플로우 버그로 인한 해킹입니다.
BatchTransfer 스마트 컨트렉트는 여러명에게 지정된 갯수만큼 코인을 보내는 함수입니다.
그래서 스마트 컨트렉트를 실행할 때 주소리스트, 보낼 갯수를 지정할 수 있습니다.
주소리스트 갯수를 cnt라고 하고 보낼 갯수를 value라고 가정하죠.
BatchTransfer에서 체크하는 조건은
1. value가 0보다 커야한다.
2. value*cnt(총 보낼갯수)이상을 보낼 계정이 가지고 있어야 한다.
입니다. 상식적으로는 이 조건이 맞는데 문제는 컴퓨터가 숫자를 처리할 때는 저장할 수 있는 범위가 있습니다. 그리고 이 범위를 넘어가면 오버플로우나 언더플로우가 발생합니다.
예를 들어 uint256이 처리할 수 있는 숫자의 범위가 0~250이라고 가정을 하죠. 이때 260을 저장하려고 하면 오버플로우가 발생을 해서 값은 10이 되어 버립니다. 반대로 -10의 값이 들어가면 240이라는 값이 되어버립니다.
만약 보내는 계정에 10의 코인이 들어있다고 가정하죠.
5명의 계정에게 51의 코인을 보내려고 하면 총 보내는 양은 255가 됩니다. 계정에는 10 코인밖에 없기 때문에 이 컨트렉트는 취소가 되어야 합니다.
하지만 오버플로우가 발생을 해서 255는 5라는 값이 되어 버리고 5는 계정에 있는 10보다 작기 때문에 무사 통과.
그리고 각 계정에 51개씩 보내기 때문에 5개의 계정에는 51개씩의 코인이 쌓여서 총 255개의 코인이 생깁니다.
그리고 보낸 계정에서는 255개가 빠져나가기 때문에 -245가 되고 언더플로우가 발생해서 5가 됩니다. 결과적으로 uint256이 처리할 수 있는 최대값만큼의 코인을 얻게 되는거죠.
문제는
1. SafeMath를 쓰던가.
2. BatchTransfer을 만들지 말던가.
3. BatchTransfer를 아무나 쓰지 못하게 하던가(토큰 Owner만 쓰게 하던가)
4. BatchTransfer내에서 체크를 잘하던가.
결론
1. 블록체인도 스마트컨트렉트 잘못 작성하면 저렇게 해킹이 됩니다. 정확히는 블록체인이 해킹되는게 아닙니다. 저 컨트렉트가 해킹되는겁니다.
2. 저 코인 지금 사시면 큰일 납니다.
3. 그리고 아마도 저 코인은 예전에 BET 때처럼 새로운 코인 만들어서 원장 뒤져서 롤백을 시키려고 할 겁니다만.
이미 뻥튀기가 된 코인이 시중에 풀려서 저걸 어찌 처리할지는 모르겠네요.
요건 이더스캔에 올라온 코드입니다.
https://etherscan.io/address/0xc5d105e63711398af9bbff092d4b6769c82f793d#code