debug random = 3

 

안녕하세요. 온더의 철학자입니다.

 

SMT라는 ERC20토큰의 토큰 이중지불 해킹이 일어났습니다. 이 해킹건에 대해 설명이 필요한 것 같아 긴급하게 글을 남깁니다.

 
 
결론부터 말씀드리면, SMT토큰은 표준 ERC20함수가 아닌 기능을 구현해 놓고 사용했고, 이에 코드 보안점검(audit)이 제대로 이뤄지지 않아 일어난 사고입니다. (ERC20토큰 혹은 블록체인 자체의 문제는 아닙니다.)

 

해킹 시나리오

해커는 함수의 취약점을 이용해 엄청난 량의 토큰을 만들어 본인의 계정으로 받은 후에, 이 중 1경개의 토큰을 거래소로 보냈습니다.

해킹은 구체적인 다음 시나리오로 이뤄졌습니다.

 

  1. transferProxy함수를 이용해 해커 본인의 계정으로 65,133,050,195,990,400,000,000,000,000,000,000,000,000,000,000,000,000,000,000.891004451135422463 토큰을 만들어냄

  2. transferProxy함수를 이용해 해커 본인의 계정으로50,659,039,041,325,800,000,000,000,000,000,000,000,000,000,000,000,000,000,000.693003461994217473 토큰을 만들어냄

  3. 받은 토큰 중 10,000,000,000,000,000개의 토큰을 거래소(후오비)로 옮김

  4. 옮긴 토큰을 거래소에서 판매(다른 코인or 현금으로 교환, 팩트확인 필요)

  5. 다른코인 or 현금을 출금(팩트확인 필요)

 

오버플로우

오버플로우란 이더리움 프로그래밍 언어에서 선언한 변수의 제한한 표현형을 넘어갈 경우, 해당 값이 0부터 시작하는 현상을 뜻합니다. 일반적으로 토큰을 전송할 때 uint256(양의 정수, 2²⁵⁶까지 값 표현 가능)형을 선언해서 사용합니다. 만약 함수 호출 간 입력한 값이 2²⁵⁶을 넘어설 경우, 이 값은 0이 됩니다.

예를들어 uint256형으로 a라는 변수를 선언했는데, a에 2²⁵⁶+1이라는 값을 할당하려고 하면, a는 0이 됩니다.

 

transferProxy()

이 함수는 SMT토큰 팀에서 특별히 만든 함수로써, 이더가 없는 사용자가 다른 제3자를 이용해 SMT토큰을 수수료로 내고 토큰을 보낼 수 있는것이 가능케 하는 기능을 구현해 놓았습니다. 소스코드에는 다음과 같은 주석이 붙어있습니다.

Proxy transfer SmartMesh token. When some users of the ethereum account has no ether, he or she can authorize the agent for broadcast transactions, and agents may charge agency fees

이 함수는 다음 여섯개의 파라미터를 받습니다.

  • address _from //보내는 사람
  • address _to //받는사람
  • uint256 _value//보낼값
  • uint256 _feeSmt// 제3자에게 지불할 수수료
  • uint8 _v //v, r, s는 트랜잭션 서명값으로 사용됨
  • bytes32 _r
  • bytes32 _s

이 함수의 기본적인 구성 로직은 다음과 같습니다.

  1. 보내는 사람의 잔액(from)이 충분한지 확인한다(보내려는 토큰 수량이 보내는 사람의 잔액보다 작어야 함)

  2. v,r,s를 이용해 거래의 서명값이 보내는 사람과 일치하는지 확인한다.

  3. 토큰을 보낸다

문제는 1번 과정에서 터졌습니다. 오버플로우를 이용해서 공격이 이뤄졌습니다.

 

transferProxy()에서 오버플로우 호출

