Invisible Safety,

Proven by Intelligence

보이지 않는 안전을 인텔리전스로 증명하다.

기술 노트
IT 산업의 변화를 이끄는 MDS인텔리전스의
기술 인사이트를 만나보세요.
시스템 소프트웨어 개발
[CodeSonar] CWE - 658/659 정복하기 (6)
2026년 01월 12일

CWE - 658/659 정복하기 (6)


l CWE-195: Signed to Unsigned Conversion Error


CWE-195는 singed 자료형에서 unsigned 자료형으로 캐스팅 수행하는 것에 대한 위험을 명시하고 있습니다. Singed와 Unsigned 값의 암시적인 캐스팅은 의도하지 않은 값을 생성하여 예상하지 못한 프로그램 실행을 유발합니다. 일반적인 예로 많은 개발자들이 함수의 실행이 실패하면 음수인 ‘-1’을 리턴하도록 코드를 작성합니다. 그러나 함수 실행 실패로 저장된 음수 값이 이후 코드에서 사이즈 인자로 사용된다면 예상하지 못한 프로그램의 실행과 결과를 초래합니다. 메모리를 복사하거나 할당하는 스탠다드 라이브러리 함수의 사이즈 인자에 음수 값이 사용되면 이 값은 형 변환이 발생하여 매우 큰 unsigned 값으로 변경되어 오버 플로우나 언더 플로우(Overflow, Underflow)가 발생하게 됩니다. 이처럼 서로 다른 부호의 값 사이의 형 변환은 데이터 무결성, 가용성, 보안성 등 다양한 문제의 원인이 됩니다.


​아래 예시 코드를 보면 변수 amount는 리턴될 때, 음수 값을 보유하고 있을 수 있습니다. 그러나 readdata() 함수가 unsinged int 타입으로 반환하도록 선언되어 있어 amount 값은 암시적으로 unsigned 값으로 변환됩니다. 예를 들어 에러 조건에 만족하여 참으로 조건 구문이 실행될 경우 변수 amount는 음수인 '-1'이 저장된 후 리턴이 수행되지만, 실제 32 bit int 형 시스템에서는 unsigned int 타입으로 변환되며 4,294,967,295 인 의도하지 않은 매우 큰 값이 리턴됩니다.



아래 또 다른 예제는 소켓으로부터 입력된 패킷 내 저장된 헤더의 정보를 읽어오는 코드입니다. 패킷 내 헤더의 개수를 변수 numHeaders에 저장한 뒤, 최대 100개를 넘지 않도록 조건 구문을 통해 검사하고 있습니다. 그러나 변수 numHeaders는 signed int 타입으로 정의되어져 있어 입력된 패킷의 값이 음수일 경우, 메모리 할당 함수인 malloc의 사이즈 인자가 음수로 입력되고 사이즈 인자의 size_t 형으로 형 변환 및 값의 변경이 발생합니다. 이로 인해 음수였던 사이즈 인자 값은 매우 큰 값으로 변경되고 malloc 함수의 실패 또는 매우 큰 사이즈의 메모리가 할당되어 오버 플로우가 발생할 수 있습니다.



위 예시와 같은 문제들은 변수에 저장된 값을 사용하기 전 최대 및 최소 값에 대한 범위를 검사하는 조건 구문을 추가하는 방어 코드를 작성하거나, 함수의 반환형과 실제 리턴되는 값이 동일한 타입으로 수행될 수 있도록 유의하여 코드를 작성하는 것이 좋습니다.


l CWE-196: Unsigned to Signed Conversion Error


CWE-196은 CWE-195와 반대로 Unsigned 자료형에서 Singed 자료형으로 캐스팅되는 것에 대한 위험을 명시하고 있습니다. 이 또한 의도하지 않은 값을 생성하여 예상하지 못한 프로그램 실행을 유발합니다. Signed에서 Unsigned 타입으로 변환되는 문제보다 적은 빈도로 발생하지만 이 문제는 공격자로부터 Buffer Underwrite를 발생시키도록 하는 가장 흔한 공격 방식입니다.  예를 들어, 캐스팅된 이후의 값이 배열의 인덱스 또는 포인터 산술 시 사용되는 경우에는 Buffer Underwrite 가 주로 발생합니다.


​CWE-195 와 같이 변수에 저장된 값 사용 전 최대 및 최소 값에 대한 범위를 항상 확인한 뒤 참조할 수 있는 방어 코드를 작성하고, 함수의 반환형과 실제 리턴되는 값이 동일한 타입으로 수행되는지 별도의 검사를 수행해야 합니다.


l CWE-197: Numeric Truncation Error


CWE-197은 작은 사이즈의 자료형으로 캐스팅되어 데이터가 절단되는 현상에 대한 문제를 명시하고 있습니다. 작은 사이즈로 캐스팅이 수행되면 상위 비트가 손실되면서 본래의 값과는 다른 예상하지 못한 값으로 변환될 수 있습니다. 또한 이 값이 버퍼의 인덱스로 사용되거나 반복문의 iterator 또는 상태를 나타내는 자료로 사용되는 경우 신뢰할 수 없는 값으로 프로그램을 실행시켜 불안전한 시스템 상태를 만들 수 있습니다.




위 예시 코드는 데이터 절단으로 인해 값이 변경될 수 있음을 보여주고 있습니다. Int 형에서 short 형으로 데이터 저장 시 절단이 발생하여 의도하지 않은 값이 저장되었으며, 예시 코드의 출력은 다음과 같습니다. 만약 이 의도하지 않은 값이 배열의 인덱스로 사용된다면 공격자로부터 악용될 가능성이 매우 높습니다.



