주요 내용으로 건너뛰기

버퍼 오버플로우 취약점에 대한 공격기법 및 대응책에 관한 동향연구

Buffer overflows: Attacks and defenses for the vulnerability of the decade

본 포스팅은 [Cowan+03] 논문에 대한 요약번역으로, 원문 출처는 아래와 같다.

Cowan, Crispin, et al. "Buffer overflows: Attacks and defenses for the vulnerability of the decade." DARPA Information Survivability Conference and Exposition, 2000. DISCEX'00. Proceedings. Vol. 2. IEEE, 2000.


논문의 제목을 “버퍼 오버플로우 취약점에 대한 공격기법 및 대응책에 관한 동향연구”으로 번역할 수 있겠으나, 이 논문이 발표된 시점은 2000년이며, 논문에서 제시한 기간의 범위가 decade(10년)임을 고려할 때, 실제로는 1990~2000년 어간의 연구동향을 종합하여 수록한 것으로 보인다. 때문에 본 블로그 포스팅을 작성하는 2017년 현재를 기준으로 한다면 ‘최신동향’이라 보기에는 어렵다. 따라서 추가적인 신기술 동향이 궁금한 독자들은 이러한 배경을 감안하고 스스로 탐구해보기 바란다.

Abstact

버퍼 오버 플로우는 지난 10 년 동안 가장 보편적으로 널리 알려진 보안 취약점이다. 익명의 인터넷 사용자가 네크워크를 통해 원격으로 침투하여 타겟 호스트의 일부 혹은 전체에 대한 통제능력을 획득하는 과정에서도 버퍼 오버플로우 취약점은 상당한 우위를 차지하고 있다. 만약 버퍼 오버플로우 취약점을 효과적으로 제거할 수만 있다면, 여러 심각한 보안 위협들의 상당수를 해결할 수 있을 것이다. 본 논문에서는 다양한 종류의 버퍼 오버플로우 취약점들을 살펴보고, 이를 방어하기 위한 기법들을 확인할 것이다. 특히, 본 연구진이 고안한 StackGuard 방법론 또한 설명할 것이다. 마지막으로 기존 시스템의 기능과 성능에 큰 지장을 주지 않는 선에서 버퍼 오버 플로우 취약점의 문제를 효과적으로 제거 할 수 있는 몇가지 대처방안을 제시하고자 한다.

Introduction

버퍼 오버플로우는 지난 10년동안 가장 많이 악용된 보안 취약점이다. 이러한 종류의 공격은 호스트 컴퓨터에 대한 완벽한 통제권을 가로채갈 수 있기 때문에, 가장 심각한 보안 위협의 일종으로 분류된다. 버퍼 오버플로우 취약점은 일반적으로 굉장히 흔하게 존재하며, 실제로 익스플로잇하기도 쉽기 때문에 해커들이 가장 애용하는 공격 기법으로 자리잡고 있다. 특히, 버퍼 오버플로우 취약점은 원격으로 침투하여 공격하는 과정에서 주로 활용되는데, 침입자는 공격 코드를 주입하고 실행하는 과정에서 오버플로우 취약점을 애용하곤 한다. 이렇게 주입된 공격 코드는 취약한 프로그램이 가진 권한을 그대로 가지고 실행되며, 공격자가 컴퓨터를 임의로 조작(사실상 ‘소유권’을 빼앗긴 상황)할 수 있도록 하는 출발점을 제공하게 된다.

관련하여 몇가지 재미있는 통계를 살펴보자면,

  • 1998년 Lincoln 연구소의 침입 탐지 시스템의 통계를 살펴보면, 새로운 원격 침투 공격의 60%는 사용자를 속여서 기밀정보를 탈취하는 사회공학적인 방식이었고, 나머지 40%는 버퍼 오버플로우를 이용한 공격이었다.
  • 1998년 CERT의 공식 발표에 따르면 13개중 9건의 침해사고가 버퍼 오버플로우와 관련이 있었으며, 1999년의 사건 통계에서도 적어도 절반은 버퍼 오버플로우 공격이 사용되었다.
  • 보안 취약점 동향을 전파하는 Bugtraq 의 비공식 설문조사에 따르면, 약 2/3의 응답자가 “버퍼 오버플로우가 보안 취약점의 주된 원인”으로 생각한다고 답했다.