위에서 확인할 수 있듯이, 세번째 파라미터인 value는 uint256(2²⁵⁶)의 데이터를 표현할 수 있습니다. 그런데 해커는 이 세번째 파라미터에 엄청나게 큰 값을 집어넣어 함수를 호출합니다. 해커가 호출한 값들은 다음과 같습니다.

 

 

해커가 65,133,050,195,990,400,000,000,000,000,000,000,000,000,000,000,000,000,000,000.891004451135422463 토큰을 만들어 낸 트랜잭션인데, 링크를 타고 들어가서 호출한 내역을 보면 특이한 점을 확인할 수 있습니다.

 

1*sbvi6Q8cI88ZeX4dCjMdyw.png 해커가 호출한 transferProxy 값으로 전달한 세번째 값이

8fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff

인 것을 확인할 수 있습니다. 이 값을 2진수로 환산하면

1000111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111

가 됩니다.

 

네번째 값도 중요한데 이 값은7000000000000000000000000000000000000000000000000000000000000001 입니다.

 

2진수로 환산하면

111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 이 되죠.

 

세번째 값과 네번째 값을 더하면, 2²⁵⁶을 넘어가게됩니다.

 

transferProxy()에서 보내는 사람의 잔액 확인 조건문

앞서 말씀드렸다시피, 이 함수는 3개의 로직으로 구성되어 있습니다.

  1. 보내는 사람의 잔액(from)이 충분한지 확인한다(보내려는 토큰 수량이 보내는 사람의 잔액보다 작어야 함)

  2. v,r,s를 이용해 거래의 서명값이 보내는 사람과 일치하는지 확인한다.

  3. 토큰을 보낸다

1번 조건문이 중요한데, 이 부분만 통과하면, 없는 토큰을 만들어 낼 수 있습니다. 해커는 앞의 오버플로우의 특성을 이용해 1번 로직을 가볍게 통과해버립니다.

조건문은 다음의 코드로 구현되어 있습니다

if(balances[_from] < _feeSmt + _value) revert(); // 1번 조건문의 구현

방금 전 말씀드린 세번째 값과 4번째 값이 _value와 _feeSmt입니다. 둘을 합치면 2²⁵⁶비트의 표현형을 넘어가 값이 0으로 오버플로우가 발생했고, 조건문을 손쉽게 통과했습니다.

 

조건문을 통과했으니, 잔액보다 더 큰 값인 8fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff을 보낼 수 있게 되어버렸고, 이 값을 10진수로 바꾸면 65133050195990359925758679067386948167464366374422817272194891004451135422463가 되는데, 이는 해커가 허공에서 만들어낸 토큰의 수량과 정확하게 일치합니다.

 

 

SafeMath()를 이용한 대비책

우리 똑똑한 개발자들이 이러한 문제를 가만히 뒀을까요? 아닙니다.

EVM의 스택구조의 특징으로 인해 생기는 이러한 특징(문제라기보다는 특징에 가깝습니다. 솔리디티라는 언어만 겪는 문제도 아니구요)을 이해하고 있던 프로그래머들은 이미 초기부터 SafeMath라는 함수를 만들어 사칙연산을 수행해 왔습니다.

 

 

SafeMath는 사칙연산 중 이러한 오버/언더플로우 문제가 발생했을 경우 곧바로 에러를 발생시키도록 설계되어 있습니다.

요즘 개발되는 컨트랙트 중 SafeMath를 사용하지 않는 경우는 매우 드뭄니다. 만약 safeMath를 사용하지 않은 컨트렉이 있다면, 이는 매우 초보적인 컨트랙트 엔지니어이거나, 오류의 가능성을 알고도 일부러 했다고 밖에 볼 수 없습니다.

다시 transferProxy()로 돌아가서 구현된 코드를 확인 해 볼까요?

 
if(balances[_from] < _feeSmt + _value) revert(); // SMT의 현재 구현코드, 잘못된 구현

 

오버플로우 가능성이 있는 사칙연산을 곧바로 사용한 문제가 있습니다. 이를 다시 올바른 방식으로 짜게 되면

 
if(balances[_from] < _feeSmt.add(_value) ) revert(); //safeMath library를 이용한 올바른 코딩 패턴

 

