Keepit 블록체인 칼럼: 해킹 잔혹사 2편

in #kr6 years ago (edited)

킵잇 히스토리.png

Keepit History


안녕하세요! Keepit입니다.
오늘자 해킹 잔혹사는 The DAO 해킹 사태를 중점적으로 다루도록 하겠습니다. The DAO(Decentralized Autonomous Organization, 탈중앙자율조직, 이하 DAO)는 2016년 5월에 ICO를 통해 탄생한, 이더리움 스마트 컨트랙트 프로젝트입니다. DAO는 2016년 당시 ICO 포함 크라우드 펀딩 역사상 최대의 모금액인 1600만 달러를 모금하며 많은 사람들의 기대를 한 몸에 받았습니다. DAO의 ICO와 관련한 자세한 내용은 아래 ICO 흥망사 2편 링크를 타고 들어가시면 확인하실 수 있습니다.

Keepit 블록체인 칼럼: ICO 흥망사 2편


The DAO 해킹 사태

1. 코드로 이루어진 기업 DAO

screen-shot-2016-05-12-at-12.35.56-pm.png
그림1. 코드로 이루어진 기업 DAO

DAO는 탈중앙자율조직이라는 이름에 걸맞게, 오직 코드만으로 돌아가는 무형의 조직, 또는 주인 없는 공동출자회사라 부를만 했습니다. DAO는 실제 주소도, 경영진도 없었고, 모든 내용은 코드로 이뤄져 있었습니다. 모든 업무가 코드로 수행되므로 누구나 github에서 코드를 통해 업무 진행 내용을 볼 수 있고, 감사할 수 있었죠.

DAO는 DAO 토큰에 의해 경영되었습니다. DAO 토큰보유자들(DAO Tokenholder)은 그들이 보유한 토큰에 따라 투표권을 행사하고, 배당금을 분배받으며, 계약자(Contractor)의 제안서가 토큰 보유자의 20% 이상 투표를 받으면 프로젝트가 승인되는 구조였습니다. 또한 토큰 보유자와 계약자 사이에 11명의 중재인(Curator)이 있어서 계약자와 그들이 제안한 코드를 검증하고, DAO Whitelist에 등록합니다. 중재인 역시 주주들의 투표에 의해 임명되거나 해고될 수 있습니다.

the DAO.png
그림 2. DAO의 경영 구조

DAO 제안.png

그림 3. DAO의 제안 페이지
Image from http://www.seunghwanhan.com/2016/07/the-dao-what-is-dao_3.html

2. 코드로 흥하고 코드로 망하다

이러한 DAO의 주주 참여 경영 방식이 효율적이었든, 비효율적이었든 간에 DAO는 그 자체로 놀라운 실험이었던 것만은 분명합니다. 그러나 코드로 흥한 DAO는 코드로 망했습니다. 1600만 달러라는 엄청난 자금을 모금한 프로젝트답지 않게, DAO의 코드는 매우 부실하였고, 결국 2016년 6월 17일 해커의 재귀호출버그를 이용한 무한환불공격에 243만 이더를 해킹당하고 말았습니다. 해킹이 일어나기 전 이미 DAO의 코드 취약점을 지적하는 글들이 많이 올라왔지만, DAO의 제작자 Stephan Tual은 “DAO 기금은 위험에 처하지 않았다"고 발표하고 빠르게 대처하지 않았던 것이 화근이었습니다. 결국 코드로 짜여진 회사의 가장 큰 위협은 해킹이라는 점이 증명되고만 셈입니다.

3. 재귀호출버그(Recursive Calls)를 이용한 무한환불공격

DAO에는 DAO토큰 보유자들이 이더를 환불받을 수 있게 하는 splitDAO 기능이 있었습니다. 해커는 DAO.sol을 분석하면서 이 splitDAO(이더 환불 명령 함수)가 재귀호출에 취약하다는 사실을 발견했습니다. 재귀호출은 하나의 명령문으로 자신을 다시 호출하여 작업을 수행하는 방식입니다.

splitDAO 함수를 이용한 재귀호출공격 과정

  1. split을 제안하고 투표 기간이 만료될 때까지 기다립니다.(DAO.sol, createProposal)
  2. split을 실행합니다.(DAO.sol, splitDAO)
  3. DAO의 토큰을 새 DAO(Child DAO)에게 보내게 합니다.(splitDAO -> TokenCreation.sol, createTokenProxy)
  4. DAO가 잔액을 갱신하기 전에 [3]을 수행한 후 보상(Reward, 27일 후 이더로 회수)을 보내려고 하는지 확인합니다. (splitDAO -> withdrawRewardFor -> ManagedAccount.sol, payOut))
  5. DAO가 [4]를 수행하는 동안, [2]와 같은 매개 변수를 사용하여 splitDAO를 다시 실행하게 합니다. (payOut -> _recipient.call.value -> _recipient ())
  6. DAO는 이제 더 많은 Child 토큰을 보내고 잔고를 갱신하기 전에 보상을 인출합니다. (DAO.sol, splitDAO)
  7. [5]로 돌아갑니다.
  8. DAO가 잔액을 갱신하게 합니다. [7]이 [5]로 돌아가기 때문에 실제로는 결코 일어나지 않습니다.

