스택 버퍼 오버플로우

KIM DO YOON·2025년 4월 20일
0

스택 버퍼 오버플로우는 사이버 보안 분야에서 가장 기본적이면서도 강력한 공격 기법 중 하나이다. 이 글에서는 스택 버퍼 오버플로우의 기본 개념부터 Direct EIP Overwrite, Trampoline 기법, SEH Overwrite 등 다양한 익스플로잇 방법과 방어 기법까지 체계적으로 정리한다.

버퍼 오버플로우의 기본 개념

버퍼 오버플로우는 할당된 메모리의 범위를 넘어선 위치에 데이터를 읽거나 쓰려고 할 때 발생하는 취약점이다. 버퍼는 데이터가 목적지로 이동되기 전에 보관되는 임시 저장소로, 송신 측과 수신 측 사이에 위치하여 데이터를 간접적으로 전달하는 역할을 한다.

버퍼 오버플로우의 발생 원인

버퍼 오버플로우가 발생하는 주요 원인은 입력 데이터의 길이 제한을 하지 않기 때문이다. 예를 들어, 10바이트 크기의 버퍼에 20바이트 크기의 데이터가 들어가려 하면 오버플로우가 발생한다. 취약한 함수들로는 strcat(), strcpy(), gets(), scanf() 등이 있으며, 이러한 함수들은 입력 길이를 제한하지 않는다.

버퍼 오버플로우로 인한 보안 위협

버퍼 오버플로우가 발생하면 다음과 같은 보안 위협이 발생할 수 있다:

  1. 중요 데이터 변조: 버퍼 오버플로우가 발생하는 버퍼 뒤에 중요한 데이터가 있다면, 해당 데이터가 조작될 수 있다.
  2. 데이터 유출: 널바이트(\0)를 제거하여 다른 버퍼의 데이터를 읽을 수 있다.
  3. 실행 흐름 조작: 함수의 반환 주소(Return Address)를 조작하여 프로세스의 실행 흐름을 변경할 수 있다

Direct EIP Overwrite 기법

Direct EIP Overwrite는 버퍼 오버플로우를 통해 프로그램의 실행 흐름을 직접적으로 제어하는 기법이다. 이 공격은 스택에 있는 함수의 반환 주소(Return Address)를 덮어씌워 공격자가 원하는 코드로 실행 흐름을 변경한다.

Direct EIP Overwrite 공격 과정

  1. 취약한 프로그램의 버퍼 크기를 파악한다.
  2. 버퍼를 오버플로우시켜 SFP(Saved Frame Pointer)까지 더미 데이터로 채운다.
  3. 반환 주소(EIP)를 공격자가 원하는 주소(보통 쉘코드가 있는 주소)로 덮어씌운다.
  4. 함수가 종료되면 조작된 반환 주소로 실행 흐름이 이동하게 된다.

Direct EIP Overwrite 기법은 ASLR(Address Space Layout Randomization)과 같은 보호 메커니즘이 적용되지 않은 환경에서 효과적이다.

Trampoline 기법

Trampoline 기법은 ASLR이 적용된 환경에서 쉘코드의 정확한 주소를 알기 어려울 때 사용하는 우회 기법이다. 이 기법은 등록된 코드의 주소를 직접 보는 대신 JMP ESP와 같은 명령어를 통해 쉘코드로 이동하는 방식을 사용한다.

Trampoline 기법의 작동 원리

  1. 쉘코드를 스택 버퍼에 삽입한다.
  2. 레지스터(ESP, ECX 등)가 쉘코드가 있는 위치를 가리키도록 한다.
  3. 반환 주소를 JMP ESP, CALL ECX 등의 명령어가 있는 주소로 덮어씌운다.
  4. 함수 반환 시 해당 명령어가 실행되어 쉘코드로 점프하게 된다.

Trampoline 기법의 장점은 ASLR이 적용된 환경에서도 공격이 가능하다는 점이다. 이 기법은 특히 프로세스가 로드하는 DLL 중에서 JMP ESP나 CALL ECX와 같은 가젯(gadget)을 찾아 활용한다.