이렇게 바꿀 수 있습니다.

 

코드 감사(Audit, 오딧 업무)

스마트 컨트랙트의 비즈니스 분야중에 오딧(코드감사)이라는 분야가 있습니다. 알려진 보안 패턴들을 바탕으로 코드를 점검해 문제를 사전에 예방해주는 업무입니다. 이러한 일만 하는 전문적인 팀도 있습니다.(Zeppelin, Onther Inc.([email protected]), jason kim님 등)

정수형 오버/언더플로우 문제는 모든 오딧 보고서의 첫번째 점검 항목이자, 기본중에 기본입니다.

 

결론

금번 SMT 사례는 전 4가지 관점으로 보고 있습니다.

 

  1. 엄청나게 초보적인 스마트 컨트랙트 엔지니어가 개발을 진행했다. 

  2. 혹은 엔지니어는 알고도 일부러 이런 방식으로 개발을 했다?

  3. 기본적인 감사업무를 진행하지 않았다.

  4. 거래소는 함량미달의 코인을 무차별 상장했다.

 

그런데 일부 사용자들은 이러한 문제를 보고 마치” ERC20의 구조적인 문제다”, “이더리움의 위기다"라고 사실을 왜곡해 확대재생산을 하는 “세력”이 있는 것 같습니다.

 

이를 통해 무엇을 얻고자 하는지 모르겠지만 이는 이더리움과 ERC20의 구조적인 문제가 아니며, 개발팀이 오딧이라는 필수적인 업무를 누락했을 가능성이 높습니다.

 

블록체인에 기록되는 스마트 컨트랙트 코드는 직접적으로 금전과 연결된 경우가 매우 많고, 이에 대한 세밀한 설계와 점검이 필요합니다.

 

금번의 사태를 바탕으로 블록체인 프로젝트를 진행하는 팀들의 코드 보안감사의 중요성을 인식하고, 거래소는 무차별적인 상장이 아닌 엄격한 검증을 거친 토큰을 상장하는 등의 방식으로 올바른 산업의 성장이 이루어 졌으면 좋겠습니다.

감사합니다.

 

참고자료

알리는글

온더에서는 알려진 솔리디티의 보안점검 항목과 자료에 대한 레퍼런스를 수집해 깃헙에 모아 오픈하고 공유하여 이러한 일이 일어나지 않도록 노력을 기울이고 있습니다[Auditing Reference]. 공부나 업무를 하는 과정에서 알게 된 지식들은 서로 공유하여 보다 나은 생태계 기여에 도움을 주시면 좋을 것 같습니다.

 

-------------------------------------

꼬리말

* 게시글 내용 삭제레벨 강등

* 질문은 각 주제별 게시판에.

 

비트코인 암호화화폐 커뮤니티 땡글~ 땡글~

-------------------------------------

31 CASH

철학자's 서명

다단계 코인을 판단하는 4가지 기준

  1. 백서(Whitepaper)의 참신성

  2. 운영진과 개발자들의 이력

  3. ICO의 투명성

  4. 코드의 존재(특히 블록체인 로직과 관련된)

by 철학자

