이번 글은 모든 개발자가 알아두면 좋은 보안 이야기입니다. 우리는 CVE를 통해 취약점의 내용, 취약한 소프트웨어, 심각도를 알 수 있어요. CVE를 특정 키워드로 구독해 서비스를 안전하게 관리하는 방법을 알아봅시다!


취약점과 익스플로잇

가장 먼저 알아두면 좋은 개념은 취약점익스플로잇(exploit)입니다. 취약하다는 것과 익스플로잇 가능하다는 말은 굉장히 큰 차이가 존재하기 때문에 둘 사이에 어떤 차이가 존재하는지 알아보도록 하겠습니다.

먼저 취약점은 임의의 공격자가 허락받지 않은 기능을 수행할 수 있게 하는 프로그램상의 결점 혹은 약점을 의미합니다. 그에 반해 익스플로잇은 취약점 위협을 통해 허락받지 않은 기능을 실제로 수행하는 것을 의미합니다. 즉, 다음과 같은 관계가 성립합니다.

취약점과 익스플로잇의 관계
취약점과 익스플로잇의 관계

예를 들어, 공격자는 소프트웨어의 취약점을 바탕으로 허락받지 않은 기능을 수행하는 익스플로잇을 통해 접근 권한을 탈취하거나, 서비스 거부 공격(DoS) 등을 발생시키게 됩니다.

취약점의 주민등록번호 CVE

한국에서는 개개인의 신분을 명확하게 구분하기 위해 주민등록번호 제도를 사용하고 있습니다. 이는 대규모의 행정 업무를 용이하게 할 뿐 아니라, 범죄나 혹은 사고 피해자의 신상 파악에 그 역할을 다하고 있습니다. 이처럼 취약점에도 주민등록번호 역할을 하는 것이 있는데요, 바로 CVE입니다.

CVE는 Common Vulnerabilities and Exposure의 약자로, “공개적으로 알려진 정보보안 취약점 혹은 위험 노출에 대한 정보”를 의미합니다. CVE가 도입되기 이전에는 국가 혹은 기관 및 업체마다 취약점을 관리하는 고유의 체계가 존재해 일관성이 없어 혼란이 야기되는 일이 빈번하였습니다.

이에 따라 미국 비영리 회사 MITRE 사에서 발견된 소프트웨어상의 취약점을 효과적이고 체계적으로 관리하기 위한 목적으로 CVE를 고안하였습니다. CVE는 이후에 미국 국립표준기술연구소(NIST)가 운영하는 국가 취약성 데이터베이스(National Vulnerability Database)에 자료를 제공하면서 현재까지도 유용하게 사용되고 있습니다.

CVE는 익스플로잇 가능한 취약점을 제보할 경우 각각의 고유한 식별 번호를 발급하고 이를 보안 전문가들이 분석합니다. 만약 승인이 되면 CVE에 해당 취약점이 추가됩니다. 각각의 CVE 엔트리에는 상세 페이지가 있고, 해당 페이지에서 취약점에 대한 설명, 심각도, 레퍼런스 등에 대해 자세히 확인할 수 있습니다. CVE 식별 번호는 아래의 규칙에 따라서 할당됩니다.

CVE 식별 번호의 규칙
CVE 식별 번호의 규칙

실제 CVE 정보는 아래의 사이트에서 검색하고 확인할 수 있습니다.

batchOverflow 취약점으로 알아보는 CVE

유명한 스마트 컨트랙트 취약점 batchOverflow을 기준으로 예를 들어보겠습니다. 위의 링크에서 batchOverflow라는 키워드로 검색을 하면 CVE-2018–10299라는 취약점이 결과로 주어집니다. 해당 취약점 페이지에 접속하면 다음과 같은 화면을 확인할 수 있습니다.

batchOverflow로 알려져있는 CVE-2018–10299 취약점
batchOverflow로 알려져있는 CVE-2018–10299 취약점

사람마다 batchOverflow, BatchOverflow, integer overflow 등 다양하게 부를 수 있는 취약점을 CVE 체계에 따라 분류를 한 덕분에 CVE-2018–10299라고 지칭할 수 있게 되었습니다.

또한, Current Description 섹션을 통해 취약점 내용과 Impact 섹션을 통해 심각도 수준을 알 수 있습니다. 이때 심각도는 OWASP의 위험 등급 방법론을 토대로, 발생 가능성(Likelihood)과 영향을 끼치는 정도(Impact)의 곱으로 계산됩니다.

OWASP의 위험 등급 방법론
OWASP의 위험 등급 방법론

자세히 알아보는 CVE-2018–10299

CVE에 대해 배웠으니 앞서 예로 든 취약점을 더 자세히 알아보도록 하겠습니다. batchOverflow라고도 불리는 이 취약점은, 이더리움 프로그래밍 언어 중 하나인 솔리디티로 작성된 스마트 컨트랙트에서 발견되었습니다. 보다 구체적으로는 ERC-20 토큰 컨트랙트에서 다수의 지갑에 지정된 개수만큼의 토큰을 전송하기 위해 구현한 batchTransfer 함수에서 발견되었습니다.

오버 플로우 현상처럼 플립 카운터도 9을 초과하면 0이 된다
오버 플로우 현상처럼 플립 카운터도 9을 초과하면 0이 된다

batchTransfer 함수를 호출하는 유저는 코인 개수를 직접 지정할 수 있는데 그 값에 따라, 오버플로우 현상이 발생하면서 엄청나게 많은 수의 토큰을 전송받을 수 있게 되었습니다. 보유한 토큰보다 많은 수의 토큰을 전송하는 것을 막기 위한 조건문이 있었지만, 오버플로우가 발생하면서 조건문을 만족하게 되었기 때문입니다. 해당 취약점의 심각도 수준은 7.5로 높은 편으로, 실제로 많은 거래소들이 ERC-20 토큰에 대한 대대적인 검사를 위해 ERC-20 토큰에 대한 거래를 정지하기도 했습니다.

ERC-20 토큰에 대한 거래를 일시 정지한 Poloniex
ERC-20 토큰에 대한 거래를 일시 정지한 Poloniex

따라서 스마트 컨트랙트에서 연산할 때 오버플로우 혹은 언더플로우가 발생할지 계속 주의 깊게 살펴야 합니다. 혹은 Open Zeppelin 사에서 운영하는 오픈소스 openzeppelin-sollidity의 SafeMath를 이용하는 것도 방법입니다. 하지만 모든 연산에 대해서 SafeMath를 썼는지에 대한 검토를 또 해야 하기 때문에 취약점 검증 과정을 전문으로 하는 회사에 코드 감사를 맡기는 것을 추천드립니다.


Audit 시리즈 모아보기
취약점에도 주민등록번호가 있다고요?
익스플로잇 개발 (z3-solver)
Anatomy of Uniswap Front-running Bot