이더리움 스마트 컨트랙트 보안 취약점

김세진
EOS Chrome
Published in
7 min readOct 3, 2018

블록체인에 대해 공부하고 글로 남기려고 합니다

첫 주제는 이더리움 스마트 컨트랙트의 보안 취약점 입니다

“분산 어플리케이션 제작을 위한 대체 프로토콜을 만드는 것” 이다

여기서 나타난 비트코인과 다른점은 “스마트 컨트랙트” 라고 생각한다

개발자가 직접 계약 조건과 내용을 코딩할 수 있기 때문에,

원칙적으로 인간이 상상할 수 있는 모든 종류의 계약을 이더리움 플랫폼을

https://www.youtube.com/watch?v=KMaURu9FC-U (코인사이트)

DASP(Decentralized Application Security Project ) 에 들어가면

먼저 살펴 볼 문제는 Reentrancy 문제다

어떻게 재진입을 하냐면 재귀를 이용해서 재진입을 한다!

예를들어 이런 코드가 있다고 하자

돈을 인출하는 함수다

처음에 require를 이용해 (나의 잔고 >= 인출하려는 돈) 인지 확인한다

그리고 나에게 인출하려는 돈 amount만큼을 주고

나의 잔고에서 amount만큼을 뺀다

별 문제 없어보인다

하지만 여기서 msg.sender이 contract 라면 문제가 생긴다

이더리움에서는 contract가 또다시 contract를 호출하는 것이 가능하다

근데 contract가 호출한다면 fallback 함수를 호출하게 된다

fallback 함수 란

출처 : https://www.bitdegree.org/learn/solidity-fallback-functions/

라고 적혀 있습니다

이름이 없고, 매칭되는 함수가 없을 때 실행 됩니다

본론으로 돌아와서

이 fallback함수가 실행 되었을 때

다시 fallback함수에서 withdraw 함수를 호출하면 어떤 일이 일어날까요?

다시 또 나는 돈을 받고 fallback 함수로 빠집니다

그리고 또 withdraw를 호출하고…

계속 반복되는 일이 일어납니다

이러한 코드가 있다면 attack 함수를 실행 시켰을 때

30번이나 withdraw를 호출해서 돈을 30배 더 받을 것 입니다

근데 이런일이 일어날 수 있을까요?

있습니다!!

사실 이 문제는 가장 유명한 DAO 사건 입니다

DAO에서 이런 일이 일어나서 엄청난 손실을 얻고

결국 하드포크를 통해 이더리움 클래식이 탄생한 것 입니다

공부하면서 보면 정말 사소한 실수 같은데

이런 사소한 실수도 나중에 큰 손해를 불러올 수 있다는 것을

항상 기억해야 할 것 같습니다

2. Access Control

두 번째는 Access Control 입니다

이것도 말 그대로 접근권한에 대한 문제 입니다

이러한 코드가 있다고 합시다

contract의 owner를 호출한 사람으로 바꾸는 함수 입니다

근데 이런 함수를 public 으로 설정한다면 무슨 일이 일어날까요?

아마 외부에서 다른 사람이 접근해서 owner가 될 것 입니다!

실제로 parity 멀티 시그 버그라는 유명한 사건 입니다

delegatecall을 이용해 walletLibary에 있는 initowner로 들어가

owner를 초기화 시킨 것 입니다

이 일로 인해 큰 손해를 보았습니다

그리고 public을 internal 로 바꾸고

owner가 초기화 되어있지 않을 때만 접근하게 만들어서

오류를 해결했습니다

3. Arithmetic Issues

세 번째 주제는 Arithmetic Issues 입니다

이건 코딩을 하다보면 자주하는 실수 입니다

수가 범위를 넘어갔을 때

underflow && overflow가 생기는 문제 입니다

예를 들어 이런 코드가 있다고 합시다

여기서 msg.sender — amount > 0 이라는 코드가 있습니다

만약 sender가 10원 / amount 가 20원 이라면 어떤 결과가 나올까요 ?

자료형을 보시면 uint 입니다

uint는 양수만 표현현하기 때문에

-10 > 0 이 아닌

엄청나게 큰 양수 > 0 이 되어버릴 것 입니다

결국 require 문을 통과하게 됩니다

false가 나와야 할 곳이 true가 나오게 되는 것 입니다!

이런 일이 발생하지 않으려면 꼼꼼하게 검사하는 습관이 필요할 것 같습니다

4. Denial of Service

네 번째는 DOS 입니다

비트코인에서는 무한루프에 빠질 가능성이 있어서

while문이나 for문을 사용하지 못했습니다

하지만 이더리움에서는 사용 가능합니다

대신 gas라는 수수료 정책을 이용해 무한루프에 빠지지 않게 만들어 줍니다

이러한 gas에는 gas limit 가 있어서 gas limit를 넘어가면

사용할 수 없는 계약이 되어 버립니다

이러한 점을 이용한 취약점도 존재합니다!

위와 같은 코드가 있을 때

for문의 크기만 큼 gas를 책정 하게 됩니다

그럼 악의적인 사용자가 for문의 크기를 계속 늘리는 겁니다

그럼 gas의 크기는 증가하고 어느 순간 gaslimit를 초과할 것 입니다

결국 사용할 수 없는 contract가 되어버릴 것 입니다

약간 네트워크 시간에 배우는 DOS 공격이랑 개념이 비슷한 것 같습니다

5. Front-Running

마지막으로 다섯번째는 Front-Running 입니다

유투브 코인사이트를 통해 공부하며 이해가 잘 되었던 내용 입니다

블록체인의 특성상 블록에 올라가기 전 트랜잭션을은 모두가 알 수 있습니다

그리고 블록에 올라가는 순서는 miner가 정합니다

위와 같이 어떠한 문제가 있고

그 문제를 빨리 푸는 사람에게 ETH를 준다고 가정합시다

이 때 밥이 그 문제를 풀었습니다

그리고 블록에 올리기 위해 보냈습니다

근데 엘리스가 그 답을 보고 더 많을 가스를 주며 보낸다면

miner는 가스가 더 큰 엘리스를 선택 할 것 입니다

* 가스가 높을수록 채굴자에게 떨어지는 수수료가 많습니다

이러한 문제를 Front-Running 이라고 합니다

블록체인의 특성을 이용해 일어나는 문제이므로

가장 해결하기 힘들수도 있다는 생각이 듭니다

이렇게 총 5가지의 보안 취약점에 대해 알아봤습니다

사소한 코딩 실수 때문에 발생하는 문제도 있고

블록체인의 특성 때문에 발생하는 문제도 있습니다

앞으로는 이런 취약점들을 잘 보완했으면 좋겠습니다

이상으로 첫 번째 주제를 여기사 마치겠습니다!

저도 공부를 하며 배운 내용이라 틀린 내용이 있을 수 있습니다

댓글로 알려주시면 감사하겠습니다!

Originally published at sejinik.tistory.com on October 3, 2018.

--

--