|
일러두기: 이 글은 C/C++ 언어 및 컴퓨터 시스템 프로그래밍에 어느 정도 지식이 있어야 이해할 수 있습니다.
요즘 내가하는 일 중 가장 큰 고민 거리는 malloc에 관한 작업이다. 내가 하는 일은 malloc의 취약성을 이용한 해커들의 공격을 막는 방법을 구현 해보는 것이다. 이제 막 학교 입학한 석사 1년차가 이런 것을 직접 만들었을리는 만무하고, 교수가 던져준 따끈따끈한 논문을 보고 구현을 하는 것이다. 구글 스칼라에서도 검색되지 않는 ASPLOS 2006에 발표될 논문이다. 대충 이 문제에 대해서 얘기 해보도록 하자. 1. Stack Overflow 학부 시절 시스템 프로그래밍 수업 시간이나 혹은 다른 곳에서 stack overflow는 많이 들어봤다. Stack overflow는 말 그대로 함수 인자 값 및 각종 local/auto 변수들이 있는 stack에 정해진 크기 보다 더 많은 데이터를 써서 컴퓨터를 해킹하는 것이다. 여기서 해킹이라는 것의 정확한 의미는: - 해커가 실행하고자하는 악성 코드를 실행할 수 있도록 컴퓨터의 제어권을 탈취하거나 - 제어권의 탈취가 아니더라도 프로그램에서 매우 중요한 데이터를 조작하는 것 을 가리킨다. Stack overflow에서는 두번째 일은 드물 것이다. 대부분이 call stack에 있는 return address를 다른 주소로 바꾸어 해커가 원하는 악성 코드가 실행되게끔 하는 것이다. 나도 자세히 이것에 대해서는 몰랐지만, 컴파일을 하면서 종종 disassembly를 보면 stack sanity check를 하는 코드가 컴파일러에 의해 만들어져있음을 볼 수 있었다. (MS C/C++ compiler 옵션 중 /RTCs가 바로 이런 것을 해준다.) 그러나 이러한 stack overflow는 이미 연구가 많이 되었고 이제 더 이상 이 취약점을 악용하기란 쉽지가 않다. 그래서 해커들이 눈을 돌린 것이 stack이 아닌 heap인 것이다. 2. Heap Overflow Heap overflow의 개념은 매우 간단하다. 예를 들어 malloc으로 10 byte의 메모리를 할당 받았다. 그런데 10 byte보다 많은 데이터를 쓸 경우에는 어떻게 될까? 바로 이것을 노린 것이 heap overflow의 핵심이다. 이것을 이해하기 위해서는 일반적인 malloc/free 함수들이 어떻게 메모리를 할당하고 해제하는 이해 해야만 한다. malloc/free로 대표되는 heap management 함수군은 작은 크기의 메모리를 빠르게 할당 해주는 것이 그 첫번째 임무이다. 대표적인 구현 방법으로는 GNU libc에서 사용 중인 Doug Lea의 malloc 구현이 있을 것이다. 먼저, 간단하게 생각해보자. malloc을 호출하면 미리 할당한 큰 메모리 블럭(Unix에서는 sbrk로, Windows에서는 VirtualAlloc으로)에서 작은 메모리 공간을 때어내서 돌려주고 그 정보를 기록하는 방식이다. 이 정보는 링크드 리스트나 기타 자료구조로 저장할 것이다. (따라서, malloc 소스는 완벽하게 user-level에서 돌아가는 알고리즘이다. 그래서 해킹이 용이한 것이다.) 실제 malloc에서 사용하는 방법은 데이터를 다음과 같이 저장한다. +-----------------------------------------------------+----- | Data | meta-data | Data | meta-data | Free space | ... +-----------------------------------------------------+----- 즉, 실제로 사용자가 쓰는 data 영역 사이에 할당한 메모리들을 관리하기 위한 meta-data가 존재한다. 이 meta-data에는 할당한 크기, 앞에 있는 블럭이 사용 중인가, 해제된 메모리의 경우에는 prev/next 프리 노드들에 대한 정보가 저장된다. 이러한 알고리즘은 이미 십여년간 사용되고 있다. 윈도우의 경우에도 이와 크게 다르지 않다. [1] malloc/free의 호출 횟수는 상황에 따라 매우 커질 수 있다. 내가 확인해본 결과 인터넷 익스플러로에서 페이지를 몇번만 열고 닫아도 수백만번이 호출된다. 구글 피카사의 경우에는 수천만번이 호출된다. 그 만큼 malloc/free 함수는 컴퓨터 프로그램의 핵심 중에 핵심이라 할 수 있다. 그래서 그 속도와 메모리 관리가 중요하고 지금까지는 속도 및 적은 메모리 낭비를 위해 위와 같은 방법이 이용되고 있는 것이다. 그러나 모든 이를 서로 믿을 수 있었던 시절에는 모두가 행복하였으나, 더 이상 세상은 그렇게 평온하지가 못하다. 수 많은 해커/크래커들이 이런 점을 악용해서 마구 나쁜 짓을 하는 것이다. 그 방법은 이러하다. 주어진 크기보다 데이터를 넘치게 써서 meta-data를 조작하는 것이다. 그래서 이른바 forward consolidation와 backward consolidation이라는 방법을 이용하여 제어권을 탈취하는 것이다! 간단하게 개요를 설명하자면 meta-data에는 prev/next free node에 대한 정보가 있는데 이것을 조작하는 것이다. 그런 뒤 뒤의 노드가 free가 될 때 무언가 잘못된 일이 벌어지게 되고 재앙이 닥치는 것이다. 언제 기회가 있으면 이 부분에 대해서 자세히 써보도록 하겠다. (사실 나도 아직 잘 이해는 못 하고 있다.) 대표적인 예로 Code Red Worm이 이러한 heap overflow를 악용한 것이다. 이런 예는 수도 없이 많다. 여러분의 윈도우가 귀찮게 보안 업데이트를 해야한다고 알리면 바로 이러한 문제를 고치기 위해서라는 것으로 이해하면 될 것이다. 아래와 같은 다이얼로그 박스 같은 것 말이다: ![]() 그런데 왜 이런 문제가 일어날까? 그건 지금까지 수 많은 프로그래머들이 이러한 공격을 감안하지 않고 프로그램을 짜왔기 때문이다. 대표적인 경우로 strcpy를 보면, 이 함수는 char* 형태의 인자 두개를 받는다. 그러나 이 char*의 길이를 체크하지 않기 때문에 악의적인 스트링 값을 준다면 주어진 공간보다 더 많이 써서 overflow가 일어날 수 있는 것이다. 최근 MSVC 컴파일러는 strcpy를 그대로 쓸 경우 보안 경고를 하고 있다. 실제로 2002년 리눅스 아파치 웹서버에서 일어난 Linux/Slapper worm 공격은 OpenSSL 패키지의 취약성을 노린 것이다. 클라이언트 키를 받아서 저장하는 버퍼가 8바이트인데 해커가 이 보다 더 많은 데이터를 악의적으로 보내어 내부 자료구조를 고쳐 쉘 코드를 수행하게끔 악용하는 것이다. [2]
최근 등록된 덧글
개발자 입장에서의 수많은 ..
by Jiyoon at 02/04 저도 아들 돌잔치때 돌잡이 .. by 박상욱 at 01/18 미국 대학원 원서 작성중에 p.. by 태클사이야 at 01/13 TO: 박PD 로그인 하지 않아.. by 박응용 at 01/10 http://gigglehd.com/zbx.. by dhunter at 12/28 우와.. 좋네요. 태반이 .. by 윤광배 at 12/17 항상 좋은 글 잘 보고 있습니.. by y2k at 11/23 글이 좋아서 제 블로그에 담.. by 쏭섭 at 11/23 최근 등록된 트랙백
메뉴릿
이글루 파인더
|