스마트 컨트랙트란?
스마트 컨트랙트란 블록체인 네트워크에서 계약의 내용과 실행 조건을 컴퓨터 코드를 통해 사전에 설정한 후 해당 조건이 충족되면 자동적으로 계약을 집행하는 기능을 의미합니다. 현대 사회에서는 거래하는 상대방과의 신뢰를 위하여 구매자와 판매자, 그리고 중개인이 관여하여 거래를 진행합니다. 여기에서 스마트 컨트랙트의 장점을 파악할 수 있습니다. 구매자와 판매자는 중개인을 고용함과 동시에 거래가 성사되면 중개인에게 수수료를 지불해야 합니다. 하지만, 스마트 컨트랙트를 이용하면 계약의 내용과 실행 조건을 만족해야만 계약이 진행되기 때문에 상대방을 신뢰하지 않아도 안전한 거래가 가능해 집니다[1]. 따라서, 중개인을 고용하지 않아도 되고 수수료 지출 또한 사라지게 되는 것이죠.
스마트 컨트랙트의 취약점
스마트 컨트랙트에는 많은 장점이 있지만, 해결해야할 단점들이 존재합니다. 스마트 컨트랙트를 구성하고 있는 코드는 완벽하고 버그가 없어야 합니다. 그렇지 않으면 실수를 야기할 수 있으며, 때때로 악용될 수 있습니다. 스마트 컨트랙트 취약점의 예로 이더리움의 Re-Entrancy 공격이 있습니다[2]. Re-Entrancy 공격은 외부 공격자가 취약한 상태 변수 업데이트 패턴을 가진 함수를 호출하고, fallback 메커니즘[3]을 통해 다시 해당 함수로 재진입을 하는 것입니다. 이러한 취약점을 이용해 2016년에 the DAO 해킹 사건이 발생하게 됩니다[4]. DAO는 이더와 DAO 토큰을 거래할 수 있는데, 해커는 이 코드에서 논리적인 코딩 결함을 발견하였고, 이더를 환불신청 했을때 이더를 먼저 받고, 자신의 DAO 토큰을 돌려주기 전에 다시 이더를 환불받는 재귀 call 코드를 만들어 일종의 무한 환불 공격을 만들어 냈습니다. 이 사건으로 손실된 이더는 360만 이더로 추정되고 있으며 당시 물가로 5000만 달러로 추정됩니다[5]. 이처럼 잘못된 코드가 있는 스마트 계정에 돈을 넣을 경우 도난 당할 가능성이 있습니다.
최신 스마트 컨트랙트 퍼징 도구 Smartian
스마트 컨트랙트에는 기존 소프트웨어와 달리 일련의 트랜잭션이 상태 변수들을 공유하는 고유한 특징이 있습니다. 이러한 특성으로 인해 기존 퍼징 도구는 중요한 트랜잭션 시퀀스를 찾기가 어렵습니다. 최근에 소프트웨어 분야 탑 컨퍼런스인 Automated Softwar Engineering에 발표된 Smartian은 이 문제를 해결하기 위해 정적 및 동적 분석을 모두 사용하여 퍼징의 효율성을 향상시킵니다[6,7]. Smartian을 사용하면 소스 코드 없이도 실제 스마트 컨트랙트의 버그를 발견할 수 있습니다. 또한, 이는 CVE를 찾는 기존의 최첨단 도구보다 더 효과적입니다. 본 포스팅에서는 Smartian의 설치 및 사용 방법에 대하여 설명하겠습니다.
Smartian 설치
저번 포스팅(최신 윈도우 커널 퍼저, NTFUZZ 사용후기)에서 설치하였던 WSL을 이용합니다. WSL의 Ubuntu 버전은 18.04를 사용합니다. WSL 실행 후, 원하는 디렉토리 위치에서 아래 명령어를 사용하여 Smartian의 소스파일을 다운로드 하고, make를 생성합니다. Smartian은 F#으로 작성되었으므로 Smartian을 실행하기 전에 .NET 5.0을 설치해야 합니다. 설치 방법은 지난 포스팅을 따라서 하시거나, 다음 링크를 따라 하시면 됩니다. https://docs.microsoft.com/en-us/dotnet/core/install/
$ git clone https://github.com/SoftSec-KAIST/Smartian
$ cd Smartian
$ git submodule update –init –recursive
$ make



이렇게 Smartian 설치를 완료할 수 있습니다.
Smartian 사용
Smartian은 EVM 바이트코드와 ABI 사양을 입력하여, 스마트 컨트랙트를 퍼징할 수 있습니다.
명령어는 아래와 같습니다.
$ dotnet build/Smartian.dll fuzz -p <bytecode file> -a <abi file> -t <time limit> -o <output dir>
Smartian examples 폴더 안에는 AF, AW, BD, CH, RE 등의 bytecode file과 abi file을 제공합니다. AF, AW, BD, CH, RE 등은 버그를 일으키는 명칭의 약자입니다. 예를 들어, 포스팅 처음에 언급했던 Re-Entrancy 공격은 약자로 RE라고 명명됩니다. 해당 명령어에서 -p <bytecode file>은 EVM 바이트 코드를 의미하고, -a <abi file>는 abi 사양을 의미합니다. 그리고, -t <time limit>는 퍼저 실행 시간을 의미합니다. 마지막으로, -o <output dir>은 퍼저 실행 결과물을 입력해준 디렉토리에 저장하는 기능을 수행합니다. 본 포스팅에서는 스마트 컨트랙트에서 발견되는 유명한 버그인 Re-Entrancy를 사용합니다. 해당 버그의 bytecode file과 abi file을 이용합니다. 그리고, time limit는 10초, output dir은 testRE라고 입력해주었습니다.
그림 4는 git clone한 Smartian 폴더입니다.





