본문 바로가기

Information Security/Hacking

버퍼 오버 플로우 (BOF - Buffer OverFlow) 공격

반응형

* BOF 공격 : 연속된 메모리 공간을 사용하는 프로그램에서 할당된 메모리 범위를 넘어선 위치에 자료를 읽거나 쓸 때 발생하며, 오작동 또는 악의적 코드를 실행할 수 있게 됨

BOF 종류 설명
Stack BOF 스택(함수 처리를 위해 지역 및 매개변수가 위치하는 메모리 영역) 구조 상, 할당된 버퍼들이 정의된 버퍼 한계치를 넘는 경우, 복귀 주소를 변경하여 공격자가 임의 코드를 수행
Heap BOF 힙(malloc()등의 메모리 할당 함수로 사용자가 동적으로 할당하는 메모리 영역) 구조 상, 최초 정의된 힙의 메모리 사이즈를 초과하는 문자열들이 힙의 버퍼에 할당될 시, 공격자가 데이터 변경 및 함수 주소 변경으로 임의 코드를 수행

 

 

 

* Stack BOF 발생 시 스택 구조

용어 설명
Stack Frame - 모든 함수가 호출 될 때 할당되는 자신만의 스택 공간
SFP
(Stack Frame Pointer)
- 이전 함수의 스택 프레임 포인터를 저장하는 영역
- 스택 포인터(Stack Pointer)의 기준점이 됨
SP
(Stack Pointer)
- SFP를 기준점으로 하여, 상대주소(offset)을 저장하여 메모리를 접근
RET
(Return Address)
- 이전 함수의 다음 실행 명령어의 주소를 저장하는 영역
EBP Register - 현재 실행중인 함수의 SFP를 저장
ESP Register - SP를 저장
EIP Register - RET를 저장

- 결국 공격자는 SFP 영역까지 값을 넘치게 덮어 쓴 후, RET 영역까지 도달, RET 영역의 주소를 악성 코드의 주소로 변경하여 실행되도록 유도하는 형태로 Stack BOF를 수행.

- 악성 코드 내 setuid를 설정하여 root 권한으로의 권한 상승 등 다양한 공격에 이용 가능

 

 

 

* C 언어 상 BOF 주요 함수

BOF 주요 함수 설명
strcpy(char *dst, const char *src) - src 문자열을 dst 버퍼에 저장
- src 문자열 길이를 체크하지 않아, dst 버퍼를 초과하는 BOF 가능
strncpy(char *dst, const char *src, size_t len) - src 문자열의 len 만큼을 dst 버퍼에 저장
- src 문자열 길이를 제한하여 BOF 방지 가능
size_t strlen(const char *str) - 문자열(str)의 null 문자를 제외한 바이트 수를 반환
sizeof(피연산자) - 피연산자의 크기를 반환

char : 일반 문자열 지정으로 '상수'를 가르키지 못함

const char : 문자열 상수를 가르키나, 그 주소에 다른 값을 씌을 수 없는 읽기 전용 함수 (사용이 필요하면 선언과 동시에 값의 대입 = 초기화 필요)

- C언어의 경우 문자열 처리 시, 끝 부분에 null(0x00)으로 문자열 끝을 표현
(ex- "ABCD"라는 4개 문자열 정의 시, 실제로는 "ABCD\0" 으로 끝에 null이 포함된 5개 문자로 저장됨)

 

 

 

- C언어 main 함수에서 매개 변수의 개수는 'argc'로, 매개변수(전달되는 문자열 참조)는 'argv[]' 포인터 배열로 받음
(단, argv[0]의 경우, 프로그램 이름을 의미, argv[1] 부터가 main 함수로 전달하는 첫 매개변수가 됨)

 

 

 

// strcpy(buffer,argv[1]); /* BOF에 취약한 함수*/
strncpy(buffer,argv[1],sizeof(buffer)-1);

- C언어 Stack BOF 방지를 위해, strcpy 함수를 strncpy로 교체한다
-> strncpy(buffer, argv[1], sizeof(buffer)-1); 형식으로 대입하는 매개변수 len 만큼만, dst 버퍼에 저장하도록 유도할 수 있다 (sizeof에 -1을 설정하는 것은 C언어 문자열 끝 부분 null(0x00)까지 고려한 설계

 

 

 

/* 입력 문자열이 버퍼와 같거나 크면 오버플로우가 발생하여 프로그램 종료*/
//if(strlen(argv[1]) >= 버퍼크기){
if(strlen(argv[1]) >= sizeof(buffer)){
...

- 입력 문자열이 버퍼의 크기와 같거나 클 시, 프로그램을 종료하는 방식으로도 BOF를 방지할 수 있다
(C언어 문자열 끝 부분 null(0x00) 고려하여, 버퍼 크기와 같은 문자열도 체크가 필요)

 

 

 

* Stack BOF 대응 기술

대응 기술 설명
Stack Guard
(Canary Word Method)
- 메모리 상 프로그램 복귀 주소와 변수 사이에 특정 값(Canary Word)를 저장, 그 값이 변경되었을 경우 BOF로 간주하고 프로그램 중단
Stack Shield - 복귀 주소를 Global RET라는 특수 스택에 저장 후, 함수 종료 시에 저장된 값과 RET 값을 비교하여 다를 시, BOF로 간주하고 프로그램 중단
ASLR
(Address Space Layout Randomization)
- 프로그램 실행 시 마다 메모리 주소 공간을 난수화 하여, 특정주소 호출을 방지하는 방식

 

반응형