데이터 절단 문제는 가능한 암시적/명시적 모든 형변환을 금지하고 저장된 데이터 값을 서로 다른 크기의 데이터 타입으로의 이전을 수행하지 않음으로써 예방할 수 있습니다.


l CWE-242: Use of Iherently Dangerous Function


CWE-242는 안전이 보장되지 않은 함수 호출에 대한 위험을 명시하고 있습니다. 일부 함수들은 어떻게 사용되는지 즉, 사용 방법에 상관없이 위험하게 동작합니다. 대부분 보안 문제를 고려하지 않고 구현이 이루어지는데, 예를 들어 문자열 입력 함수인 gets()는 대표적인 안전하지 않은 함수입니다. 문자열 입력 시 입력 받는 문자열 크기에 대한 검사를 수행하지 않기 때문입니다. 이에 공격자는 임의의 크기를 가진 문자열을 gets() 함수를 통해 입력시켜 시스템의 오버 플로우를 유발할 수 있습니다.



개발자는 소스 코드 작성 시 위험한 함수 사용을 지양하고 대체 가능한 안전한 함수를 사용하도록 하는 것이 좋습니다. 또는 소스 코드 기반의 분석을 수행하는 정적 분석 도구를 통해 위험한 함수가 사용되는지 검사하여 프로그램 실행 전 사전에 발생 가능한 문제를 예방하는 것이 좋습니다. GrammaTech 사의 정적 분석 도구인 CodeSonar는 C와 C++ 언어에서 주로 사용되는 라이브러리 함수 중 보안 취약점을 가진 함수나 위험한 함수로 알려진 다양한 함수를 사용할 경우 위험으로 간주하고 결함을 검출합니다. 더불어 사용자가 위험한 함수에 대한 정보를 도구에 사전 설정할 경우 소스 코드 내 해당 함수가 사용된 부분에서 Custom 결함을 검출할 수 있습니다.


l CWE-243: Creation of chroot Jail Without Changing Working Directory


CWE-243은 chroot() 함수를 사용하여 jail(감옥)을 생성하였으나, 이후 작업 디렉토리를 변경하지 않아 외부에서 파일에 대한 접근이 차단되지 않는 문제에 대하여 말하고 있습니다.


​chroot() 함수는 리눅스/유닉스 환경에서 제공하는 명령으로 파일시스템에서 루트 디렉토리를 변경하는 명령입니다. chroot()로 특정 디렉토리를 루트 디렉토리로 설정하면 jail 즉, 감옥이라는 환경이 생성되는데 이 감옥 안에서는 외부의 파일과 디렉토리 자원에 접근이 불가합니다. 이와 같이 chroot()는 디렉토리 경로를 차단하고 격리함으로써 정보 유출을 예방하기 위해 주로 사용됩니다. 예를 들어, 많은 FTP 서버들은 서버의 새로운 취약점을 발견한 공격자가 암호 파일이나 다른 중요 정보가 담긴 파일을 다운로드하는 것을 방지하기 위해 chroot를 통해 생성한 감옥 안에서 실행합니다.



위 예시 코드는 네트워크에서 파일 이름을 읽은 후 로컬 PC에서 파일을 열고 네트워크를 통해 데이터를 전송하고 있습니다. 작업 수행 전 chroot()를 초기에 호출하였으므로 /var/ftproot 디렉토리 내부에서는 외부 파일과 접근이 불가합니다. 그러나 현재 작업 디렉토리를 변경하지 않고 작업을 수행하고 있어, 공격자가 시스템 암호가 저장된 파일에 (예를 들면, ../../../../etc/passwd) 접근하여 중요 정보를 탈취할 수 있습니다. 사용자는 chroot를 통해 작업 디렉토리를 제한할 경우 해당 디렉토리로 경로를 이동한 뒤 작업을 수행될 수 있도록 chdir 또는 cd 등의 명령을 통해 반드시 작업 디렉토리를 변경해주어야 합니다.


l CWE-244: Improper Clearing of Heap Memory Before Release ('Heap Inspection')


CWE-244는 realloc()을 호출하여 버퍼 사이즈를 조절할 때 데이터가 메모리에서 제거되지 않아 중요 정보가 노출되는 위험을 명시하고 있습니다. 시스템 비밀번호 또는 암호화 키와 같은 중요 정보가 메모리에서 제거되지 않는다면 외부 공격자가 "heap inspection" 공격을 통해 중요 정보를 탈취할 수 있습니다. 'heap inspection'이란, 메모리 덤프(Memory dump)를 수집과 같은 방법을 통해 메모리에 저장된 데이터를 읽는 정보 탈취 공격을 말합니다.


​realloc() 함수는 할당된 메모리 블록 사이즈를 증가할 때 흔히 사용하는 함수입니다. 이 함수는 기존의 메모리 블록에 저장된 데이터를 새로운 큰 사이즈의 블록으로 복사하여 이동시킵니다. 그러나 기존 메모리 영역의 데이터는 삭제되지 않고 그대로 저장되어 있으며 프로그램에서 접근이 불가하여 저장된 중요 정보를 제거할 수 없습니다. 이 때 공격자가 메모리 덤프를 통해 데이터에 접근할 경우 중요한 정보가 노출될 수 있습니다. 사용자는 중요 정보를 저장한 메모리 참조 및 사용 직후 반드시 초기화 또는 데이터 삭제를 수행하도록 설계하여 정보 노출 및 악용을 사전에 예방하는 것이 중요합니다.



출처 : CWE 웹사이트 (http://cwe.mitre.org/index.html)


소프트웨어 버그 및 취약점 검출 솔루션 CodeSonar
E. codesonar@mdsit.co.kr
MDS인텔리전스