[컴퓨터 보안] 버퍼 오버플로우(Buffer overflow)의 개념과 예방법
버퍼 오버플로우(Buffer overflow)의 개념과 예방
버퍼 오버플로우 개념
버퍼 오버플로우 개념
버퍼 오버플로우는 버퍼 오버런(buffer overrun), 버퍼 오버라이트(buffer overwrite)라고도 불린다.
버퍼 오버플로우의 개념은 버퍼에 할당된 저장 영역에 할당된 영역보다 더 많은 자료를 입력하여 데이터를 변경 할 수 있는 조건이다.
공격자는 조건을 이용하여 시스템 먹통으로 만들거나 코드를 삽입해서 시스템의 제어를 가진다.
버퍼 오버플로우는 스택 버퍼 오버플로우, 힙 버퍼 오버플로우 2 가지가 있다.
버퍼 오버플로우 예제
1. 아래 코드를 실행 해보자.
#include <stdio.h>
#include <string.h>
void vulnerableFunction(char* input) {
char buffer[10];
strcpy_s(buffer, 20, input);//4 copy하기
printf("입력값: %s\n", buffer); //공백"\n" 포함 10자가 넘으면 오류 발생
}
int main() {
char userInput[20];
printf("문자열을 입력하세요: ");// 1. 문자 입력
gets(userInput); //2. 문자열 입력 받기(공백"\n" 포함 )
vulnerableFunction(userInput);//3. 함수 가기
return 0;
}
2. 1234567891 을 입력하면 총 11글자다.(gets 함수는 문자열을 입력하는 함수인데 공백(\n)을 포함 한다.)
3. 버퍼 오버플로우가 발생했다면서 에러가 발생한다.
4. 오류가 발생하는 이유
1. main 함수의 UserInput[20] 배열은 20바이트를 할당 했고
2. vulnerableFunction 함수의 buffer[10] 배열은 10 바이트를 할당 했다.
3. strcpy_s(buffer, 20, input); 함수에서 buffer에 *input의 11바이트(1234567891\n)을 복사해서 넣을려고 하니 버퍼 오버플로우가 발생해 오류가 났다.
5. gets 함수 바꿔서 개수 지정해주기
위처럼 gets 함수는 문자열을 입력 할 수 있다. gets 함수 대신 fgets 함수를 사용하여 최대 입력 수를 정할 수 있다. 만약 10을 적으면 10개만 입력이 가능하니 버퍼 오버플로우를 예방 할 수 있다.
스택 버퍼 오버플로우
buffer[8] 보다 많은 8글자 이상 입력하면 오버플로우가 발생한다.
gets 함수를 fgets로 바꿔 입력수를 제한해야 한다.
#include <stdio.h>
int main() {
char buffer[8];
printf("문자열을 입력하세요: ");
gets(buffer);
printf("입력값: %s\n", buffer);
}
힙 버퍼 오버플로우
동적 할당을 한 buffer 보다 많은 10글자 이상 입력하면 오버 플로우가 발생한다.
gets 함수를 fgets로 바꿔 입력수를 제한해야 한다. 또한 동적 할당 해제인 free를 꼭 해줘야 한다.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void vulnerableFunction(char* input) {
char* buffer = (char*)malloc(10);
strcpy_s(buffer, 10, input);
printf("입력값: %s\n", buffer);
free(buffer);
}
int main() {
char userInput[20];
printf("문자열을 입력하세요: ");
gets(userInput);
vulnerableFunction(userInput);
return 0;
}
버퍼 오버플로우 예방법
1. 프로그래밍 언어 선택 : 현대의 고급 프로그래밍 언어는 변수 타입, 허용되지 않는 연산 등에 대해 강력한 표기법을 제공한다. 이러면 프로그래머가 오버플로우를 따로 검증하는 코드를 안 작성해도 된다. 왜냐하면 이미 컴파일러가 그 표기법은 안된다고 검증을 하라고 알려주기 때문.
2. 안전한 라이브러리 사용 : 검증된 라이브러리 같은 경우는 개발자들이 마음 놓고 쓴다. 하지만 어떠한 버퍼 오버플로우가 있을 지 모르는 일이다. 또한 사용하지 말라는 함수는 사용 하면 안된다. 예를 들어 gets 함수대신 getsf 함수를 쓰는 것처럼 안전한 라이브러리 함수를 사용해야 한다.
댓글
댓글 쓰기