Atachment
첨부 '1'
댓글 21
  • ?
    asdcasc 2018.04.25 23:46
    엄청 좋은 자료네요. 솔리디티와 관련된 정보는 어디서 얻으시나요? 한국에 솔리디티 관련 인터넷 커뮤니티가 있나요?
  • ?
    철학자 2018.04.26 02:32
    to asdcasc :
    페이스북과 텔래그램을 중심으로 개발자 커뮤니티가 형성되어 있습니다.

    그리고 전 직업 블록체인 엔지니어입니다^^;;
    공부는 팀원들이랑 업무 하면서 같이 합니다.

    이더리움 블록체인 R&D스타트업 온더 페이스북 페이지 https://www.facebook.com/OntherInc/

    이더리움 사용자그룹 https://www.facebook.com/groups/ethereumkorea/

    블록체인 개발자모임 https://www.facebook.com/groups/114962092511047/

    솔리디티 코리아https://www.facebook.com/groups/soliditykorea/

    한국 블록체인 비즈니스 연구회
    https://www.facebook.com/groups/kblockchain/

    온더 공식 텔래그램(전문가들과 이더리움 기술 관련 질의응답을 나눌 수 있음)
    https://t.me/onther_blockchin
  • ?
    naverad 2018.04.26 00:06
    잘 보았습니다. 사태를 어떻게 처리 할지 궁금해 지네요.
  • profile
    young69 2018.04.26 00:12
    정말 인간은 위대합니다^^
  • ?
    전주박씨 2018.04.26 00:23
    잘 봤습니다. 감사합니다!!
  • profile
    지나니 2018.04.26 00:36
    소논문 감사합니다.
  • ?
    천웅 2018.04.26 01:01
    팩트체크.. 잘봤습니다.
  • profile
    형수 2018.04.26 01:14
    철학자님 지식에 감탄했습니다.
  • ?
    XTR 2018.04.26 01:23
    그렇게 리스크가 큰 부분이라면 SafeMath를 +- 등 기본 연산에 사용하게 하고, 필요시 (gas사용량 감소?) 개발자가 UnsafeMath를 사용해서 개발하도록 솔리디티 패치가 되어야 할 것 같습니다. 누가 proposal 좀 해주면 좋겠네요.
  • ?
    철학자 2018.04.26 02:34
    to XTR :
    보통의 경우에는 리스크가 크지 않습니다만, 특정한 형태로 구현하면 리스크가 생깁니다.
    개선이나 제안이 필요할 것 같긴 합니다.
  • profile
    비트미 2018.04.26 09:28
    to XTR :
    예, 저도 비슷한 생각을 했는데요... 오버플로우에 대해서도 0으로 설정하는게 아니라 에러를 발생시켜야 한다고 봅니다.
    다른 언어도 그렇다지만 돈과 관련된 언어에선 그렇게 하는게 맞다고 보거든요.
  • profile
    다롱잉임 2018.04.26 02:23
    철학자님 감사합니다
  • profile
    금마 2018.04.26 02:42
    SafeMath 만 썼어도 막을 수 있었을텐데 ...
  • profile
    스투시 2018.04.26 02:48
    대표님 좋은글 땡글에도 기고해주시고 감사합니다.
  • ?
    quantum1 2018.04.26 07:36
    이해하기 쉽게 설명해주셨네요. 자료 감사합니다. 추천누르고 갑니다. *^^*
  • profile
    오늘만사는광부 2018.04.26 09:13
    머리에 쏙쏙 들어오는 알기 쉬운 설명에 감사합니다.
  • ?
    Vaultboy 2018.04.26 11:11
    진짜 저런 단순한 버퍼 오버플로우 기법으로 뚫려버린거면 말도안되게 취약한건데...
  • profile
    크루토 2018.04.26 12:54
    좋은글 잘보았습니다
  • profile
    컴빠 2018.04.27 03:55
    깔끔한 정리 감사합니다.
  • profile
    미남자TG 2018.04.28 21:24
    좋은 분석글 잘 봤습니다.
    좋아요. 꾹.
  • ?
    AppA 2018.05.02 17:21
    잘 읽었습니다~

