보안 공부/소스코드 보안약점 진단

소스코드 보안약점 진단 - 해제된 자원 사용

H.J.World 2022. 2. 2. 10:10
728x90
반응형

소스코드 보안약점 진단 // 소프트웨어 보안약점 진단 // SW 보안약점 진단과 같이 다양한 이름으로 불리는 진단 과업 중 하나이다.

SW개발보안은 해킹 등 사이버공격의 원인인 보안약점을 SW개발단계에서 사전에 제거하고 SW 개발 생명주기의 각 단계별로 수행하는 일련의 보안활동을 통하여 안전한 SW를 개발·운영하기 위한 목적으로 적용하는 개발체계이다.

해당 내용은 KISA에서 발간하는 취약점 진단 가이드 항목을 기준으로 작성한다.

 

제 5절 코드오류

타입 변환 오류, 자원(메모리 등)의 부적절한 반환 등과 같이 개발자가 범할 수 있는 코딩오류로 인해 유발되는 보안약점이다.

 

3. 해제된 자원 사용

가. 개요

C언어에서 동적 메모리 관리는 보안 취약점을 유발하는 대표적인 프로그램 결함의 원인이다. 해제한 메모리를 참조하게 되면 예상치 못한 값 또는 코드를 실행하게 되어 의도하지 않은 결과가 발생하게 된다.

나. 보안대책

동적으로 할당된 메모리를 해제한 후 그 메모리를 참조하고 있던 포인터를 참조 추적이나 형 변환, 수식에서의 피연산자 등으로 사용하여 해제된 메모리에 접근하도록 해서는 안된다. 또한, 메모리 해제 후, 포인터에 널(Null)값을 저장하거나 다른 적절한 값을 저장하면 의도하지 않은 코드의 실행을 막을 수 있다.

다. 코드예제

다음 예제는 동적 변수 temp에 할당된 동적 메모리를 해제 후 다시 사용하고 있다. 이 경우 예상치 못한 임의의 프로그램이 수행되는 취약점을 유발할 수 있다.

- 안전하지 않은 코드의 예 C -

1: int main(int argc, const char *argv[]) {
2: char *temp;
3: temp = (char *)malloc(BUFFER_SIZE);
4: ……
5: free(temp);
6: //해제한 자원을 사용하고 있어 의도하지 않은 결과가 발생하게 된다.
7: stmcpy(temp, argv[1], BUFFER_SIZE-1);
8: }

 

- 안전한 코드의 예 C -

다음 예제와 같이 메모리를 해제하기 전에 할당한 메모리를 사용하는 작업을 수행하고 최종적으로 메모리를 해제한다.

1: int main(int argc,const char *argv[]) {
2: char *temp;
3: temp = (char *)malloc(BUFFER_SIZE);
4: ……
5: //할당된 자원을 최종적으로 사용하고 해제하여야 한다.
6: stmcpy(temp,argv[1], BUFFER_SIZE-1);
7: free(temp);
8: }

 

라. 진단방법

소스코드 상에 메모리나 파일과 같은 자원을 사용하는 코드를 사용하는지 확인한다. 이 때, 자원을 사용하는 코드의 앞에서 자원의 해제가 발생하면 취약하다고 판단하며, 자원의 해제 후 모든 경우의 제어 흐름이 자원을 사용하는 코드로 도달하지 않을 경우 안전하다고 판단한다. 또한 자원을 참조 하는 포인터변수에 연산 작업을 수행하는 경우 보다 정밀하게 올바른 값을 참조하는지 검사해야 하며, 사용이 완료된 포인터 변수의 초기화가 이루어지는지 확인한다.

다음 예제는 할당된 메모리를 해제한 후 다시 접근하는 예제로, 21번 라인에서 실행되는 if문에서 messageBody에 할당된 메모리를 해지하였지만, 32번 라인에서 다시 해당 변수에 접근하고 있으 므로, 보안약점이 존재하는 코드라고 판단한다. 또한 사용이 완료된 변수는 반드시 널(Null) 값으로 초기화 해주도록 한다.

 

- 정탐코드의 예 -

다음의 예제에서는 재인증을 거치지 않고 계좌이체를 하고 있으므로 취약하다고 판정한다.

1: #define FAIL 0
2: #define SUCCESS 1
3: #define ERROR -1
4: #define MAX_MESSAGE_SIZE 32
5:
6: int processMessage(char **message)
7: {
8: int result = SUCCESS;
9: int length = getMessageLength(message[0]);
10: char *messageBody;
11:
12: if ((length > 0) && (length < MAX_MESSAGE_SIZE))
13: {
14: messageBody = (char*)malloc(length*sizeof(char));
15: messageBody = &message[1][0];
16: int success = processMessageBody(messageBody);
17:
18: if (success == ERROR)
19: {
20: result = ERROR;
21: free(messageBody);
22: }
23: }
24: else
25: {
26: printf(“Unable to process message; invalid message length”);
27: result = FAIL;
28: }
29:
30: if (result == ERROR)
31: {
32: logError(“Error processing message”, messageBody);
33: }
34: return result;
35: }

 

728x90
반응형