티스토리 뷰























윈도우 버퍼 오버플로우 익스플로잇 개발 - 1  
 
 
지난 3월 발견된 ntdll.dll의 버퍼 오버플로우는 스택 기반 버퍼 오버플로우의 한 사례를 보여주는 보안 버그였다. 이번 컬럼에서는 ntdll.dll 사례를 바탕으로 윈도우 환경에서 어떤 방식으로 버퍼 오버플로우가 일어나는지 그 원리와 작동 방식을 살펴보면서 고질적인 버퍼 오버플로우를 막을 수 있는 방법에 대해 잠시 생각할 수 있는 시간을 마련해 보았다.  
 





최 근 보안에 대한 관심이 높아짐에 따라 TV와 신문에는 보안 전문가를 자처하는 많은 사람이 나와 작금의 허술한 보안에 대해 실상을 폭로한다. 그러나 그 속내를 들여다보면 회사 광고나 자사 제품 광고를 위한 것인 경우가 많다. 이른바 ‘보안’은 하나의 ‘상품’에 불과해진 것이다. 많은 이들에게 보안은 아주 어렵고도 까다로운 분야이고 이해하기 힘든 용어들이 쏟아져 나오는 분야일 것이다.
보안과 뗄 수 없는 행위가 바로 ‘해킹’이다. 해킹은 그 뜻을 이해하기도 힘들지만 구체적으로 어떤 행위인지 알기도 힘들다. 그래서 해킹이라는 의미 자체가 남들이 이해하기 힘든 행동을 뜻하기도 하며, 남들이 하지 않는 아주 특수한 작업을 하는 것 자체를 해킹이라고 부르기도 한다. 따라서 ‘해커’는 평범한 사람과는 다른 괴짜이고 특별한 사람일 것이라고 생각하기 쉽다.
이렇게 보안과 해킹이 어렵고 특별해 보이고 일반인과 거리가 멀어 보이는 것 자체가 사실은 가장 큰 문제가 아닐 수 없다. 이러한 선입견의 결과로 일반인들은 보안에 대해서는 깊게 파고들기를 주저하게 된다. 전산인들조차도 보안과 해킹에 대해서는 아주 특수한 분야로 단정하고 미리 관심을 기울이지 않기 마련이다. 하지만 조금만 사고를 전환해 보면 보안이나 해킹과 같은 것들은 일종의 ‘게임’이나 ‘스포츠’가 될 수도 있다. 특히나 해킹은 아주 흥미진진한 스포츠다.
필자는 스포츠를 보면서 해킹과 아주 비슷한 점을 많이 발견했다. 둘 이상이 서로 경쟁하는 스포츠에서는 우선 이론적인 뒷받침이 있어야 한다. 그리고 이론적인 뒷받침 뒤에는 항상 정확한 ‘구현’이 필요하다. 이러한 구현은 선수들의 훈련의 결과에 의해 결정된다. 이론도 중요하지만 그때그때 상황을 어떻게 해결하느냐가 중요한 문제다.
보안과 해킹도 마찬가지다. 둘 다 이론적인 뒷받침이 아주 중요하다. 보안은 물론 해킹 분야에서는 그 이론적인 뒷받침을 해주는 수많은 문서가 존재하며 하루에도 엄청나게 많은 정보가 쏟아진다. 하지만 이러한 정보의 보유 여부보다는 그 정보를 관리자나 해커가 얼마나 잘 훈련해 소화하느냐가 더 중요한 경우가 많다.
이러한 관리자와 해커는 서로 경쟁 관계다. 관리자가 조금이라도 밀리게 되면 사이트가 뚫리는 것이고, 해커가 밀리면 사이트를 지킬 수 있는 것이다. 둘 사이의 경쟁은 시간에 따라서 서로 기술을 발전시키며 앞서거니 뒤서거니 하며 발전한다. 그리고 가장 중요한 점은 서로가 상대편을 제대로 알지 못하면 이 경기에서 이길 수 없다는 것이다. 따라서 해커들은 보안 기술을 공부하고 보안 관리자들은 해킹 기술을 공부하게 되어 결국에는 서로 공부하는 분야가 같아진다. 이론적인 배경과 관심 분야가 서로 일치할 때 경기 결과는 오로지 각 경기에 임하는 선수들의 능력에 의존하게 된다. 그만큼 보안과 해킹은 아직은 수공업 단계의 기술로서 인간 자신이 중요한 분야다.
많은 사람이 해킹은 편법으로만 이루어진 아주 하급적이거나 주변적인 기술 정도일 것이고, 해커들은 그러한 주변 기술을 다루는 주변적인 인물일 것이라고 오해를 하는 경우가 많다. 물론 어느 분야와 마찬가지로 그러한 사이비 선수들이 없는 것은 아니다. 하지만 해커 중에도 일반 전산 분야에서도 우수한 성적을 내놓을 수 있는 능력을 갖춘 선수는 얼마든지 있다.
또한 해킹이라는 분야 자체가 해당 분야에 대한 기본 지식이 없으면 사실 파고들 수 없는 분야이므로 해킹에 대해 제대로 된 선수가 되기 어려운 것이 사실이다. 이것이 바로 사이비 해커들이 양산되는 원인이기도 하다. 해커가 대중 매체에 의해 사이버 세계의 정복자 내지는 신으로 그 의미가 와전되면서 순진한 청소년들의 마음에 해커가 되고 싶은 열정을 심어 놓았다. 하지만 그러한 대중 매체는 해커의 윤리나 기술은 가르치지 않기 때문에 많은 사람이 사이버 세계를 정복하고 싶은 마음만으로 하급 기술 내지는 쓰레기 기술을 수집하면서 남들을 괴롭히는 ‘사이버 산적’ 정도의 인물이 되고 있다. 해커의 어원과 정확한 의미에서 볼 때 그러한 사람들을 해커라고 부를 수는 없다. 그러한 사람들은 ‘크래커’나 ‘스크립트 키디’와 같은 용어로 표현하는 것이 적절할 것이다.
스포츠라는 단어가 생겨난 것은 13세기경으로 ‘엄하고 가혹한 작업이나 노동에서 잠시 벗어나 기분을 전환한다’는 뜻으로 쓰였다. 근래에 들어와 스포츠 자체가 완벽한 상품이긴 하지만 초기 스포츠는 레크리에이션의 순수한 의미를 지니고 있었다. 해킹도 점점 상품화가 되어 가고 있지만 초기의 순수한 정신으로 비추어 본다면, 일종의 ‘지적 스포츠’라고 볼 수 있다.
우수한 선수가 되기 위해 기본기가 철저해야 하듯이 해커가 되기 위해서는 컴퓨터 과학에 대한 기본기는 갖추고 있어야 한다. 그리고 부단한 훈련과 이론적인 학습 또한 중요하다. 뛰어난 해커는 개인의 천재성보다는 훈련의 결과물일 경우가 많다.
일단 자신이 전산학에 대해 기본기가 되어 있다고 생각한다면 이번 컬럼부터 제시할 문제들을 흥미를 가지고 도전해 보기 바란다. 첫 번째로 제시할 문제는 2003년 3월에 발견된 ntdll.dll의 버퍼 오버플로우 보안 문제다. 일단 버퍼 오버플로우에 대해 간단히 개념을 정리한 후 윈도우 버퍼 오버플로우의 특징과 익스플로잇(exploit) 방법에 대해 ntdll.dll의 익스플로잇을 예로 하여 알아보기로 한다.
아마 많은 독자들이 이 내용을 이해하기 힘들 것이다. 하지만 여기에 나오는 내용은 운영체제의 메모리 관리 방법과 윈도우 시스템의 특성, 어셈블리 언어, Perl에 대해 알고 있다면 모두 이해할 수 있는 것들이다. 먼저 이러한 필요조건들을 충족시킨 후 여기에 제시한 문제들을 상상력을 최대한 발휘해 이해해 보기 바란다.