위의 재귀호출공격 과정은 다음 사이트에서 인용했습니다. 재귀호출공격에 대해 더 자세히 알고 싶으신 분들은 이 사이트를 참조하시면 되겠습니다.
http://hackingdistributed.com/2016/06/18/analysis-of-the-dao-exploit/

해커는 재귀호출을 이용해 DAO 토큰을 구매하는데 지불한 이더만 반환받고, DAO 토큰 split은 철회합니다. 첫번째 반환 요청이 두번째 반환 요청을 일으키고, 두번째 반환 요청이 세번째 반환 요청을 일으키는 식으로 재귀호출이 무한히 반복됩니다. 이를 이용해 하나의 DAO 토큰으로 무한대의 환불을 요청합니다.(https://www.ddengle.com/traders_free/1283386) 이렇게 해커는 2개의 주소에서 대략 250번의 split을 실행합니다.(https://www.reddit.com/r/ethereum/comments/4os7l5/the_big_thedao_heist_faq/)

스크린샷 2017-11-21 오후 7.32.38.png

그림 4. SplitDAO 코드

스크린샷 2017-11-21 오후 9.27.19.png

그림 5. SplitDAO 코드 중 취약한 부분

Image 4,5 from http://hackingdistributed.com/2016/06/18/analysis-of-the-dao-exploit

4. DAO가 촉발한 논쟁, 소프트포크 VS 하드포크

DAO는 코드만으로 운영되는 이더리움 최초의 탈중앙조직이었다는 점에서 분명 기억할 만한 가치가 있습니다. 비록 허술한 코드로 인해 해킹당하며 이 실험은 실패로 끝났지만, DAO는 향후 블록체인 상에 세워질 탈중앙조직들의 역사적 사례로 기억될 것입니다. 비효율적인 중개인, 관리인을 코드로 대체하는 실험은 현재도 진행중이며 이 분야의 미래는 밝습니다. 우리가 매우 관심 가지는 블록체인이라는 기술 자체가 비트코인이라는 금융의 혁신으로부터 시작한 것처럼, 탈중앙조직도 블록체인의 발전과 함께 언젠가 경영의 혁신을 가져올 수 있을 겁니다.

허나 DAO 해킹 사태에서도 알 수 있듯이, 코드가 인간이 만든 도구라면 코드 역시 완벽하지는 않습니다. 인간이 가진 취약점과 인간이 행한 실수 모두 코드에 반영되는 것이지요. DAO 사태의 처리 과정에서 나온 대응방안들은 이러한 실수를 바로잡기 위한 지성들의 치열한 논의를 보여줍니다. 어떻게 보면 DAO 사태에 있어 기억해야할 핵심은 DAO 해킹 자체가 아니라, 이더리움을 살리기 위한 눈물겨운 노력일지도 모릅니다. 이 과정에서 강탈당한 이더를 복구하기 위한 수많은 논의들이 오고 갑니다. 소프트포크로부터 시작해, 하드포크, 그리고 해커와 접촉하려는 시도에 이르기까지 수많은 참여자들이 최선의 방안을 찾기 위해 여러가지 아이디어를 제시합니다. 이 논쟁, 논의가 중요한 이유는, 이들이 취하는 입장이 곧 거버넌스(합의구조)를 이해하는 입장의 차이이기 때문입니다. 탈중앙화라는 이념으로 시작한 블록체인에 사람이 인위적으로 개입하는 것이 옳으냐, 틀렸냐는 논쟁은 여기서 본격적으로 등장하기 시작합니다. 이는 해킹 잔혹사 4편에서 다시 소개해드리겠습니다. 그럼 Keepit histroy는 다음 주 화요일에 찾아뵙겠습니다. 감사합니다.

blockchainnomad

Sort:  

엄격히 이야기하면, 소프트포크 진영과 하드포크진영간의 대립이 아니었습니다. 이더리움 파운데이션에서도 소프트 포크로 문제해결을 하거나 아니면 최소한의 응급조치로서 이용할 수 있는지 여부에 대해 매우 심각한 검토를 했지만, 당시 상황에서 소프트포크로부터 발생될 수 있는 DoS 공격벡터때문에 이를 선택할 수 없었습니다. 이더리움의 소프트포크 진영이라고 따로 존재했던 것도 아니고, ETC가 소프트포크 지지자도 물론 아니었습니다.
http://hackingdistributed.com/2016/06/28/ethereum-soft-fork-dos-vector/

답글 감사합니다. 아톰님의 말씀 듣고 굳이 이 논의를 진영 간의 대립으로 나눌 필요는 없을 것 같아 결론 부분을 조금 고쳤습니다. 진영 간의 대립이라기보다는 이더리움을 복구하기 위한 방안의 의견 차이가 있었다는 점이 적절하겠습니다.

Coin Marketplace

STEEM 0.27
TRX 0.13
JST 0.032
BTC 60895.62
ETH 2917.92
USDT 1.00
SBD 3.58