소프트웨어의 약점(weakness)과 CWE에 대한 설명글
과제를 하다가 샛길로 새어버렸고 어쩌다 소프트웨어의 취약점에 대해서 공부를 하게 됐다.
여기저기 찍먹을 하다보니 CWE까지 가게 되어서 이에 대해 정리를 해보려고 한다.
용어 정리
CWE(Common Weakness Enumeration)를 설명하려면 취약점과 약점에 대해서 간략하게 정리해야한다.
•
자산(Asset)
데이터, 디바이스, 조직의 시스템의 기타 구성 요소들을 말한다.
서버, 네트워크와 같은 인프라, 소프트웨어, 컴퓨터, 데이터(정보) 등이 모두 자산에 해당한다.
•
위협(Threat)
자산에 부정적인 영향을 줄 수 있는 모든 사건을 말한다.
흔히 말하는 ‘해킹’과 같이 악의적인 공격 행위 또한 위협(threat)에 해당하고
자연 재해로 물리적인 피해를 받는 것도, 직원의 실수도, 내부자가 내부 정보를 무단으로 사용하는 것 또한 위협에 해당한다.
•
취약점/취약성(Vulnerability)
자산(asset)을 파괴하거나 손상시키는 부정적인 행위가 위협(threat)이라고 했는데,
이 위협에 악용(exploit)될 수 있는 결함을 취약점(vulnerability)이라고 한다.
쉽게 말해서 해킹이 성공하려면 취약한 부위를 공격 해야하는데 이 취약한 부위가 취약점이 된다.
위협(threat)은 취약점(vulnerability)을 이용해서 발생할 수 있다.
•
약점(결함, weakness)
CWE의 공식 문서에 따르면 약점은 취약점으로 이어질 수 있는 오류를 말한다.
•
소프트웨어 취약점(Vulnerability)
◦
CVE 리스트에 나열되어 있는 소프트웨어 취약점(vulnerability)
◦
해커가 시스템, 네트워크에 접근(access)하기 위해서 직접적으로 사용할 수 있는 소프트웨어의 실수(mistake)이다.
•
소프트웨어 약점(Weakness)
◦
소프트웨어와 하드웨어의 디자인, 설계, 코드 구현에서 발생할 수 있는 결함(flaw), 결점(fault), 버그(bug), 에러(error)를 의미한다.
◦
만약 이것을 해결하지 않고 남겨두면 시스템, 네트워크, 하드웨어가 공격에 취약해질 수도(vulnerable) 있다.
모든 취약점(vulnerability)은 약점(weakness)에 의존하지만 모든 약점(weakness)이 반드시 취약점(vulnerability)을 수반하는 것은 아니다.
소프트웨어 기준으로 약점(weakness)의 예시를 들어보자면 다음과 같다.
•
버퍼 오버플로우, 인증 에러(authentication errors), 불충분한 데이터 검증(insufficient verification of data) 등
CWE(Common Weakness Enumeration)
일반적인 소프트웨어와 하드웨어의 보안 약점(weakness)을 나열한 공식적인 리스트(혹은 사전)를 말한다.
미국 국토안보부(DHS)와 CISA에서 후원하고, MITRE에서 운영하는 국토안보 시스템 엔지니어링 및 개발 연구소(HSSEDI)에서 이 리스트를 관리하고 있다.
앞에서 정리했던 것과 같이 약점(weakness)은 설계, 디자인, 코드(코딩), 구현 단계에서 발생할 수 있으며 악용 가능한 취약점(vulnerability)으로 이어질 수 있다.
참고로 CWE의 주요 목표(main goal)는 “제품이 배포되거나 사용자에게 제공되기 전 설계, 디자인, 코드 작성 등의 개발 과정에서 엔지니어로부터 흔히 발생하는 일반적인 실수나 오류를 제거하는 방법을 교육하여 소스 코드 상의 취약점을 사전에 방지하는 것"이라고 한다.
내용 출처 : 한컴인텔리전스
CWE List Version 4.7
2022.05.25 기준으로 가장 최신 버전의 리스트는 4.7이다.
CWE는 각 약점들에 대해서 번호를 부여하여 관리한다.
또한 여러 약점을 분류하고 묶어서 카테고리화한 후 ID를 부여하여 목록으로 제공하고 있다.
몇 가지를 예를 들어보자면 다음과 같이 그룹화되어 있으며, 이 중 필요로 하는 카테고리만을 찾아볼 수 있다.
•
C로 작성된 소프트웨어 약점 : VIEW ID 658
•
C++로 작성된 소프트웨어 약점 : VIEW ID 659
•
Java로 작성된 소프트웨어 약점 : VIEW ID 660
•
모바일 애플리케이션의 약점 : VIEW ID 919
•
소프트웨어 개발 관련 약점 : VIEW ID 699
◦
API / 함수 에러 : Category ID 1228
◦
인증 에러 : Category ID 1211
◦
잘못된 코딩 습관 : Category ID 1006
◦
키 관리 에러 : Category ID 320
◦
기타 등등
•
하드웨어 디자인 관련 약점 : VIEW ID 1194
◦
core 및 compute 이슈 : Category ID 1201
◦
메모리 및 스토리지 이슈 : Category ID 1202
◦
기타 등등
예시) CWE-14 : Compiler Removal of Code to Clear Buffers
어떤 내용들이 있는지 알아보기 위해서 C로 작성된 소프트웨어의 결함(Weaknesses in Software Written in C)에 있는 약점들 중 가장 앞에 있는 자료를 하나 가져왔다.
해당 약점의 고유한 번호는 CWE-14이며, name은 “Compiler Removal of Code to Clear Buffers”이다.
※ 글 작성의 편의를 위해 본 약점(weakness)을 CWE-14로 표현하겠습니다.
CWE-14에 대한 페이지를 보면 가장 먼저 약점(weakness)에 대한 설명과 부가적인 설명들(적용 가능한 플랫폼이나 약점으로 인해 발생할 수 있는 영향 등)이 상세하게 적혀있다.
CWE-14는 컴파일러 최적화(optimization) 시 발생하는 deat store를 주의해야한다는 내용이다.
일반적으로 암호(password)나 암호화 키와 같은 중요 데이터를 노출하지 않기 위해서 메모리에서 조작되는 민감한 데이터는 덮어쓰기를 한다.
하지만 컴파일러의 최적화로 인해 덮어쓰기가 제대로 되지 않는 경우가 있다.
빠른 이해를 돕기 위해서 간단한 예시를 가져왔다.
#include <unistd.h>
#include <string.h>
int main(void)
{
char pwd[10];
char cryto_pwd[16] = "world";
read(0, pwd, sizeof(char) * 10);
strcat(cryto_pwd, pwd);
write(1, cryto_pwd, sizeof(char) * 16);
memset(pwd, 0, sizeof(char) * 10); // **이 부분**
memset(cryto_pwd, 0, sizeof(char) * 16); // **이 부분**
return (0);
}
C
복사
•
컴파일 시 -O3으로 최적화했으며, 오브젝트 파일을 좀 더 보기 쉽게 하기 위해 -g 옵션을 주었다.
gcc -g -O3 -c test.c -o test.o
C
복사
•
오브젝트 파일을 읽을 때는 objdump 명령어를 이용했다.
objdump -S test.o
C
복사
위의 결과에서도 볼 수 있듯이 memset 함수가 호출되지 않는다.
이는 변수 pwd와 cryto_pwd의 공간이 memset()으로 값이 덮여진 이후에 사용되지 않기 때문이다.
최적화 컴파일러는 memset에 대한 호출을 데드 코드(dead code)로 해석하고 제거한다.
때문에 두 변수는 데드 스토어(dead store)가 된다.
CWE-14의 페이지에는 이러한 데드 스토어가 발생할 수 있는 예시(example)와 어떻게 악용할 수 있는지에 대하여 상세하게 설명한다.
예시를 보여준 후 CWE-14를 완화할 수 있는 방법에 대해서 간략하게 설명해준다.
구현, 빌드 및 컴파일, 아키텍처 및 디자인 단계에서 CWE-14를 완화할 수 있는 방법은 다음과 같다.
•
구현 단계 : 가능한 한 민감한 데이터를 휘발성 메모리에 저장한다.
•
빌드 및 컴파일 단계 : 가능한 한 컴파일러가 dead store를 제거하지 않도록 구성한다.
•
아키텍처 및 디자인 단계 : 가능한 한 소프트웨어 시스템에서 사용하는 민감한 데이터를 암호화한다.
이 외에도 이 약점으로 인해 영향을 받는 리소스, 악용(exploit) 가능성, 본 약점과 관련된 CVE 등을 확인할 수 있다.
참고
소스코드 취약점 진단이나 시큐어코딩 가이드를 만들 때, CWE를 참조한다고 합니다.
시큐어코딩의 중요성을 이해하고, 지향하고 있다면 CWE를 가볍게 한번 훑어보는 것도 좋을 것 같습니다.
또한 CWE의 목록을 보면 알 수 있듯이 과제를 하면서 한번쯤 접하게 되는 내용들이 많이 나와 있습니다.
예를 들어, Weaknesses in Software Written in C에는 과제를 하면서 자주 언급됐던 다음과 같은 약점(weakness)들이 있습니다.
•
Stack-based Buffer Overflow
•
Heap-based Buffer Overflow
•
Unexpected Sign Extension
•
Double Free와 Use After Free
•
Use of Uninitialized Variable
•
NULL Pointer Dereference
•
Out-of-bounds Write
영향력이나 조치방안(완화방안) 등을 정리할 겸 가벼운 마음으로 훑어보는 것도 괜찮을 것 같습니다.