버퍼 오버플로우 취약점에 대한 공격은 굉장히 다양한 방식으로 발전되어 왔다. 우리는 이어지는 2장에서 각 기법을 분류하고 설명할 것이다. 또한, 해당 공격들에 대응하기 위해 고안된 보호기법 역시 굉장히 다양하며 이를 3장에서 상세히 살펴보고, 특정방식의 공격들에 대해 보다 더 효과적으로 보호할 수 있는 기법을 선별하여 제시할 것이다. 특히, 기존 시스템의 호환성이나 성능을 저해하지 않으면서도 굉장히 효과적으로 공격으로부터 방어할 수 있는 것으로 알려져 있는 StackGuard 보호기법(by Immunix project)을 소개한다. 이어서 4장에서는 각각의 방어 기법들의 장단점과 보완관계를 살펴보고, 마지막 5절에서 결론을 제시한다.

버퍼 오버플로우 취약점과 그 공격기법

버퍼 오버플로우 공격의 최종적인 목표는 권한이 부여된 프로그램의 특정 함수를 강제로 조작하여, 그 프로그램을 통해 호스트 컴퓨터 전체를 좌지우지하는 것이다. 이때 전형적으로 공격의 대상이 되는 것은 root(최고관리자) 권한이 부여되어 있는 프로그램들로, 여기에다가 “exec(sh)” 등의 명령어를 실행하도록 하여 root 계정의 쉘을 호출하는 방식이 주로 쓰인다. 이러한 목적을 달성하기 위해서, 공격자는 다음의 두가지 절차를 수행해야 한다.

임의의 코드를 프로그램의 주소 공간(address space)에 접근 가능하도록 적절히 배치시켜야 한다.적절한 매개변수가 레지스터와 메모리에 적재된 채 프로그램의 해당 코드 부분으로 진입(jump)할 수 있도록 해야 한다.

버퍼 오버플로우 방지 기법

버퍼 오버플로우 취약점에 대한 공격으로부터 시스템을 보호할 수 있는 방법은 크게 4가지로 분류할 수 있다. 3.1절에서는 가장 단순하면서도 근원적인 방법으로 시큐어 코딩을 설명한다. 그 다음으로는 운영체제 관점에서 버퍼의 실행을 원천 봉쇄하여, 해커가 공격 코드를 주입하지 못하게하는 방법을 3.2절에서 소개한다. 이는 꽤나 효과가 있긴 하지만 공격자가 굳이 코드주입을 하지 않는 경우에는 쉽게 우회될 수 있으므로 약간의 약점을 갖는다. 3.3 절에서는 컴파일러 직접 접근을 사용하여 모든 배열 액세스에 대해 유효범위 검사를 수행하는 방법을 소개한다. 이 방법은 오버 플로우 공격을 불가능하게하여 관련 취약점을 완전히 제거할 수는 있지만 그만큼 상당한 cost를 부과해야한다. 3.4절에서 설명하는 간접-컴파일러 접근법은 코드 포인터를 역 참조하기 전에 코드 포인터에 대한 무결성 검사를 수행하는 것이다. 이 기술은 버퍼 오버 플로우 공격을 완벽히 방지할 수는 없지만, 대부분의 버퍼 오버플로 공격을 탐지하고 중단시키므로 공격이 어렵게 만든다.