버퍼 오버플로우란
인터넷 용어를 정리한 자곤(jargon)을 보면 버퍼 오버플로우에 대해 다음과 같이 기술하고 있다.

버 퍼에 가질 수 있는 것보다 많은 데이터를 넣었을 경우에 발생하는 것. 이 문제는 루트 권한으로 실행되는 프로그램에서 원하는 명령을 실행하기 위해 크래커들이 주로 사용한다. 이것은 생산하는 프로세스와 소비하는 프로세스 사이의 처리율이 달라서 생기거나 버퍼가 모든 데이터를 수용하기에는 너무 작아서일 수도 있다. 예를 들어 한 번에 한 줄씩 처리하는 텍스트 처리 프로그램에서 짧은 버퍼는 긴 줄의 입력을 다 처리하지 못하고 그 나머지를 버리게 된다. 이에 대한 좋은 방어책은 각 문자에 대해 오버플로우를 체크하는 것이다. 그리고 버퍼가 가득 찼을 경우에 데이터를 더 이상 받아들이지 않는 것이다. 이 용어는 비유적인 의미로도 사용된다. “언제 만나기로 했지? 내 버퍼가 오버플로우됐나 보군.” 또는 “만약 내가 저 전화를 받으면 나의 버퍼가 오버플로우될 거야.”(출처 : http://www.catb.org/jargon/html/entry/buffer-overflow.html)

스택 기반 버퍼 오버플로우
스 택 기반 버퍼 오버플로우는 한마디로 버퍼가 넘쳐 난다는 것이다. 버퍼가 넘쳐 나면 프로그램이 엉망이 된다. 엉망이라는 것은 일반적으로 세그먼테이션 폴트(segmentation fault)와 비슷한 에러 메시지를 남기고 프로그램이 다운되는 현상을 불러일으킨다. 하지만 이 엉망인 상황을 제대로 제어할 수만 있다면 엄청난 일이 벌어지게 된다. 스택 기반 버퍼 오버플로우는 앨렙 원(Aleph One)이 쓴 프랙(Phrack) 매거진 49호 열네 번째 파일 ‘Smashing The Stack For Fun And Profit’에서 대중화했다. 자곤을 보면 ‘smash the stack’에 대해 다음과 같이 기술하고 있다.

많 은 C로 짜여진 코드에서 어떠한 루틴(routine)에서 auto type으로 정의된 배열의 끝을 지나서 데이터를 써 넣음으로써 실행할 번지가 저장된 스택을 변경할 수 있다. 이러한 역할을 하는 코드를 smash the stack이라고 한다. 이러한 코드는 이 루틴에서 리턴하면서 이 루틴을 호출한 루틴이 아닌 특정한 주소로 점프(jmp)할 수 있게 한다. 이러한 현상은 데이터와 관련된 최악의 버그를 양산했다. 변종으로는 trash the stack, scribble the stack, mangle the stack이 있다. mung the stack이라는 용어는 사용하지 않는데 이는 의도적으로 한 것이 아니기 때문이다(출처 : http://www. catb.org/jargon/html/entry/smash-the-stack.html).


춮처: http://www.imaso.co.kr/?doc=bbs/gnuboard.php&bo_table=article&wr_id=43&page=8