Trampoline 기법 예시

예를 들어, GlobalScapeFTP 프로그램에서는 ECX 레지스터가 스택의 주소를 가리키고 있다는 것을 확인한 후, call ecx 명령어가 있는 주소(0x165095e5)를 찾아 이를 반환 주소로 덮어씌워 공격에 성공한 사례가 있다.

SEH Overwrite 기법

SEH(Structured Exception Handling) Overwrite는 윈도우의 예외 처리 메커니즘을 이용한 공격 기법이다. 윈도우 시스템의 SEH는 예외 처리기 등록 구조체가 스택에 위치하기 때문에 공격자가 버퍼 오버플로우를 통해 이를 조작할 수 있다.

SEH의 구조

SEH는 다음과 같은 구성요소로 이루어져 있다:

  1. EXCEPTION_REGISTRATION_RECORD: 스택에 할당되는 링크드 리스트 구조
  2. pNextSEHRecord: 다음 SEH 레코드를 가리키는 포인터
  3. pExceptionHandler: 예외 처리를 위한 함수 주소

SEH Overwrite 공격 과정

  1. 버퍼 오버플로우를 통해 스택에 있는 SEH 구조체까지 데이터를 덮어씌운다.
  2. pNextSEHRecord에는 쉘코드로 점프하는 코드(예: JMP SHORT)를 삽입한다.
  3. pExceptionHandler에는 POP POP RET 가젯이 있는 주소를 삽입한다.
  4. 의도적으로 예외를 발생시켜 SEH 체인이 활성화되게 한다.
  5. 공격 코드가 실행된다.

SafeSEH와 그 우회 방법

SafeSEH는 SEH Overwrite 공격을 방어하기 위한 기법으로, exception_handler가 스택의 범위에 있을 경우 호출하지 않도록 한다. 그러나 다음과 같은 방법으로 SafeSEH를 우회할 수 있다:

  1. SafeSEH가 적용되지 않은 모듈의 POP POP RET 주소를 사용한다.
  2. 프로그램이 로드하는 DLL 중에서 SafeSEH가 적용되지 않은 모듈을 찾아 활용한다.
  3. 힙 주소에 있는 코드 조각을 활용한다.

버퍼 오버플로우 방어 기법

버퍼 오버플로우 공격을 방어하기 위한 다양한 기법들이 존재한다.

1. 스택가드(Stack Canary/Cookie)

스택 쿠키(Stack Cookie)는 메모리상에서 프로그램의 복귀주소와 변수 사이에 특정 값(카나리)을 저장해 두었다가 그 값이 변경되었을 경우 오버플로우로 가정하여 프로그램 실행을 중단하는 방법이다. Windows에서는 GS(Generic Security)라고도 불린다.

스택 쿠키 우회 방법

  1. 쿠키 값을 추측하거나 계산하는 방법
  2. 예외 핸들링을 이용한 우회
  3. 함수 내의 스택 데이터를 스택까지 덮어쓰는 방법

2. 스택 쉴드(Stack Shield)

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

3. ASLR(Address Space Layout Randomization)

메모리 공격을 방어하기 위해 주소 공간 배치를 난수화하는 방법이다. 이를 통해 공격자가 쉘코드나 함수의 정확한 주소를 예측하기 어렵게 만든다.

4. DEP(Data Execution Prevention)

데이터 영역(스택, 힙)에서 코드가 실행되는 것을 방지하는 보안 기능이다. 이로 인해 공격자가 삽입한 쉘코드가 실행되는 것을 막을 수 있다.

5. 안전한 함수 사용

취약한 함수 대신 길이 제한이 있는 안전한 함수를 사용하는 것이 중요하다.

  • 취약한 함수: strcat(), strcpy(), gets(), scanf() 등
  • 권장 함수: strncat(), strncpy(), fgets(), snprintf() 등
profile
안녕하세요 김도윤 입니다.

0개의 댓글