본문 바로가기
공부/정보보안기사

<정보보안기사> 1. 시스템 이론 - 버퍼 오버플로우 공격(Buffer Overflow Attack)

by Richard_Hoon 2024. 11. 27.
반응형

 

 

버퍼 오버플로우 공격 개요

 

 - `버퍼 오버플로우`는 컴퓨터 프로그램에서 발생하는 치명적인 취약점 중 하나

 - 프로그램이 할당된 메모리 공간(버퍼)보다 더 많은 데이터를 입력받아 인접한 메모리 영역까지 덮어씌우는 현상을 의미

 - 마치 물에 담긴 컵에 물을 계속 부으면 넘쳐서 테이블까지 젖는 것과 비슷

 

`버퍼 오버플로우 종류`

 

`1. 스택 버퍼 오버플로우`

 - ㄱ. 발생 위치 : 동적으로 할당된 메모리 영역인 힙에서 발생

 - ㄴ. 공격 원리 :

    - 힙에 할당된 메모리 블록의 크기보다 더 많은 데이터를 쓰면, 인접한 메모리 블록의 내용을 덮어씌울 수 있음

    - 이를 통해 메모리 관리 구조를 손상시키거나, 다른 프로그램의 메모리를 침해할 수 있음

 - ㄷ. 위험성 :

    - 스택은 프로그램 실행에 필수적인 정보를 저장하는 공간이므로, 스택 버퍼 오버플로우는 프로그램의 정상적인 동작을 방해하고 시스템 전체를 불안정하게 만들 수 있음

 - ㄹ. 예방 :

    - 함수 호출 시 전달되는 인자의 크기를 검사하고, 지역 변수의 크기를 충분히 할당해야 함

    - 스택 크기 제한, 스택 쿠키 등의 보안 기법을 활용할 수 있음

 

`2. 힙 버퍼 오버플로우`

 - ㄱ. 발생 위치 : 함수 호출, 지역 변수 등이 할당되는 메모리 영역인 스택에서 발생

 - ㄴ. 공격 원리 :

    - 공격자가 스택에 할당된 버퍼보다 더 많은 데이터를 입력하면, 스택 포인터가 다음에 실행될 명령의 주소를 가리키는 부분까지 덮어씌우게 됨

    - 이를 통해 공격자는 임의의 코드를 실행할 수 있는 주소를 조작하여 시스템을 장악할 수 있음

 - ㄷ. 위험성 :

    - 힙은 프로그램 실행 중 동적으로 할당되는 메모리 영역이므로, 힙 버퍼 오버플로우는 다양한 종류의 공격에 악용될 수 있음

 - ㄹ. 예방 :

    - 메모리 할당 및 해제를 신중하게 처리하고, 메모리 할당 크기를 정확하게 계산해야 함

    - 메모리 풀, 가비지 컬렉션 등의 메모리 관리 기법을 활용할 수 있음

 

 

`버퍼 오버플로우가 위험한 이유`

 

1. 코드 실행 :

 - 공격자는 버퍼 오버플로우를 이용해 악성 코드를 메모리에 주입하고 실행시킬 수 있음

 - 이를 통해 시스템을 완전히 장악하거나 민감한 정보를 탈취할 수 있음

 

2. 시스템 충돌 :

 - 버퍼 오버플로우는 프로그램의 정상적인 동작을 방해하여 시스템이 크래시되거나 응답하지 않는 상태가 될 수 있음

 

3. 데이터 손상 :

 - 중요한 데이터가 덮어씌워져 손실 될 수 있음

 

 

 

스택 오버플로우 공격 예제

 

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[]){
	
    char buffer[16];				# 크기가 16바이트인 버퍼 생성
    
    strcpy(buffer, argv[1]);			# 사용자 입력을 버퍼에 복사(길이 검사 없음)
    
    printf("You entered: %s\n", buffer);	# 버퍼 값을 출력
}

 

gcc -o overflow overflow.c ./overflow "AAAAAAAAAAAAAAAAAAAAAA" # 16바이트를 초과하는 문자열 입력

 

 - 입력값을 검증하지 않고 복사하는 strcpy 함수의 취약점을 이용해 스택 버퍼 오버플로우를 발생할 수 있음

 - 루트 권한으로 악성 코드를 실행하거나 입력값을 버퍼를 초과하여 받을 경우 치명적인 동작이 발생할 수 있음

 

 

 

스택 오버플로우를 위한 안전한 코드

 

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[]) {
    char buffer[16];				# 크기가 16바이트인 버퍼 생성

    if (strlen(argv[1]) >= 16) {		# 입력값의 크기가 16 이상일 경우 입력값 초과 에러
        printf("Input too long\n");
        return 1;
    }

    strncpy(buffer, argv[1], sizeof(buffer)-1);	# 마지막 바이트를 null 문자로 채우기 위해 -1
    buffer[MAX_SIZE - 1] = '\0';

    printf("You entered: %s\n", buffer);	# 버퍼 값을 출력

    return 0;
}

 

 

 - 스택 버퍼 오버플로우에 취약한 strcpy 함수를 strncpy 함수로 대체함

 - `sizeof(buffer)-1`의 의미는 입력값에서 null을 포함했기에 null 문자 `0x00`의 크기인 1을 제거하기 위함임

 - strlen은 null 문자를 포함하지 않기에 `strlen(buffer) = sizeof(buffer) - 1`을 암기하면 좋음

 

입력값에 `AAAAAAAAAAAAAAAAAAAA` 20바이트를 입력하면

`strlen(argv[1]) = 20`으로 나오나

`strlen(buffer) = 15`로 나온다.

 

sizeof(buffer) - 1 = 16 - 1 = 15만큼 버퍼를 복사하기 때문이다.

 

 

스택 버퍼 오버플로우 대응 기술

 

`1. 스택가드(Stack Guard)`

 - 원리 :

    - 스택 프레임의 중요한 영역인 반환 주소와 지역 변수 사이에 특정 값(카나리 값)을 삽입하여 스택의 무결성을 검사 

    - 공격자가 버퍼를 넘쳐 흐르게 하여 반환 주소를 변경하려고 하면, 카나리 값도 함께 변경되므로 이를 감지하여 프로그램을 비정상 종료 

 - 장점 :

    - 구현이 간단하고 효과적이며, 컴파일러 레벨에서 지원하는 경우가 많음

 - 단점 :

    - 카나리 값을 예측하거나 우회하는 공격 기법이 존재할 수 있음

 

`2. 스택 쉴드(Stack Shield)`

 - 원리 :

    - 스택 가드와 유사하지만, 더욱 강력한 보호 기능을 제공 

    - 스택 프레임의 레이아웃을 변경하고, 특수한 스택을 사용하여 반환 주소를 보호 

 - 장점 :

    - 스택 가드보다 더욱 강력한 보호 기능을 제공하며, 공격자가 예측하기 어렵게 만듬

 - 단점 :

    - 구현이 복잡하고, 모든 시스템에서 지원되지 않을 수 있음

 

`3. ASLR(Address Space Layout Randomization)`

 - 원리 :

    - 프로그램이 메모리에 로드될 때마다 메모리 주소를 무작위로 배치하여 공격자가 정확한 메모리 주소를 예측하기 어렵게 만듬 

 - 장점 :

    - 스택 버퍼 오버플로우 공격뿐만 아니라 다양한 종류의 메모리 공격에 효과적

 - 단점 :

    - 완벽한 보호는 어렵고, 다른 보안 기술과 함께 사용해야 효과적

 

반응형

댓글