본문 바로가기
시스템 보안

버퍼 오버플로우 공격(BOF, Buffer Overflow Attack)

by 민지.com 2025. 3. 27.
반응형

Buffer Overflow

= 연속된 메모리 공간을 사용하는 프로그램이 할당된 메모리를 넘어선 위치에 자료를 읽거나 쓰려고 할 때 발생.

이로 인해 프로그램 오작동 발생 또는 악의적 코드 실행이 가능함.

 

1. Stack Buffer Overflow

: 함수 처리를 위해 지역변수와 매개변수가 위치하는 스택에 할당된 버퍼들이 문자열 계산 등에 의해 정의된 버퍼 크기의 한계치를 초과하는 경우 발생. 이를 통해 복귀 주소(return address)를 변경하고 공격자가 원하는 코드 실행 가능.

 

2. Heap Buffer Overflow

: 사용자가 malloc() 등의 메모리 할당 함수를 통해 동적으로 할당하는 힙에 할당된 버퍼들에 문자열 등이 저장될 때, 최초에 정의된 힙의 사이즈를 초과해 저장될 경우 발생. 이를 통해 데이터와 함수 주소 등을 변경해 공격자가 원하는 코드 실행 가능.

 

- 예시 공격 코드(Stack Buffer Overflow)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
shell_code() {
	setreuid(0,0); //ruid, euid를 root로 설정
	setregid(0,0); //rgid, egid를 root로 설정
	system("/bin/sh"); //root 및 root 그룹 권한으로 쉘 실행
}

int main(int argc, char **argv) {
	char buffer[12];
	memset(buffer, 0x00, sizeof(buffer));
	if (argc != 2) {
		printf("Usage : buf_over data\n");
		exit(-1);
	}
	strcpy(buffer, argv[1]);  //인자로 받은 문자열을 버퍼로 복사
	printf("sizeof %d \n", sizeof(argv[1]));
	printf("strlen %d \n", strlen(argv[1]));
	return 0;
}

 

- 코드 설명

  • buffer = 12byte 크기의 배열
  • strcpy(char *dst, const char *src)
    = src 문자열을 dst 버퍼에 저장할 때 문자열의 길이를 체크하지 않아 버퍼 오버플로우에 취약한 함수.
    (보안적인 측면에서 strcpy와 달리 문자열의 길이를 체크하는 strncpy를 사용하는 것이 바람직함)
  • argv [ ] 매개변수
    = C 언어에서 main 함수를 통해 전달되는 매개변수를 받게 해주는 포인터 배열. 
    단, argv[0]은 프로그램명을 의미. argv[1]부터 main 함수로 전달하는 첫 번째 매개변수에 해당.
  • argv[1]의 길이가 버퍼의 크기인 12byte를 초과할 경우, 버퍼 오버플로우 발생.
  • 공격자는 버퍼 오버플로우를 발생시키기 위해 return address 위치에 shell_code()의 주소를 삽입해야 한다.
    따라서, 입력 데이터를 다음과 같이 구성한다.
    - 입력 데이터: "A" * 12 + "B" * 4 + "\xef\xbe\xad\xde" (이때, shell_code()의 위치는 0xdeadbeef라고 가정)

버퍼 오버플로우 대응 방법

  1. strcpy와 같은 취약한 함수 대신 strncpy 사용
  2. 스택 실행 비활성화(NX bit)
  3. 스택 무작위화(ASLR, Address Space Layout Randomization) 
  4. Stack Canary 사용(아래 스택 가드와 스택 쉴드에서 사용하는 기술)
  5. 포인터 사용하기 이전에 인자 길이 검증 수행
  6. 스택 가드 사용(메모리상에 프로그램 복귀주소와 변수 사이에 특정 값 저장해 두었다가 해당 값이 변경되었을 경우 프로그램 실행 중단)
  7. 스택 쉴드 사용(함수 시작 시 복귀 주소를 Global RET이라는 특수 스택에 저장해 두었다가 종료 시 저장된 값과 스택의 실제 RET 값 비교해 다를 경우 프로그램 실행 중단)
반응형