그림 5~8을 보면, Smartian은 정적 분석을 통해 컨트랙트에서 일어나는 데이터 흐름을 파악하는 것을 확인할 수 있고, 이 정보를 활용하여 퍼징을 시행하고 오류를 찾아 버그 시드에 저장하는 것을 확인할 수 있습니다. 그리고 지정해준 시간을 경과하게 되면 Fuzzing timeout expired 되어 Fuzzing이 종료되고 결과를 출력합니다. 여기에서는 디버깅과 Fuzzing을 통해 얻은 정보들을 한번에 출력합니다. 출력되는 결과 중에서 Total Executions는 퍼징 과정에서 타겟 프로그램(컨트랙트)를 실행한 총 횟수이고, Deployment failures는 프로그램을 실행하려고 할 때 초기화(deploy)에 실패한 횟수 입니다. 만약 이 수치가 비정상적으로 높다면, 컨트랙트를 아예 실행하지 못한 것을 짐작할 수 있습니다. 그리고, Test Cases는 생성한 총 테스트 케이스의 개수를 의미합니다. 이 밖에도 Covered Edges와 Covered Instructions을 출력합니다. 이는 각각 edge coverage, instruction coverage를 의미하고 이것을 통하여 coverage achievement를 측정할 수 있습니다. 마지막으로 가장 중요한 버그의 종류를 찾아낼 수 있습니다. 이 실행에서는 Smartian에서 제공한 examples를 사용했으므로 RE(Re-Entrancy) 버그를 찾아낸 것을 확인할 수 있습니다.


Smartian을 실행하면 입력해주었던 testRE라는 폴더가 생성되고, 그 안에는 bug 폴더와 testcase 폴더가 생성됩니다. bug 폴더 안에는 버그를 유발한 입력이 포함되어 있고, testcase 폴더에는 퍼징 동안 Edge coverage를 증가시키는 입력을 포함하고 있습니다.
글을 마치며
현재 보안의 중요성은 해가 거듭하면서 중요해지고 있습니다. 특히 현재 각광받는 기술인 블록체인에서 사용되는 스마트 컨트랙트는 하나의 버그가 엄청난 손실을 가져오기 때문에 더욱 중요합니다. 2021년 한해에만 스마트 컨트랙트 취약점은 이더리움 네트워크에서만 3만 4천개 이상이 발견되었습니다. 스마트 컨트랙트는 일반적으로 패치가 불가능하고, 모두 같은 실행 환경을 가지고 있기 때문에 취약점이 남아있다면 계속해서 해킹 당할 가능성이 있습니다. 이에 따라 취약점을 찾아내는 스마트 컨트랙트 퍼저들이 개발되고 있는 상황입니다. 본 포스팅에서는 Automated Software Engineering 컨퍼런스에서 발표된 Smartian을 설치 및 사용해 보았습니다. Smartian은 다른 스마트 컨트랙트 퍼저와 달리 소스 코드 없이, 바이트 코드만을 이용하여 스마트 컨트랙트의 버그를 발견할 수 있습니다. 아래의 그림은 유명한 스마트 컨트랙트 버그를 찾아내는 도구들과 Smartian의 비교 분석표입니다.

그림을 보면, 실제 스마트 컨트랙트에서 알려진 CVE를 찾는데 기존의 최첨단 도구보다 더 효과적임을 알 수 있습니다. Smartian은 스마트 컨트랙트에서 발견되는 유명한 버그 종류인 Re-Entrancy (RE), Integer Overflow (IO), Ether Leak (EL) 등을 전부 찾아낼 수 있습니다. Smartian을 사용하여 the DAO 해킹 사건과 같은 블록체인 스마트 컨트랙트 해킹 사고를 미리 방지하여 보안을 강화합시다.
참고문헌
[1] https://kr.cointelegraph.com/ethereum-for-beginners/what-are-smart-contracts-a-beginners-guide
-to-automated-agreements
[2] https://dasp.co/#item-1
[3] https://docs.soliditylang.org/en/v0.8.12/contracts.html#fallback-function
[4] https://kr.cointelegraph.com/ethereum-for-beginners/what-is-a-decentralized-autonomous-organization-and-how-does-a-dao-work
[5] https://www.wired.com/2016/06/50-million-hack-just-showed-dao-human/
[6] Jaeseung Choi, Doyeon Kim, Soomin Kim, Gustavo Grieco, Alex Groce, and Sang Kil Cha., “SMARTIAN: Enhancing Smart Contract Fuzzing with Static and Dynamic Data-Flow Analyses”, Automated Software Engineering (ASE) 2021
[7] https://github.com/SoftSec-KAIST/Smartian
[8] https://github.com/SoftSec-KAIST/Smartian-Artifact
[9] https://ndb796.tistory.com/522

KAIST 사이버보안연구센터 바이너리분석 팀원으로 강력한 타입 시스템과 직관적인 프로그래밍이 가능한 F#을 이용하여 Parser 개발 및 다양한 연구를 수행하고 있다.