develop custom_top_html:no
default debug random = 1 / type = READ / detected = READ

 

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

 

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.(info@onther.io), jason kim님 등)

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

 

결론

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

 

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

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

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

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

 

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

 

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

 

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

 

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

감사합니다.

 

참고자료

알리는글

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

 

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

꼬리말

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

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

 

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

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

31

철학자님의 서명

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

  1. 백서(Whitepaper)의 참신성

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

  3. ICO의 투명성

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

by 철학자

Attachment
첨부 '1'
댓글 21
default debug random = 0 / type = READ / detected = READ

List of Articles
번호 분류 제목 추천 수 조회 수 글쓴이 날짜
1834 개발 모니터링 프로그램 ver 0.82 업데이트 안녕하세요. 남자별입니다.   어제 하루 잠시 시간이 비어서 0.8 업데이트에 몇몇 기능 개선을 추가했습니다. 주요 업데이트 내용은 다음과 같습니다. 자세한 설명은 압축파일 안에 Readme.txt ... 107 file 97 12960
남자별
2018.03.20
1833 개발 허접하지만 알뜰한 기능의 채굴기 모니터링 프로그램입니다 기능 -채굴기 1set의 평균온도와 해쉬 -모든 그래픽카드들의 온도와 해쉬 -온도와 해쉬의 수치별 색상변화 -각 set별 혹은 그래픽카드별 설정수치시 알람 발생(sms 문자발생, 다수인원 가능) -설... 23 file 93 8222
503
2017.08.12
1832 개발 다중 수천대 가능 무료 원격조정 모니터링 알람 제어 ( 꽁짜 )     천리님 글  1. 마이너 컨픽 파일 수정2. 컨픽 파일 일괄 업로드3. 마이너 재시작4. 컴퓨터 리부팅5. 마이너 버전 업데이트 시 파일 일괄 업로드6. 마이닝 프로그램 일괄 변경 (ex. Claymore... 35 file 76 5799
다롱잉임
2018.04.08
1831 개발 오버클럭을 손쉽게! 이지 오버클럭을 릴리즈 합니다. 안녕하세요, 땡글을 통해 여러가지 도움을 얻고 있는 괴발개발 입니다.   애프터 버너는 좀 무겁고, 옵션이 너무많아 다루기가 쉽지 않습니다. 또한, 여러 그래픽카드의 정보를 한눈에 보기 어려... 70 file 73 6524
괴발개발
2018.04.20
1830 개발 모니터링 프로그램 ver 0.8 업데이트 안녕하세요. 남자별입니다.   0.7 업데이트 이후로 빠르게 업데이트 해드릴려고 했으나 여러 사정이 겹쳐서 이제서야 업데이트 했습니다. 이런저런 문의/요청사항에 대해서 추가 작업 및 명절이 ... 61 file 67 6783
남자별
2018.03.16
1829 개발 모니터링 프로그램 ver 0.6 업데이트 안녕하세요. 남자별입니다.   최근에 개인일이 바빠져서 모니터링 프로그램 업데이트를 당분간 보류할 생각이었으나 갑자기 핫해진 모네로 관련으로 문의가 많으셔서 -_-a 급하게 땜빵 수정했습... 75 file 61 16910
남자별
2017.08.28
1828 개발 누구나 따라할 수 있는 ETN 마이닝 풀 구축 가이드 입니다. 일렉트로니움 마이닝풀 운영을 위한 설치 가이드 입니다.   ETN 마이닝 풀 서버 설치를 해보려고 했는데 node 버전 문제로 여러번의 실패로 우분투를 재설치하면서 여러번의 삽질을 하여 성공하... 61 60 11922
번트마이너
2018.02.11
1827 개발 오픈소스 거래소 깃헙 공개하였습니다. 안녕하세요 몇일전 거래소 오픈소스로 깃헙에 공개하겠다고한 coinext 개발자입니다. 좀더 리팩토링이나, 보완할걸 하고 공개하려고 했는데, 전반적으로 크게 문제는 없어보여 선공개합니다. 시... 42 57 18805
coinext
2017.12.20
1826 개발 모니터링 프로그램 ver 0.7 업데이트 안녕하세요. 남자별입니다.   최근에 몇몇 분들이 개인적으로 Bminer 지원을 요청하시기에 api 분석만 하고 바로 적용했습니다. Bminer 지원 이외에 다른 수정사항은 아직 적용하기전이라 Bminer... 84 file 53 15326
남자별
2018.01.08
1825 개발 안녕하세요. 오픈소스로 자동 트레이딩+알림 봇 공유합니다.   파이썬3로 제작되었고요.   1. 텔레그램에서 문자인증 받고 자동으로 로그인하는 기능. 2. 텔레그램에서 해당 채널의 메시지를 자동으로 읽는 기능. 3. 읽은 메시지를 정규표현식으로 분석해서... 24 file 48 25236
소프트
2018.01.12
1824 개발 모니터링 프로그램 ver 0.4 업데이트 안녕하세요. 남자별입니다. 이번 업데이트는 좀 늦었습니다. 개인적인 사정과 회사프로젝트가 바빠져서 그랬습니다.   더이상 미루기 힘들어 몇시간정도 뚝딱 거려봤습니다. 저번에 요청오신 기... 71 file 47 18761
남자별
2017.07.19
1823 개발 모니터링 프로그램 ver 0.5 업데이트 안녕하세요. 남자별입니다. 이번 업데이트는 기존 요청사항들중 편의성 부분으로 개별 설정할 수 있도록 수정했습니다.   ver 0.5  업데이트                 monitor.ini 설정 추가. 기본 배포... 61 file 44 12814
남자별
2017.08.11
1822 개발 전세계 실시간 챠트/시세를 원화로 모아서 볼수 있는 사이트를 만들었습니다 전세계 3048개 코인, 648종 가상화폐를 실시간 차트/시세를 원화로 모아서 볼수 있는 사이트를 만들었습니다.   암호화폐 실시간 차트및 시세를 각국 통화로 암호화폐별, 거래소별, 관심코인으로... 33 file 42 4686
그냥초보
2018.04.10
개발 SMT 토큰 이중지불 해킹에 대한 설명과 대비책   안녕하세요. 온더의 철학자입니다.   SMT라는 ERC20토큰의 토큰 이중지불 해킹이 일어났습니다. 이 해킹건에 대해 설명이 필요한 것 같아 긴급하게 글을 남깁니다.   Ethereum Transaction 0x1... 21 file 41 2879
철학자
2018.04.25
1820 개발 이더리움과 스마트 컨트랙(2) - 30분만에 ICO 하기 30분만에 ICO하기   안녕하세요. 오늘은 조금 자극적인 제목을 가지고 와봤습니다. 요즘 ICO 많이들 참여하시고,  직접 하시는 분들도 많이 계신데요. ICO에 필요한 토큰을 단 30분 만에 발행하... 28 file 40 8467
파이리
2018.02.22
1819 개발 단순 콘솔 모니터링 프로그램 ver 0.2 배포   안녕하세요. 지난번에 올린 모니터링 프로그램에 요청사항들이 있으셔서 수정했습니다. 이하는 개발노트입니다. 보안 관련으로 걱정하시는 분들도 계셔서 소스코드도 같이 첨부합니다. ver 0.... 44 file 39 8885
남자별
2017.06.26
1818 개발 채굴 관리프로그램 MINE ASSIST 베타버전 공개 안녕하세요. 저는 S전자에서 개발자로 일하다가 지금은 작은 스타트업을 하고 있는 파이리입니다.   얼마 전에 채굴기 관리 프로그램을 개발하고 있다고 글을 올린적이 있었는데, 베타 테스트에 ... 180 file 39 14897
파이리
2017.06.17
1817 이더리움 데브콘4 참관기 1 이더리움 데브콘4 참관기 1 2018년 프라하에서 열린 이더리움 데브콘4에 참석했었습니다. 행사 참석 기사를 위해 썼던 내용을 정리해보았습니다.   데브콘4에서 가장 인상깊었던 내용   세션하... 24 file 34 2865
atomrigs
2018.11.18
1816 개발 예스빗부스터 무료배포(ver 0.0.1)   예스빗매니저 오픈베타서비스에 참여해주신 분들의 요청으로 윈도우 최적화 프로그램(예스빗부스터)을 배포합니다. 앞으로도, 요청사항을 검토하여, 지속적인 업데이트를  진행할  예정입니다.... 22 file 34 4158
예스빗
2018.07.09
1815 [강좌] 쌩광부의 모바일 지갑 만들기 #4. 이더리움 계열 지갑 만드는 방법 안녕하세요. 쌩광부입니다.   이번 시간에는 RN에 대한 설명을 잠시 접어두고 이더리움 계열 코인의 지갑 구조에 대해서 설명하도록 하겠습니다.   #4. 이더리움 계열 지갑 만드는 방법   1. Pri... 16 30 1656
쌩광부
2018.11.21
Board Pagination Prev 1 2 3 4 5 6 7 8 9 10 ... 92 Next
/ 92
default debug random = 0 / type = READ / detected = READ