버퍼 오버플로우란?
버퍼 오버플로우(Boffer Overflow)란 메모리를 다루는 데 오류가 발생해 잘못된 동작을 하는 프로그램 취약점입니다. 프로그램이 할당된 고정 길이(Fixed-length) 메모리 버퍼의 한계를 제대로 확인하지 않고 보유할 수 있는 것 보다 더 많은 데이터를 쓰는 경우 발생합니다. 이로 인해 인접 메모리 공간으로 넘지는 (Overflow)가 일어나 그 곳의 정보를 덮어쓰게 되고, 충돌이나 악용 가능한 상태를 유발합니다. 임의로 악성코드를 실행하는 가장 오래되고 흔한 공격 방법 중 하나입니다. 비교적 자유도가 높고, 프로그래머이 책임이 큰 C/C++ 언어는 다른 언어보다 이런한 오류가 발생할 가능성이 높습니다.
버퍼 오버플로우 공격(Buffer Overflow Attack)이란 길이에 대한 불명확한 정의를 악용한 덮어쓰기로 발생합니다. 버퍼 오버플로우에 취약한 함수와 그렇지 않은 함수가 있는데, 프로그래머가 취약한 특정 함수를 이용하지 않으면 공격이 훨씬 어려워집니다.
버퍼 오버플로우의 종류
버퍼 오퍼플로우의 종류는 다음과 같습니다.
- Stack Buffer Overflow
- 스택(함수 처리를 위해 지역 변수와 매개변수가 위치하는 메모리 영역) 구조 상, 할당된 버퍼들이 한계치를 넘는 경우 복귀 주소를 변경해 공격자가 임의의 코드를 수행
- Heap Buffer Overflow
- 힙(malloc() 등의 메모리 할당 함수로 사용자가 동적으로 할당하는 메모리 영역) 구조 상, 최초 정의된 힘의 메모리 사이즈를 초과하는 문자열들이 힘의 버퍼에 할당될 시, 공격자가 데이터 변경 및 함수 주소 변경으로 임의 코드를 실행
버퍼 오버플로우 예시
(위키피디아)
/* overflow.c - 버퍼 오버플로를 설명한다 */
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
char buffer[10];
if (argc < 2)
{
fprintf(stderr, "사용법: %s 문자열\n", argv[0]);
return 1;
}
strcpy(buffer, argv[1]);
return 0;
}
위의 C 소스코드를 컴파일한 후, 긴 문자열을 가지고 실행하면 이 프로그램은 버퍼 오버플로우 오류가 발생할 것입니다. 왜냐면 인자의 길이를 체크하지 않고 버퍼를 채우는데 사용하기 때문입니다. 이 코드는 9개 이하의 문자 스트링에서는 버퍼 오버플로우를 일으키지 않습니다. 그러나 10 이상의 문자들은 일으킵니다.
strncpy 함수를 사용하면 버퍼에 쓰일 문자의 개수를 제한할 수 있어 버퍼 오버플로우를 일으키지 않습니다.
대응방안
- 개발자가 오류를 피하도록 교육/ 보안 코딩 가이드 또는 코딩 표준 사용하기
- 버퍼오버플로우에 취약한 함수/라이브러리 사용하지 않기
- 버퍼오버플로우 공격에 안전한 프로그래밍 언어나 프레임워크 사용
- 입력값 사전 검증