이러한 방식의 방어 기법들에는 각각의 장단점이 있다. 예를들어, 코드 포인터 무결성 검사는 버퍼 오버 플로우 문제를 완벽하게 해결하지 못하는 경계 검사에 비해 단점이 있다. 그러나 성능 측면에서는 상당한 이점을 갖는다. 이러한 평가척도를 측정할 때에는 크게 세가지 요소로 구분할 수 있다.

  • 성능(Performance) : C언어에서는 기본적으로 코드 포인터를 해제하는 등의 과정에서 커다란 오버헤드를 야기할 수 있다. 매번 배열의 범위를 체크하게 되면 성능이 굉장히 저하될 수 있다.
  • 구현에 필요한 노력(Implementation Effort) : C언어에서 bound checker를 개발하는 난이도에 따라 적용 여부가 달라질 수 있다.  
  • 기존 코드와의 호환성(Compatibility with Existing Code) : 기존에 존재하는 코드를 많이 수정해야 한다면 적용이 꺼려질 것이다. 기존 코드의 변경을 최소화하는 측면에서 도입을 고려해야 한다.

효과적인 접목

앞서 섹션 2에서 설명한 취약점과 공격의 종류를 섹션 3에서 설명한 방어 조치와 비교하여, 버퍼 오버 플로우 문제를 완전히 제거 할 수있는 기술 조합과 비용을 요약정리하였다. 표 3은 버퍼 오버 플로우 공격과 방어의 교차 비교표이다. 맨 위에는 공격 코드가있는 곳 (2.1 절)이 있고 그 아래쪽에는 프로그램의 제어 흐름을 손상시키는 방법 집합 (2.2 절)이 있습니다. 각 셀에는 특정 조합에 대해 효과적인 방어 수단이 있다. 경계 검사(섹션 3.3)는 모든 형태의 버퍼 오버플로 공격을 막는 데 효과적이지만 대부분의 경우 비용이 지나치게 높으므로, 표 3에서 생략되어 있다.

버퍼 오버 플로우 공격의 가장 일반적인 형태는 스택 할당 버퍼에 코드를 주입하여 Activation Record 를 공격하는 방법이다. 이 양식은 1996 년 말 출판 된 논문에서 유래된 것이다 [30, 28, 35]. 가장 기초적인 방어책 (Non-executable Stack [19, 18] 및 StackGuard [14])들은 모두 이 공격기법에 대해 효과적으로 대처할 수 있다. Non-Executable Stack은 스택에 할당 된 버퍼에 코드를 삽입하는 모든 공격을 포괄하여 방어할 수 있고, StackGuard는 활성화 레코드를 손상시키는 모든 공격에 대응할 수 있다. 이러한 방어 체계는 서로 완벽하게 보완되므로 두 가지를 모두 사용하면 대부분의 공격을 상당 부분 포괄하여 지켜낼 수 있다.

실행 불가능 스택과 스택 가드 방어의 결합으로 커버할 수 없는 나머지 공격들은, 본 논문에서 제안하는 Point Guard을 통해 코드 포인터 무결성 검사를 수행하여 자동으로 공격을 방지 할 수있다. 임의의 프로그램 변수를 손상시키는 나머지 공격 역시 PointGuard에서 해결할 수는 있지만 상당한 수작업이 필요하다. 완전 자동 PointGuard 방어는 모든 변수에 대한 Canary-무결성 검사를 요구하며,이 시점에서 경계 검사는 무결성 검사와 유사하게 작동한다.

결론

본 논문에서는 버퍼 오버 플로우 취약점을 활용한 공격 및 그 방어기법을 상세히 분류하고, 분석하였다. 버퍼 오버 플로우는 대부분의 시스템에서 보안 취약점 및 원격 침투 가능성을 야기하기 때문에 명확한 원인분석이 필수적이다. 결론적으로 StackGuard [14, 9] 방어기법과, 스택 내용을 임의로 실행하지 못하도록 하는 방어기법 [19, 18]을 적절히 조합하면 대부분의 현대식 버퍼 오버 플로우 공격으로부터 보호할 수 있으며, 새롭게 제안한 PointGuard 기법의 경우 대부분의 나머지 현대 버퍼 오버 플로우 공격을 커버할 수 있음을 확인하였다.


정보보안에 관심이 많은 대학원생, 소프트웨어 엔지니어/서버관리자

CPUU 님의 창작활동을 응원하고 싶으세요?

댓글

SNS 계정으로 간편하게 로그인하고 댓글을 남겨주세요.