스택 버퍼 오버플로우는 사이버 보안 분야에서 가장 기본적이면서도 강력한 공격 기법 중 하나이다. 이 글에서는 스택 버퍼 오버플로우의 기본 개념부터 Direct EIP Overwrite, Trampoline 기법, SEH Overwrite 등 다양한 익스플로잇 방법과 방어 기법까지 체계적으로 정리한다.
버퍼 오버플로우는 할당된 메모리의 범위를 넘어선 위치에 데이터를 읽거나 쓰려고 할 때 발생하는 취약점이다. 버퍼는 데이터가 목적지로 이동되기 전에 보관되는 임시 저장소로, 송신 측과 수신 측 사이에 위치하여 데이터를 간접적으로 전달하는 역할을 한다.
버퍼 오버플로우가 발생하는 주요 원인은 입력 데이터의 길이 제한을 하지 않기 때문이다. 예를 들어, 10바이트 크기의 버퍼에 20바이트 크기의 데이터가 들어가려 하면 오버플로우가 발생한다. 취약한 함수들로는 strcat(), strcpy(), gets(), scanf() 등이 있으며, 이러한 함수들은 입력 길이를 제한하지 않는다.
버퍼 오버플로우가 발생하면 다음과 같은 보안 위협이 발생할 수 있다:
Direct EIP Overwrite는 버퍼 오버플로우를 통해 프로그램의 실행 흐름을 직접적으로 제어하는 기법이다. 이 공격은 스택에 있는 함수의 반환 주소(Return Address)를 덮어씌워 공격자가 원하는 코드로 실행 흐름을 변경한다.
Direct EIP Overwrite 기법은 ASLR(Address Space Layout Randomization)과 같은 보호 메커니즘이 적용되지 않은 환경에서 효과적이다.
Trampoline 기법은 ASLR이 적용된 환경에서 쉘코드의 정확한 주소를 알기 어려울 때 사용하는 우회 기법이다. 이 기법은 등록된 코드의 주소를 직접 보는 대신 JMP ESP와 같은 명령어를 통해 쉘코드로 이동하는 방식을 사용한다.
Trampoline 기법의 장점은 ASLR이 적용된 환경에서도 공격이 가능하다는 점이다. 이 기법은 특히 프로세스가 로드하는 DLL 중에서 JMP ESP나 CALL ECX와 같은 가젯(gadget)을 찾아 활용한다.
예를 들어, GlobalScapeFTP 프로그램에서는 ECX 레지스터가 스택의 주소를 가리키고 있다는 것을 확인한 후, call ecx 명령어가 있는 주소(0x165095e5)를 찾아 이를 반환 주소로 덮어씌워 공격에 성공한 사례가 있다.
SEH(Structured Exception Handling) Overwrite는 윈도우의 예외 처리 메커니즘을 이용한 공격 기법이다. 윈도우 시스템의 SEH는 예외 처리기 등록 구조체가 스택에 위치하기 때문에 공격자가 버퍼 오버플로우를 통해 이를 조작할 수 있다.
SEH는 다음과 같은 구성요소로 이루어져 있다:
SafeSEH는 SEH Overwrite 공격을 방어하기 위한 기법으로, exception_handler가 스택의 범위에 있을 경우 호출하지 않도록 한다. 그러나 다음과 같은 방법으로 SafeSEH를 우회할 수 있다:
버퍼 오버플로우 공격을 방어하기 위한 다양한 기법들이 존재한다.
스택 쿠키(Stack Cookie)는 메모리상에서 프로그램의 복귀주소와 변수 사이에 특정 값(카나리)을 저장해 두었다가 그 값이 변경되었을 경우 오버플로우로 가정하여 프로그램 실행을 중단하는 방법이다. Windows에서는 GS(Generic Security)라고도 불린다.
함수 시작 시 리턴주소를 특수 스택에 저장해 두었다가 함수 종료 시 저장된 값과 스택의 RET값을 비교해 다른 경우 프로그램을 종료하는 방법이다.
메모리 공격을 방어하기 위해 주소 공간 배치를 난수화하는 방법이다. 이를 통해 공격자가 쉘코드나 함수의 정확한 주소를 예측하기 어렵게 만든다.
데이터 영역(스택, 힙)에서 코드가 실행되는 것을 방지하는 보안 기능이다. 이로 인해 공격자가 삽입한 쉘코드가 실행되는 것을 막을 수 있다.
취약한 함수 대신 길이 제한이 있는 안전한 함수를 사용하는 것이 중요하다.