자격증/정보보안기사

시스템 보안 - 버퍼 오버플로우 공격(Buffer Overflow Attack) 방지하는 방법

j9m 2022. 10. 3. 10:39
반응형

버퍼 오버플로우(Buffer Overflow)

  • 버퍼 오버플로우는 프로세스가 사용 가능한 메모리 공간을 초과해서 발생되는 공격으로 보안 취약점이다.
  • C나 C++를 사용해서 프로그램을 개발할 때 메모리 공격에 제한을 두지 않는 API를 사용해서 발생하는 공격이다.
  • 버퍼 오버플로우 공격(Buffer Over flow Attack)을 알기 위해서는 먼저 실행 중인 프로세스가 사용하는 메모리 공간의 구조를 알아야 한다. 프로세스가 사용하는 메모리 공간은 Stack, Heap, Text, Data로 나누어져 있다.

 

메모리 구조(Memory Structure)

스택 영역

  • 프로그램 함수 내에서 사용하는 지역변수(Local varialbe)가 저장된다.
  • 함수를 호출하는 경우 되돌아오는 주소인 복귀 주소(Return Address)를 가지고 있다.
  • 함수의 인자 값을 가지고 있다.

 

힙영역

  • 프로그램 실행 중 메모리를 동적으로 할당하는 경우 힙 영역에 할당된다.
  • int *i 변수의 선언은 정수형(integer) 변수의 주소를 저장할 수 있는 포인터(Pointer) 변수를 선언한 것이다.
  • malloc() 함수를 사용해서 동적으로 메모리를 할당한다.
  • 동적으로 메모리를 할당할 때 sizeof(int)를 사용하면 4가 리턴되므로 4바이트의 크기가 동적으로 할당되는 것이다.
  • 마지막으로 malloc 함수는 "void *"을 리턴하는데 "(int *)"는 그것을 "int *"로  형 변환해서 맞추어 주는 것이다. 이렇게 동적 메모리 할당 함수를 사용해야 메모리를 할당하면 힙 영역에 할당된다.
  • 또한 동적으로 할당된 메모리는 free() 함수를 사용해서 해제해야 한다.

 

데이터(Data) 영역

  • 전역 변수를 선언하는 경우 전역 변수가 저장된다.
  • 정적 변수를 선언하면 정적 변수가 저장된다.
  • 데이터 영역에 변수가 선언되면 자동으로 초기화된다.

 

텍스트(Text) 영역

  • 읽기만 가능한(Read Only) 메모리 영역이다.
  • 프로그램 코드가 저장된다.

버퍼 오버플로우에 취약한 C언어 코드

  • 버퍼 오버플로우에 취약한 C언어 함수들은 다음과 같다. 이들 함수의 공통점은 길이 제한을 두는 기능이 없다는 것이다.
strcpy(char *dest, const char *src); //문자열 복사하는 함수
strcat(char *dest, const char *src); //문자열 합치는 함수
getwd(char *buf); //디렉터리 경로를 확인하는 함수
gets(char *s); //문자열을 입력받아 메모리에 저장하는 함수
fscanf(FILE *stream, const char *format); //파일에서 데이터를 읽는 함수
scanf(const char *format, ...); //입력을 읽는 함수
sprintf(char *str, const char *format, ...); //입력을 출력하는 함수

 

버퍼 오버플로우를 방지하기 위해서 사용을 권고하는 C언어 함수

strncat(); //문자열을 합치는 함수
strncpy(); //문자열을 복사하는 함수
fgets(); //문자열을 읽는 함수
vfscanf(); //문자열을 읽는 함수
snprintf(); //문자열을 출력하는 함수
vsnprintf(); //문자열을 출력하는 함수

 

버퍼 오버플로우 공격 종류

스택 오버플로우 공격

  • 스택 버퍼 오버플로우 공격은 스택에 저장되어 있는 복귀 주소가 지역변수에 의해서 침범당하는 공격이다.

 

힙 버퍼 오버플로우 공격(Heap Buffer Overflow Attack)

  • 힙 영역은 동적으로 할당되는 공간이 저장되어 있다.
  • 힙 영역은 하위 주소에서 상위 주소로 메모리를 할당한다. 그러므로 경계 값을 검사하지 않고 메모리를 사용하면 경계를 초과하는 취약점이 발생한다.

 

버퍼 오버플로우 공격의 대응책

스택가드

메모리상에서 프로그램의 복귀주소와 변수 사이에 특정 값을 저장해 두었다가 그 값이 변경되었을 경우 오버플로우로 가정하여 포르그램 실행을 중단하는 방법이다.

 

스택 쉴드 

변수 시작 시 리턴주소를 Global RET라는 특수 스택에 저장해 두었다가 함수 종료 시 저장된 값과 스택의 RET값을 비교해 다른 경우 프로그램을 종료하는 방법이다.

 

ASLR(Address Space Layout Randomization)

메모리 공격을 방어하기 위해 주소 공간 배치를 난수화하는 방법이다.

 

참고자료
이기적 정보보안기사 필기
https://slidesplayer.org/slide/12900990/
반응형