List of Articles
번호 분류 제목 추천 수 조회 수 글쓴이 날짜
공지 [Air Drop 이벤트] 게시판을 신설합니다 9 updatefile 793
땡글운영위원회
2019.05.17
공지 [땡글] (주)이에스엔운영 채용공고 15 file 2 2789
ESN운영
2019.05.14
[AD] [AD] ESN으로만 신청 가능한 광고자리입니다. 14 11705
관리자
2019.01.02
1107 개발 4/28 로빈8 (PUT) 밋업 후기입니다. 안녕하세요, 늘 땡글에서 많은 도움받고 있는 괴발개발입니다.   4/28 삼성동 M-Tower 에서 로빈8의 밋업행사가 있었습니다.   PUT는 로빈8에서 진행하는 프로젝트로 지난 1월에 이미 ICO를 성공적으로 마쳤으며, Bit... 2 file 1 1016
괴발개발
2018.04.30
1106 개발 전세계 실시간 코인 및 거래소 챠트/시세를 지원하는 모바일 웹 버전을 만들었습니다. *** 답변 댓글이 있을 때 글 내용 삭제시 경고 없이 계정이 정지됩니다. *** *** 개인정보가 포함된 경우 혹은 불법적인 요소의 수정은 가능합니다.*** -----------------------------------------------------------... 8 file 6 1417
준형이아빠
2018.04.29
1105 질문 데탑에서 글카 2개로 채굴소소히 공부중입니다.. 현제 문제가 생겼는데   엔디비아 텍스트에 글카 1개만 설정해놓고하면 잘돌아가는데 엔디비아 텍스트에 글카 2개 설정해놓으면      화면같이 에러가 뜹니다.. 원래 두개다 잘돌아갔는데 드라이브업데이트이후 이런... file 537
다행이군
2018.04.29
1104 개발 현재까지 누적된 자산별 매수금액 을 알수있는 API 가 ... 두번째 ?     빗썸 인데요...   답변 ===&gt;   https://api.bithumb.com/info/user_transactions더보기 회원 거래 내역이렇게 있을겁니다.응답 json으로는 {&quot;status&quot; : &quot;0000&quot;,&quot;data&quot; : [{&quot;search&quot; : &quot;2&quot;,&quot;transfer_date&quot; : 1417... 614
킴나라
2018.04.29
1103 개발 현재까지 누적된 자산별 매수금액 을 알수있는 API 가?     어떤 API 가 이런 역할을 하는지 알 수가 없네요...                   ------------------------------------- 꼬리말 * 게시글 내용 삭제시 레벨 강등 * 질문은 각 주제별 게시판에.   비트코인 암호화화폐 커... 5 483
킴나라
2018.04.29
1102 질문 코인허브 만들려고 합니다. 안녕하세요   https://github.com/ethersocial/ethersocial-pool     위 링크를 보고 따라해 봤습니다 그런대 저는 도메인은 없는 상태이고 사설 IP망에서 IP로 접속해서  테스트를 해보려고 합니다   우선 ESN코인부... 1 file 795
Miningwithme
2018.04.28
1101 개발 해커 정보 공유     바이러스 스크립트 랜섬웨어 걸려요 bitcoin hacking 유튜브 거기 적힌 url클릭금지 https://www.youtube.com/watch?v=_h-D3cEoY2A                                 ------------------------------------- 꼬리... 4 file 1388
돈벼락치기
2018.04.27
1100 질문 엔트풀 시아주소... 도와주십쇼   *** 답변 댓글이 있을 때 글 내용 삭제시 경고 없이 계정이 정지됩니다. *** *** 개인정보가 포함된 경우 혹은 불법적인 요소의 수정은 가능합니다.*** --------------------------------------------------------... 6 file 528
후덜들
2018.04.26
1099 개발 - -       ------------------------------------- 꼬리말 * 게시글 내용 삭제시 레벨 강등 * 질문은 각 주제별 게시판에.   비트코인 암호화화폐 커뮤니티 땡글~ 땡글~ ------------------------------------- 2 684
ooii12
2018.04.26
1098 개발 ERC20 홈페이지 연동 토큰 제작해주실 분   ERC20 홈페이지 연동 토큰 제작해주실 분 010 - 2069 - 7359 10:00 ~19:00 통화 가능합니다                     ------------------------------------- 꼬리말 * 게시글 내용 삭제시 레벨 강등 * 질문은 각 주제... 2 832
5105
2018.04.26
1097 질문 - -     ------------------------------------- 꼬리말 * 게시글 내용 삭제시 레벨 강등 * 질문은 각 주제별 게시판에.   비트코인 암호화화폐 커뮤니티 땡글~ 땡글~ ------------------------------------- 3 502
ooii12
2018.04.26
1096 개발 비트코인 거래소, ICO 완벽 개발   안녕하세요   비트코인 거래소, ICO개발 팀장입니다. 고객분들의 요구사항에 따라 완벽하게 개발 및 유지 보수해드립니다.   회신부탁드립니다 감사합니다   email : [email protected] skype : TK Team te... 1 850
트레이딩_MAN
2018.04.26
» 개발 SMT 토큰 이중지불 해킹에 대한 설명과 대비책   안녕하세요. 온더의 철학자입니다.   SMT라는 ERC20토큰의 토큰 이중지불 해킹이 일어났습니다. 이 해킹건에 대해 설명이 필요한 것 같아 긴급하게 글을 남깁니다.   Ethereum Transaction 0x1abab4c8db9a30e703114... 21 file 41 2700
철학자
2018.04.25
1094 개발 ERC20 토큰 제작 가능한 분     ERC20 토큰 제작 해주실 분 010 ㅡ 2069ㅡ  3027 10;00 ~ 19;00 통화 가능                   ------------------------------------- 꼬리말 * 게시글 내용 삭제시 레벨 강등 * 질문은 각 주제별 게시판에.   비... 1 1 1441
5105
2018.04.25
1093 질문 - 햐7-------- 2 584
ooii12
2018.04.25
1092 질문 ETH -> ERC20 오입금 복구 불가능한지 문의드립니다....(절실)   이클300개를 업비트 다른계정에서(보낸지갑 업비트, 받는지갑 업비트) 제 업비트 이클지갑주소로 보낸줄 알았는데요.. 제 업비트 슨트지갑주소로 간거같네요 분명히 전 큐알코드 찍었는데..   6) ETC 또는 ETH를 본... 3 1 1258
존버ㅠ
2018.04.24
1091 질문 오토핫키 if 에 변수 비교문 하는거에서 막히는데 원인을 모르겟어요 경고온도:=12 글픽로그온도1:=20 글픽로그온도2:=25 글픽로그온도3:=23 글픽로그온도4:=21 글픽로그온도5:=26 글픽로그온도6:=27 글픽로그온도7:=28 글픽로그온도8:=25 글픽로그온도9:=22 글픽로그온도10:=26 글픽로... 17 2 1215
형수
2018.04.23
1090 개발 탈중앙화된 네이버 지식인을 만들었습니다 https://steemit.com/kr/@yunjh1994/xdemi https://github.com/quokki/quokki-whitepaper http://www.quokki.net/   사용방법은 스팀잇 글을 참조해주세요 자유게시판에도 글 올려서 중복이긴 한데... 딱히 관심도 못... 31 15 3336
asdcasc
2018.04.23
1089 개발 마스터카드와 연동하기   안녕하세요..   개발한 코인을 체크카드와 연동하여 누구나 손쉽게 사용하고 싶어 하지 않나요? 저희 회사가 해외 은행과 제휴하여 마스터카드와 연동이 가능한 카드를 출시하였습니다.   카드는 기명식과 무기명식... 578
진짜호호아줌마
2018.04.23
1088 질문 일본 마이닝 풀 사이트들 추천 부탁드립니다       일본 마이닝 풀 사이트 추천 부탁드립니다. 감사합니다                 ------------------------------------- 꼬리말 * 게시글 내용 삭제시 레벨 강등 * 질문은 각 주제별 게시판에.   비트코인 암호화화폐 ... 348
트레이딩_MAN
2018.04.23
Board Pagination Prev 1 ... 23 24 25 26 27 28 29 30 31 32 ... 83 Next
/ 83