Hacking & Security/System2008. 11. 18. 17:51
사용자 삽입 이미지

2007/04/02(월)
전략마케팅실 기술기획 / 대리 이성열

'Buffer Overflow 공격'.. 보안에 대해서 관심있는 사람뿐 아니라 시스템/네트웤, 개발자에 이르기까지 한 번 쯤은 들어봤을 만한 용어이다. 적어도 IT분야에서는 널리 알려진 이 용어에 대해서 인터넷, 보안서적 등을 살펴보면 "지정된 크기의 저장공간(Buffer) 보다 넘치게(overflow) 입력되는 Overflow 현상을 이용하여 Buffer에 입력되지 못한 조작된 데이터를 시스템의 특정 위치에 기록하여 공격하는 기법" 이라는 간략한 설명으로 시작되는 Buffer Overflow에 대해서 그 원리에 대해서 충분히 이해하기란 쉽지않아 이번 Lecture에서는 Overflow 공격의 기본 원리를 Buffer Overflow 공격기법 중 하나인 Stack Overflow를 중심으로 정리한다.


기본 메모리 구조 - Stack, Heap, Code
Overflow 공격을 설명하기에 앞서서 우선은 시스템의 메모리 구조에 대한 이해가 필요하다. 일반적인 시스템에서 메모리는 아래의 그림처럼 3가지로 구분되는데 메모리의 상세구조에 대해서 설명하기 보다는 우선 Stack Overflow 공격과 관련된 Stack 영역과, Code 영역에 대한 이해를 돕기로 한다.

사용자 삽입 이미지

[그림 1] 일반적인 메모리 구조


STACK 영역

Stack 영역은 프로그램안에 함수에 의해서 선언된 변수에 할당되는 영역으로 시스템이 특정 함수를 실행하는 경우 함수내에 선언된 변수와 이들 값을 저장하기 위해서 할당되었다가, 함수의 실행이 종료되면서 해제되는 영역이다.
프로그램의 함수가 실행되면 Stack 영역에 Stack Frame 이라는 영역이 함수에 할당되는데 이 Stack Frame에 해당 함수가 실행하는데 필요한 정보들이 저장되어있다.

사용자 삽입 이미지

[ Stack & Stack Frame ]


CODE 영역
Code 영역은 프로그램이 실질적으로 실행될 명령어가 저장되는 공간으로 기계어로 프로그램(또는 함수)의 실행코드가 기계어 형태로 저장되어있다.



Buffer Overflow에 취약한 프로그램?
Buffer Overflow에 취약한 프로그램에 대해서 설명하기 전에 우선은 아래의 샘플코드를 살펴보자.
먼저 6라인의 char var[10]; 부분에서는 var라는 변수에 최대 10Byte의 자료가 저장될 수 잇는 공간을 할당하였다. 다음 7라인을 보면 strcpy()함수를 실행하는데 6라인에서 선안한 10Byte 크기의 var 변수공간에 32byte 크기의 문자열을 저장하고 있어 이 샘플코드를 컴파일하고 실행하면 Buffer Overflow 현상이 발생하여 프로그램이 정상적으로 실행하지 못할 것을 예상할 수 있다.

사용자 삽입 이미지

위 샘플코드를 컴파일하고 실행하고 로그를 확인한 결과를 다음에 보여주는데 프로그램이 실행한 직후 프로그램상에서 오류가 발생하였으며, 이벤트 로그를 확인한 결과 주소 0x45454545 부분에서 문제가 발생했음을 알 수 있다.

사용자 삽입 이미지

[ 샘플코드 실행결과 ]

 

사용자 삽입 이미지

[ 로그 확인 결과 ]


Buffer Overflow 현상과 Stack Frame
이제 지정한 크기의 저장공간에 큰 값을 입력하였을 경우 시스템 내부적으로 어떻게 동작하여 Overflow가 발생하면서 오류가 발생하는지 살펴보자.

최초 샘플프로그램이 실행되면서 Stack 영역에 하나의 Stack Frame에 할당되며, 이 Stack Frame에 'var' 변수를 위한 공간이 할당된다.

그 다음으로 scrcpy()함수가 실행되면서 'var'변수에 문자열 'AAAABBBBCCCCDDDDEEEEFFFF GGGGHHHH' 문자열이 저장되는데 문제는 12byte 크기의 저장소에 32byte 크기의 문자열이 저장되면서 'var'에 할당된 12byte 까지는(주1) 정상적으로 저장될 것이다.

※ 주1 : 샘플 프로그램에서 'var'에 할당한 메모리 크기는 10byte 이지만 테스트한 시스템은 32bit 시스템으로 실제 'var' 변수에는 12byte의 공간이 할당되며, 문자열도 12byte 크기가 저장된다.)

그렇다면 'var'에 저장되고 남은 문자열은 어디에 있는지 살펴보면, 운영체제가 var에 할당해준 12byte 공간에 이어서 문자열이 저장되는 것을 메모리 맵을 통해서 확인할 수 있다.

사용자 삽입 이미지

[ 문자열 저장확인 ]

이제 주어진 문자열이 지정한 공간의 넘어서 메모리에 쓰여졌을을 확인하였는데, 이렇게 불필요하게 쓰여진 데이터가 프로그램에 미치는 영향을 확인해야 한다.

Strack Frame의 구조를 다시 살펴보면 Stack Frame의 argument영억에 이어서 Instruction 영역이 존재하는데 Instruction 영역은 함수가 종료한 후에 실행될 명령어가 저장된 주소값을 가지고 있다.
따라서 위 그림에서 '45 45 45 45' 문자열에 위치한 곳은 strcpy()함수가 실행되고 다음 실행할 명령어가 있는 위치한 주소값을 저장한 곳이다.

그러나 잘못된 프로그래밍에 의해서 strcpy() 다음 명령어가 저장된 주소값이 지워져 버린것이다.
이를 확인하지 위해서 메모리 주소 '45 45 45 45 '를 확인한 메모리 맵이 아래 그림이다.

사용자 삽입 이미지


메모리 상의 '45 45 45 45' 위치를 확인한 결과 '?' 표기로 되어있어 아무런 기계어 코드가 없는 것을 확인할 수 있으며, 프로그램은 strcpy()를 실행한 후에 '45 45 45 45' 위치의 '????' 명령어를 실행하던 중 오류가 발생한 것이며 프로그램의 각 실행코드와 메모리 동작을 나타내면 아래 그림으로 표현 할 수 있다.
 

사용자 삽입 이미지


지금까지 살펴본 내용은 Buffer Overflow 현상이 발생하는 과정을 메모리 특히 Stack 영역에 국한하여 살펴보았으며, 다음 강좌에서는 Overflow 취약점을 이용하여 임의의 명령어를 실행하는 방법을 설명하면서 메모리 동작을 더욱 자세하게 살펴보겠다.



출처 : http://www.coconut.co.kr/board/seculetter.php?id=seculetter
Posted by skensita