1

Similar documents
Microsoft PowerPoint - chap01-C언어개요.pptx

Windows Server 2012

ISP and CodeVisionAVR C Compiler.hwp

Microsoft Word - windows server 2003 수동설치_non pro support_.doc

Microsoft Word - [Windows Hook] 6.HideProcess.doc

Microsoft Word - ntasFrameBuilderInstallGuide2.5.doc

Microsoft PowerPoint - chap02-C프로그램시작하기.pptx

목차 윈도우드라이버 1. 매뉴얼안내 운영체제 (OS) 환경 윈도우드라이버준비 윈도우드라이버설치 Windows XP/Server 2003 에서설치 Serial 또는 Parallel 포트의경우.

Windows 8에서 BioStar 1 설치하기

<B1E2BCFAB9AEBCAD28C0CCB5BFBCF6295F F6F6B696E672E687770>

WinDbg 사용법

WinDBG 실무

Chapter #01 Subject

Mango-IMX6Q mfgtool을 이용한 이미지 Write하기

<4D F736F F D D31312D30312D53572D30312DBBE7BFEBC0DABCB3B8EDBCAD5FBFDCBACEB9E8C6F7BFEB2E646F63>

임베디드시스템설계강의자료 6 system call 2/2 (2014 년도 1 학기 ) 김영진 아주대학교전자공학과

Studuino소프트웨어 설치

untitled

MF5900 Series MF Driver Installation Guide

Microsoft Word - src.doc

Microsoft Word - Armjtag_문서1.doc

iii. Design Tab 을 Click 하여 WindowBuilder 가자동으로생성한 GUI 프로그래밍환경을확인한다.

비디오 / 그래픽 아답터 네트워크 만약에 ArcGolbe를 사용하는 경우, 추가적인 디스크 공간 필요. ArcGlobe는 캐시파일을 생성하여 사용 24 비트 그래픽 가속기 Oepn GL 2.0 이상을 지원하는 비디오카드 최소 64 MB 이고 256 MB 이상을 메모리

MF Driver Installation Guide

<C1A4C8B8BFF8C6F2B0A15FB1E2BCFAB9AEBCAD5F444B4F4D5FC0CCB5BFBCF62E687770>

Install stm32cubemx and st-link utility

Microsoft PowerPoint Android-SDK설치.HelloAndroid(1.0h).pptx

슬라이드 1

WinDBG 실무

<B1E2BCFAB9AEBCAD28C0CCB5BFBCF6295F F6F6B696E672E687770>

SSDT Hooking

SIGIL 완벽입문

6. 설치가시작되는동안 USB 드라이버가자동으로로드됩니다. USB 드라이버가성공적으로로드되면 Setup is starting( 설치가시작되는중 )... 화면이표시됩니다. 7. 화면지침에따라 Windows 7 설치를완료합니다. 방법 2: 수정된 Windows 7 ISO

커알못의 커널 탐방기 이 세상의 모든 커알못을 위해서

Microsoft PowerPoint - 02_Linux_Fedora_Core_8_Vmware_Installation [호환 모드]

아이콘의 정의 본 사용자 설명서에서는 다음 아이콘을 사용합니다. 참고 참고는 발생할 수 있는 상황에 대처하는 방법을 알려 주거나 다른 기능과 함께 작동하는 방법에 대한 요령을 제공합니다. 상표 Brother 로고는 Brother Industries, Ltd.의 등록 상

System Recovery 사용자 매뉴얼

Chapter ...

목 차 1. 드라이버 설치 설치환경 드라이버 설치 시 주의사항 USB 드라이버 파일 Windows XP에서 설치 Windows Vista / Windows 7에서 설치 Windows

IRISCard Anywhere 5

<4D F736F F F696E74202D20BBB7BBB7C7D15F FBEDFB0A3B1B3C0B05FC1A638C0CFC2F72E BC8A3C8AF20B8F0B5E55D>

KEY 디바이스 드라이버

다른 JSP 페이지호출 forward() 메서드 - 하나의 JSP 페이지실행이끝나고다른 JSP 페이지를호출할때사용한다. 예 ) <% RequestDispatcher dispatcher = request.getrequestdispatcher(" 실행할페이지.jsp");

PowerPoint 프레젠테이션

슬라이드 1

지난시간에... 우리는 kernel compile을위하여 cross compile 환경을구축했음. UBUNTU 12.04에서 arm-2009q3를사용하여 간단한 c source를빌드함. 한번은 intel CPU를위한 gcc로, 한번은 ARM CPU를위한 gcc로. AR

<4D F736F F F696E74202D20B8B6C0CCC5A9B7CEC7C1B7CEBCBCBCAD202839C1D6C2F7207E203135C1D6C2F >

네이버블로그 :: 포스트내용 Print VMw are 에서 Linux 설치하기 (Centos 6.3, 리눅스 ) Linux 2013/02/23 22:52 /carrena/ VMware 에서 l

NTD36HD Manual

SSDT Hooking

금오공대 컴퓨터공학전공 강의자료

PowerPoint Template

리눅스설치가이드 3. 3Rabbitz Book 을리눅스에서설치하기위한절차는다음과같습니다. 설치에대한예시는우분투서버 기준으로진행됩니다. 1. Java Development Kit (JDK) 또는 Java Runtime Environment (JRE) 를설치합니다. 2.

<4D F736F F F696E74202D20C1A632C0E520C7C1B7CEB1D7B7A5B0B3B9DFB0FAC1A4>

RealDSP UT 프로그램 메뉴얼

*Revision History 날짜 내용 최초작성 Tel Fax [2] page

슬라이드 1

Microsoft PowerPoint - additional01.ppt [호환 모드]

Microsoft PowerPoint - chap-02.pptx

슬라이드 제목 없음

RHEV 2.2 인증서 만료 확인 및 갱신

슬라이드 1

[ 마이크로프로세서 1] 2 주차 3 차시. 포인터와구조체 2 주차 3 차시포인터와구조체 학습목표 1. C 언어에서가장어려운포인터와구조체를설명할수있다. 2. Call By Value 와 Call By Reference 를구분할수있다. 학습내용 1 : 함수 (Functi

CODESYS 런타임 설치과정

API 매뉴얼

Title Here

M C S 심 층 분 석 1 루트킷을이용하는악성코드 안철수연구소주임연구원 고흥환 1. 개요 루트킷설치는 SunOS, Unix, Linux 등의루트권한을획득하기위한해커들의가장중요한목적이기도하다. 루트킷 이라는이름의유래도바로이러한루트액세스를위한공격에서유래된것이다. 루트킷의

API 매뉴얼

<4D F736F F F696E74202D20B8AEB4AABDBA20BFC0B7F920C3B3B8AEC7CFB1E22E BC8A3C8AF20B8F0B5E55D>

Microsoft PowerPoint - 권장 사양

악성코드분석보고서 (Lucci.exe) 작성자 : 김진태 1

Microsoft PowerPoint - chap05-제어문.pptx

<41736D6C6F D20B9AEBCADBEE7BDC42E687770>

임베디드시스템설계강의자료 6 system call 1/2 (2014 년도 1 학기 ) 김영진 아주대학교전자공학과

vRealize Automation용 VMware Remote Console - VMware

윈도 모바일 6.1을 OS로 사용하는 스마트폰(옴니아2 등)에서의 Tcl/Tk의 사용

경우 1) 80GB( 원본 ) => 2TB( 복사본 ), 원본 80GB 는 MBR 로디스크초기화하고 NTFS 로포맷한경우 복사본 HDD 도 MBR 로디스크초기화되고 80GB 만큼포맷되고나머지영역 (80GB~ 나머지부분 ) 은할당되지않음 으로나온다. A. Window P

tiawPlot ac 사용방법

SQL Developer Connect to TimesTen 유니원아이앤씨 DB 기술지원팀 2010 년 07 월 28 일 문서정보 프로젝트명 SQL Developer Connect to TimesTen 서브시스템명 버전 1.0 문서명 작성일 작성자

MF3010 MF Driver Installation Guide

1. 자바프로그램기초 및개발환경 2 장 & 3 장. 자바개발도구 충남대학교 컴퓨터공학과

PowerPoint 프레젠테이션

Oracle VM VirtualBox 설치 VirtualBox에서 가상머신 설치 가상머신에 Ubuntu 설치

PowerPoint 프레젠테이션

Microsoft PowerPoint SDK설치.HelloAndroid(1.5h).pptx

Poison null byte Excuse the ads! We need some help to keep our site up. List 1 Conditions 2 Exploit plan 2.1 chunksize(p)!= prev_size (next_chunk(p) 3

Xcovery 사용설명서

이도경, 최덕재 Dokyeong Lee, Deokjai Choi 1. 서론

<4D F736F F F696E74202D203137C0E55FBFACBDC0B9AEC1A6BCD6B7E7BCC72E707074>

1. Windows 설치 (Client 설치 ) 원하는위치에다운받은발송클라이언트압축파일을해제합니다. Step 2. /conf/config.xml 파일수정 conf 폴더에서 config.xml 파일을텍스트에디터를이용하여 Open 합니다. config.xml 파일에서, 아

Microsoft Word - building the win32 shellcode 01.doc

표준프레임워크 Nexus 및 CI 환경구축가이드 Version 3.8 Page 1

PowerPoint 프레젠테이션

서현수

Microsoft Word - 3부A windows 환경 IVF + visual studio.doc

SSDT(System Service Descriptor Table) Hooking Written by 백구 Contack Me : 목차 가. 이문서의목적... 2 나. 유저모드와커널모드... 2 다. Windows API 흐름..

Microsoft Word - PLC제어응용-2차시.doc

ActFax 4.31 Local Privilege Escalation Exploit

server name>/arcgis/rest/services server name>/<web adaptor name>/rest/services ArcGIS 10.1 for Server System requirements - 지

ADP-2480

Transcription:

초보자를위한 Kernel based windows rootkit -1 부 - By Beist Security Study Group (http://beist.org) 요약 : 이문서는윈도우 2000/XP/2003 환경에서의커널루트킷에대한개요와윈도우와하드웨어간의커넥션에대해다룹니다. 그리고실습을위해커널레벨에서 CR0 레지스터를변경하여 SSDT 의 read-only 속성을 write 속성으로바꾸는프로그램을디바이스드라이버를이용해서작성할것입니다. 이글을읽는독자가유저레벨에서의윈도우시스템프로그래밍경험이있다는전제하에진행하겠습니다.

1. 소개 Rootkit? 루트킷은해커가특정시스템을해킹한이후에시스템의제어권을획득할목적으로설치하는악성프로그램을말합니다. 루트킷은유저레벨에서구현될수도있고커널레벨에서구현될수도있는데본강좌에서는커널레벨의루트킷에대해서다루겠습니다. 해커는루트킷을설치함으로써하드웨어의제어권을쥐고있는소프트웨어를자신의목적에맞게조작하여, 시스템을자신이원하는방향으로조작할수있습니다. 루트킷의성능을좌우하는요소는여러가지가있지만대표적인요소를꼽자면, 1) 원하는목적대로제어권을획득할수있는가? 2) detect 되지않게작성할수있는가? 이두가지를꼽을수있습니다. 위조건을만족시키기위한가장좋은방법은루트킷을커널레벨에서작동하도록제작하는것입니다. 즉, 운영체제가작동하는커널모드에서루트킷을작성한다면보다운영체제에가까이접근하여운영체제만이가질수있는특권을루트킷도누릴수있다는의미가됩니다. 그외, 커널레벨에서작동할때의장점을더꼽아보겠습니다. 운영체제의코드나데이터를변경시킬수있게됩니다. 이것을통해운영체제의제어흐름을변경시켜서원하는목적을달성할수있습니다. 가장커다란결과로는후킹을 system wide 하게적용시킬수있게됩니다. 이것은실제로윈도우커널후킹기법인 Native API Hooking 과 IDT Hooking 을가능하게합니다. 또한강력한기법중하나인 DKOM(Direct Kernel Object Manipulation) 도가능하게합니다. 커널레벨에서동작하는다른모든프로그램의코드나데이터도변경시킬수있게됩니다. 이러한점을악용한다면대부분의보안프로그램을무력화시킬수있습니다. 보안프로그램은시스템에대한강력한권한을얻기위하여, 커널레벨기반으로작성하게됩니다. 보안프로그램들이커널레벨에서작동되어도, 루트킷도역시같은커널레벨에서실행되기때문에해커가단순한커널해킹기법만으로도시스템코드를조작해서제어권을루트킷에게넘어오게할수있습니다. 그결과보안프로그램을무력화시키고, 보다조작을가하면보안프로그램을자신이원하는방향으로실행할수있습니다. 마지막으로, 루트킷을 detect 하기어렵게만듭니다. 커널레벨은운영체제가작동하는모드인만큼사용자나유저레벨프로그램이접근하기어려운영역입니다. 보안프로그램이커널레벨에서작동한다고하더라도위에서말했던것처럼루트킷이그보안프로그램을무력화시키는코드를작성해두었다면 detect 되지않습니다. 루트킷과보안프로그램은커널레벨에서작동하는만큼시스템에대한권한차이는없기때문에, 누가먼저서로를감지하고무력화시키느냐에따라승패가갈리게됩니다. 2. Windows Internals 윈도우커널루트킷의공격기법을이해하고, 루트킷을작성하려면윈도우의내부구조에대한이해가요구됩니다. 프로세스와스레드, 스케쥴링, API 의호출과정, 페이징과정, ring 0 와 ring 3, 그밖의윈도우내부구조들을이해해야합니다. 하지만이내용만으로도상당히방대하므로본문서에서는 API 호출과정에대한내용과 ring 0 와 ring 3 에관한내용, 그리고몇가지중요한윈도우내부구조만을서술하겠습니다. 자세한내용은다른책들을참고해보시기바랍니다. API 의호출과정을분석해보면윈도우내부구조의많은개념들을접할수있습니다.

Kernel32.dll, Ntdll.dll 등과같은중요한시스템모듈들의역할 유저모드와커널모드 System Call 의개념 Native API, SSDT(System Service Descriptor Table) SSDT Hooking 기법에관한이해 이개념들을 API 호출과정을분석하면서살펴보겠습니다. 2-1. 커널모드와유저모드 API 호출과정을커널모드까지진입하여알아보려면먼저커널모드가무엇인지를알아야합니다. CPU 에내릴수있는명령에도각각권한이있습니다. 이권한이높을수록운영체제에깊이접근할수있습니다. 내릴수있는명령들에권한을부여하여구분하지않았다면갖가지심각한악성프로그램들이특별한제한없이활개칠것입니다. 이런상황을방지하기위해서 CPU 가내릴수있는명령에권한을부여했는데, 이러한프로세서디자인을 Multiple Ring 이라고하고, 간단한구조는아래그림과같습니다. 그림 1. Multiple Ring Ring0~3 까지총 4 가지권한이있지만 Windows 에서는 Ring 0 와 Ring 3 만을사용합니다. Ring 3 는유저모드라고하고, Ring 0 는커널모드라고도합니다. 그림 1 에서보면맨바깥쪽원의권한이 Ring 3 인유저모드입니다. 이곳은유저레벨프로그램의코드가실행되는곳이며, 특별한명령 (int 2e, SYSENTER) 을통해서만 Ring 0 권한에진입할수있습니다. 유저모드에서는하드웨어에직접접근하거나커널의가상메모리, 그밖의중요한레지스터나데이터에접근하는것이제한되어있습니다. 반면에커널모드에서는직접하드웨어컨트롤러에명령을보내거나운영체제의코드, 기타시스템에중요한레지스터에도접근이가능합니다. 특히유저모드에서접근이불가한 0x8000000 이상인커널의가상메모리공간에도접근이가능합니다. 2-2. 유저모드에서의 API 호출과정

이제본격적으로 API 함수의호출과정을분석해보겠습니다. 여기서는 CreateFile() 함수를호출했을때를가정하고진행합니다. 그림 2. 유저레벨에서의 CreateFile() 함수호출과정 1. 일반응용프로그램에서 CreateFile() 함수를호출할때, 첫번째인자로파일이름에해당하는문자열을전달합니다. 파일이름을 ASCII 형식으로쓰는지 UNICODE 형식으로쓰는지에따라 CreateFileA() 함수또는 CreateFileW() 함수를호출하게됩니다. UNICODE 형식으로파일이름을전달하는경우에는 CreateFileA() 함수를거치지않습니다. ASCII 형식으로파일이름을전달할경우엔, CreateFileA() 함수에서 ASCII 문자열을 UNICODE 형식을위한 Wide Character 로변환시키고나서 CreateFileW() 함수를호출합니다. 이렇게 xxxxa() -> xxxxw() 호출되는방식은많은 Win32 API 함수에서쓰이고있습니다. 2. CreateFileW() 함수로흐름이건너옵니다. CreateFileW() 함수는내부적으로여러가지복잡한과정을거치게되는데, 중요한내용은아니기때문에생략하겠습니다. 내부의복잡한과정을거치고나면, CALL imp NtCreateFile 이라는코드가등장하는데, 이코드는 ntdll.dll 의 imp NtCreateFile() 함수를호출합니다. 여기서 ntdll.dll 은 kernel32.dll 과커널사이의일종의중개역할을하는모듈로서, 주로유저모드와커널모드로의전환을수행하는역할을담당합니다. 이코드를실행하면이제흐름은 imp NtCreateFile() 함수로이동합니다. 3. ntdll.dll 의 imp NtCreateFile() 로흐름이넘어왔습니다. 그림을보게되면첫번째코드는 mov EAX, 0x00000025 인데, 이것은 EAX 레지스터에 0x25 를집어넣겠다는코드입니다. 0x25 는커널의약 300 개의 Native API 함수중, 어떤함수를호출할지정하는인덱스가되어서, 나중에커널모드로제어가넘어갔을때참조하게됩니다. Native API 는반드시알아야하는개념인데, 강력한커널후킹기법중하나가이 Native API 를후킹하는것이기때문입니다. Native API 를간단히정의하면, Win32 API 혹은이와비슷한다른서브시스템이커널단에서의도움이필요한경우에호출하는커널의특별한함수집합을말합니다.

커널단에서도움을주는개념이기때문에 Native API 함수를 System Service Dispatcher 라고도부릅니다. 좀더구체적인이해를위해 Win32 API 함수와이에대응되는 Native API 를몇개나열해보겠습니다. CreateFile()->NtCreateFile(), ReadFile()->NtReadFile(), CreateProcess()->NtCreateProcess() OpenProcessToken()->NtOpenProcessToken() WriteProcessMemory()->NtWriteVirtualMemory() 위를보시면알수있듯이중요한시스템 API 함수들이 Native API 함수를거치게됩니다. 이러한 Native API 를후킹한다면, 아래그림처럼유저레벨에서의모든프로세스에적용이되면서결국은전역적으로후킹이됩니다. 예를들어서 NtCreateProcess() 를후킹한다면, 모든프로세스의생성을제어할수있고, NtWriteVirtualMemory() 를후킹하면, 모든프로세스의메모리 writing 시도를제어할수있으므로, 특정프로세스메모리공간을 write 하지못하게만들수도있습니다. 실제로몇몇보안프로그램은이함수를후킹해서프로세스메모리공간을보호하기도합니다. 그림 3. 각각의프로세스의 CreateFile() 호출은한곳의 NtCreateFile() 로이동된다. 이제두번째코드를건너뛰고, 세번째코드를살펴보면 int 0x2E 명령이보입니다. 이코드는유저모드에서커널모드로의제어이행을수행하는코드로써, 소프트웨어인터럽트를발생시키고, 유저스택을커널스택으로변경시킵니다. 그리고 int 0x2E 의인터럽트핸들러인 KiSystemService() 를실행시킵니다. 여기서 int 2e 명령어는 Windows 2000 까지만커널로의이행을수행하는게이트가됩니다. 펜티엄 2 이상의사양을갖춘 XP 이후에서부터는 int 2e 대신 SYSENTER 를사용합니다. 동일한기능을수행하지만 SYSENTER 는커널로의이행을좀더빠르게수행하도록만들어졌고, int 2e 를게이트로쓰는것은이젠구식의방법이되어버렸습니다. SYSENTER 를통해커널모드로이동했다면, KiSystemService() 를거치기전에 KiFastCallEntry() 를거치게됩니다. 이것에대해자세한사항은다른문서들을참고하시길바랍니다.

2-3. 커널모드에서의 API 호출과정 이제커널모드로넘어와서, API 호출과정을분석해보겠습니다. 전체흐름은아래그림과같습니다. 그림 4. 커널에서의 API 호출과정 1. 앞에서언급했지만유저레벨에서 SYSENTER 를통해커널모드로진입했을경우에는 KiFastCallEntry() 를거치고, int 2e 로진입했을경우에는 KiFastCallEntry() 를거치치않고바로 KiSystemService() 로넘어가게됩니다. 2. KiSystemService() 에서하는가장중요한작업은 SSDT 의주소값을얻어오고어플리케이션에서호출한 API 에맞는 Native API 의주소를찾아내서호출하는것입니다. KiSystemService() 함수에서는먼저 SSDT 를찾기위해서 KeServiceDescriptorTable 에접근합니다. KeServiceDescriptorTable 의구성요소는 4 가지로이루어져있습니다. 여기서는두번째요소를제외하고나머지를살펴보겠습니다. 첫번째요소는 SSDT(KiServiceTable) 의주소를담고있고, 세번째요소인 NumberOfService 는뜻그대로풀어쓰면서비스의개수가됩니다. 여기서말하는서비스는 Native API 를지칭하기때문에결국세번째요소는 Native API 의총개수를말합니다. 그림에나온 11C 는 Windows XP SP2 에서의실제값으로, 십진수로는 284 개가됩니다. 네번째요소는 KiArgumentTable 의주소값을담고있습니다. KiArgumentTable 은 SSPT(System Service Parameter Table) 라고도불리는데, 이들각각은 SSDT 의 Native API 와 1:1 대응을합니다. 이것들은대응되는 Native API 함수의파라미터총크기를바이트단위로써나타냅니다. 3. Native API 를찾기위해서, Ntdll.dll 에서 EAX 레지스터에인덱스의형태로값을저장한다는것을이전에살펴봤었습니다. 이제이것과 SSDT 주소값을이용해서 Native API 함수의엔트리주소값을얻어오게됩니다. SSDT 주소 (KiServiceTable)+[EAX 인덱스 *4] 를한다면아주간단하게 Native API 함수주소를얻어올수있는데, 이것은실제로 KiSystemService() 가하는코드와도같습니다.

4. 이제원하는 Native API 함수로진입하게됩니다. 만약어플리케이션에서 CreateFile() 함수로 USB 메모리디스크에 aaa.txt 파일을생성한다고치면, 시스템게이트를거쳐커널의 NtCreateFile() 함수로진입합니다. NtCreateFile() 함수에서는커널의구성요소인 I/O Manager 를통해디스크드라이버와 USB 관련드라이버들을거치면서일련의작업을진행합니다. 이과정은문서와는맞지않는내용이기때문에기술하지않겠습니다. 3. 간단한루트킷제작 커널기반루트킷은 Windows 에서디바이스드라이버의형태로동작하기때문에루트킷을작성하려면, WDM 디바이스드라이버를작성할수있어야합니다. WDM 을이용하지않아도좋지만, Windows 2000/XP/2003 모두호환성있도록작성하려면 WDM 을이용해야합니다. (Vista 까지호환성을유지하려면 WDF 라는새로운드라이버개발환경으로도작성할수있어야합니다.) WDM 드라이버의빌드환경과디버깅환경을구축하는방법을간단히설명하고, 그다음간단한 WDM 드라이버제작을해보겠습니다. 그리고작성된드라이버의기본틀에덧붙여서 SSDT Hooking 을가능하게하도록 CR0 레지스터를수정하는코드를작성해보겠습니다. 3-1. 빌드환경구축하기 우선빌드환경을구축하기전에고려해야할사항이있습니다. 사용하고있는 CPU 가 32 비트인가 64 비트인가? 단일프로세서환경인가멀티프로세서환경인가? 등을체크해야합니다. 이문서에서는 IA-32 기반과단일프로세서환경에서프로그래밍을한다고가정합니다. 64 비트의경우에는아직많이연구들이진행되지않았고, 멀티프로세서환경에서 CPU 레지스터의영향을받는루트킷의경우에는프로그래밍하기가약간까다로워지기때문에디바이스드라이버를처음접하는분들은제작하기어렵다고느끼실수있습니다. 이제본론으로들어가서빌드환경구축에대해살펴보겠습니다. WDM 디바이스드라이버를만들기위해서는우선 DDK 를구해야합니다. DDK 를구하기위해서는 Microsoft 홈페이지를참고하세요. (http://www.microsoft.com/ddk) DDK 를설치하셨다면, 프로그래밍환경과빌드환경을통합할지결정하셔야합니다. 통합하지않는다면직접빌드프롬프트에들어가서 build 명령어를통해드라이버를컴파일해야합니다. 반면프로그래밍환경과빌드환경을통합한다면상당히편리해지는데, 이것을구성하는방법은여러가지가있습니다. VC6 의환경설정을통해서 build 를기존의메뉴를통해사용할수도있고, 혹은 DriverStudio(Softice) 3.2 를설치하면같이설치되는간단한툴바를통해 VC6 에서버튼하나로빌드시킬수도있습니다. 저는주로후자의방법을사용하고있습니다. 여러가지환경이있으니자신이편하다고생각하는환경을구축하시길바랍니다. 3-2. 디버깅환경구축하기 디바이스드라이버프로그래밍은, 프로그램의규모가커질수록잠재적인버그들이너무나많아지고, 디버깅하기도유저레벨프로그램들에비해상당히까다롭습니다. 그때문에실무에서도다른프로그래밍분야보다안정성을높이는데많은시간과노력이소요됩니다. 이를위해서커널레벨에서의디버거사용법에대해서익숙해질필요가있습니다. 디바이스드라이버를디버깅할수있는커널디버거로는대표적으로 WinDbg 와 Softice 가있습니다. WinDbg 는 PC 2 대를연결해서디버깅하는구조로되어있는데하나는디버기 (debugee) 로다른

하나는디버거 (debugger) 로사용하게됩니다. 두 PC 를연결하기위해서시리얼케이블이나 1394 케이블이사용되는데, 시리얼케이블은속도가느리기때문에 Windows XP 이상의 OS 라면 1394 케이블을쓰는것이좋습니다. Vista 에서는 USB 2.0 디버깅전용케이블도지원된다고하지만아직까지는케이블을국내에서구할수없고약간비싸다는게단점입니다. WinDbg 의장점으로는 Microsoft 가내놓은커널디버거인만큼비교적안정적으로디버깅을할수있습니다. Softice 는커널디버깅을하기위해서후킹기법같은시스템에불안정적인방법을사용하게되지만, WinDbg 는 Microsoft 에서제공하는 API 를통해시스템에안정적인방법으로디버깅을하게됩니다. Softice 는로컬디버깅을할때많이사용됩니다. WinDbg 도 LiveKd 라는유틸을이용한다면보다쉽게로컬디버깅을사용할수있지만, 실제적인실시간디버깅이아니고단순히한순간의시스템덤프를이용한디버깅이기때문에드라이버디버깅은불가능하고그밖에제한사항이많이있으나간단히 Windows 의내부구조를둘러볼때쓰는용도라면유용합니다. WinDbg 는 Microsoft 홈페이지에서무료로다운로드받을수있지만 Softice 는상용프로그램입니다. Softice 는 64 비트운영체제디버깅을지원하지않고현재개발중단된상태이기때문에 WinDbg 를이용해서커널디버깅을시작하는것을추천합니다. WinDbg 나 Softice 의자세한사용법은홈페이지를참고하시기바랍니다. 3-3. 드라이버의기본틀 #include <ntddk.h>// 대부분의드라이버가반드시포함해야하는헤더파일. VOID OnUnload( IN PDRIVER_OBJECT DriverObject) { // 드라이버안에서할당했던모든것을해제한다. // OnUnload 가수행되고나면드라이버는메모리상에서제거된다. } NTSTATUS DriverEntry( IN PDRIVER_OBJECT thedriverobject, IN PUNICODE_STRING theregistrypath ) { // 드라이버의메인함수. // 이제부터함수안의모든코드는커널레벨에서수행된다. // 드라이버언로드함수의주소를등록시킨다. 가장기본적인 thedriverobject->driverunload 드라이버의구조는위와 = 같습니다 OnUnload;. } // DriverEntry 의수행이끝나면 STATUS_SUCCESS 를반환한다. return STATUS_SUCCESS; KBasic.c 위의주석에모든설명을달아놓았습니다. 기억해야할것은 DriverEntry() 함수에서드라이버가시작되고, Unload() 함수에서제거된다는것입니다. 이제위소스를빌드시켜보겠습니다. 빌드하기위해서는소스파일 (.c 파일 ) 뿐만아니라 MAKEFILE, SOURCE 라는파일도필요합니다. 먼저 MAKEFILE 파일의내부를살펴보도록하겠습니다.

# # DO NOT EDIT THIS FILE!!! Edit. sources. if you want to add a new source # file to this component. This file merely indirects to the real make file # that is shared by all the driver components of the Windows NT DDK #!INCLUDE $(NTMAKEENV) makefile.def MAKEFILE 위를보시면알수있듯이이파일을수정하지말고그냥이내용그대로 MAKEFILE 파일을작성해서소스파일과같은폴더에넣어두면됩니다. TARGETNAME=KBasic 그다음 SOURCE 파일의내부를살펴보겠습니다. TARGETPATH=OBJ TARGETTYPE=DRIVER SOURCES=KBasic.c SOURCE 각각의항목을살펴보면, TARGETNAME 은프로젝트의네임을뜻하고, TARGETPATH 는컴파일된파일들이위치할하위폴더를말하는데, 보통 OBJ 폴더를만듭니다. TARGETTYPE 는작성하는프로그램의성격을결정하는데여기서는 DRIVER 를씁니다. 그리고 SOURCES 는작성한소스파일의이름을씁니다. 소스파일이여러개일경우에는, SOURCES=KBasic.c, add1.c, add2.c 이런식으로추가합니다. 이제빌드프롬프트를이용해서빌드해보도록하겠습니다. 그림 5. KBasic.c, MAKEFILE, SOURCES 위의그림과같이세개의파일이같은폴더내에존재해야합니다. 그림 6. 빌드프롬프트로가기

드라이버를컴파일시키려면빌드프롬프트를실행해야합니다. 위의그림 6 처럼시작 -> 모든프로그램 ->Development Kits 안에가면설치된버전에맞는 DDK 폴더안에 Build Environments 폴더가존재할것입니다. 이곳에또하위폴더로 Windows 2000, Windows Server 2003 그리고 Windows XP 가존재합니다. 어떤하위 OS 폴더의빌드프롬프트를선택하느냐에따라서각각의 OS 환경에특화된드라이버파일을만들게됩니다. 여기선현재제가쓰고있는 OS 가 Windows XP 이기때문에 Windows XP 폴더의 Windows XP Checked Build Environment 를클릭하겠습니다. Checked Build 와 Free Build 의차이점은디버깅정보를포함해서드라이버파일을만드느냐? 그렇지않느냐? 의차이입니다. Checked Build 로하는것이좋습니다. 그림 7. 빌드화면 이제빌드프롬프트에서소스파일이있는폴더로가서그림 7 과같이 build -cez 라고치면컴파일을하게됩니다. 메시지를보면 objchk_wxp_x86 i386 kbasic.sys 로드라이버파일만들기에성공했다고뜹니다. 이제이폴더에가서드라이버를실행해보겠습니다. 그림 8. DriverStudio 의 DriverMonitor 캡쳐화면

위의그림은 DriverStudio 에구성요소중하나인 DriverMonitor 의캡쳐화면입니다. 드라이버를로딩해서구동시키려면드라이버로더프로그램이필요한데이에유용합니다. 다른로더프로그램도공개된것이많으니찾아보시기바랍니다. 메뉴에서 File->Open 에서드라이버파일인 Kbasic.sys 를선택한다음에위의툴바에나오는 Go 버튼을누르게되면드라이버가구동하게되고, 옆의 Stop 버튼을누르게되면드라이버의 Unload 루틴을실행시키고나서드라이버를메모리에서제거시킵니다. 가장기본적인드라이버를작성하여빌드하고드라이버로더를통해구동까지해봤습니다. 이제다음은여기서코드를조금더해서 CR0 레지스터조작을통해 SSDT 메모리의 read-only 속성을 write 속성으로변경시켜보겠습니다. 3-4. CR0 레지스터조작하기 CR0 레지스터는제어레지스터 (Control Register) 의하나로써, 보호모드에서프로세스의특성과작동모드를결정하는레지스터입니다. 그림 9. CR0 레지스터 위의그림을보시면 16 번째비트로 WP 비트를볼수있는데, Windows XP 이상의 OS 에서이비트를 0 으로만든다면 SSDT 나 IDT 같은메모리페이지들의 read-only 속성을 write 속성으로고칠수있고, 이것을통해 SSDT 후킹이나 IDT 후킹기법을가능하게만들수있습니다. 이제이기능을구현한소스코드를작성해보겠습니다.

#include <ntddk.h> VOID OnUnload( IN PDRIVER_OBJECT DriverObject) { asm // CR0 레지스터속성되돌리기 { push eax mov eax, CR0 or eax, NOT 0FFFEFFFFh mov CR0, eax pop eax } } DbgPrint("unload~~ n"); NTSTATUS DriverEntry( IN PDRIVER_OBJECT thedriverobject, IN PUNICODE_STRING theregistrypath ) { DbgPrint("DriverEntry() Start n"); thedriverobject->driverunload = OnUnload; asm // CR0 레지스터 WP 비트를 0 으로만들기 ~~ { push eax mov eax, CR0 and eax, 0FFFEFFFFh mov CR0, eax pop eax } } return STATUS_SUCCESS; KCr0.c 이전에작성했던 KBasic.c 와다른부분은인라인어셈코드가들어가있는굵은글씨의부분밖에는없습니다. 이것이 CR0 레지스터의 WP 비트를바꾸는루틴입니다. 정말로 CR0 레지스터의비트가바뀌었는지 LiveKd 를이용해서확인해보겠습니다. LiveKd 는지금은 Microsoft 에인수된 Sysinternals.com 홈페이지를들어가면다운로드받을수있고, 설치법은압축된파일을전부 WinDbg 의폴더에복사시키면됩니다. 실행법은단순히 LiveKd.exe 파일을실행하면됩니다. 먼저드라이버를구동시키기전의 CR0 레지스터의값은밑의그림과같습니다.

그림 10. LiveKd 로 CR0 레지스터값확인 LiveKd 에서제어레지스터 (Control Register) 의값을 Windbg 로확인하는명령어는 rm 0x80 입니다. 이명령을사용하면 CR0, CR2, CR3 레지스터의값이출력됩니다. 우리가주목해야할것은 CR0 레지스터이고, 이값은 8001003b 라는값을갖습니다. 이값에서중간의 1 이라는숫자가 WP 비트가포함되어있고, 이것은 WP 비트가 1 로설정되어있다는이야기입니다. 이제 LiveKd 를종료한후드라이버구동을시키고다시 LiveKd 로 CR0 레지스터값확인을통해 WP 비트의변화를살펴보겠습니다. 그림 11. 드라이버를구동한다.

그림 12. LiveKd 로바뀐 WP 비트확인 드라이버를구동시키고, LiveKd 를다시구동시켜서 CR0 레지스터를확인한결과 WP 비트가바뀌었습니다. 이제 SSDT 나 IDT 의후킹을할수있는근간이마련된것입니다. 4. 마치는말 지금까지 API 호출과정을유저레벨과커널레벨에서분석해보고, WDM 디바이스드라이버를이용하여간단한커널기반루트킷을작성하는방법을살펴보았습니다. 아마이과정에서빌드과정이나드라이버프로그래밍과정을자세히기술하려고노력했기때문에특별히어려운부분은없었을것이라고생각합니다. 하지만드라이버빌드환경설정하는부분을자세히기술하지않았기때문에그것은뒤에도움이될만한사이트들을올리는것으로대신하겠습니다. 이제다음에연재할문서에는 DKOM 기법을다뤄보면서기본적인드라이버의틀에서벗어나드라이버프로그래밍을좀더깊이들어가겠습니다. DKOM 이란것을간단히소개하면, Direct Kernel Object Manipulation 의약자로서 Object Manager 를거치지않고커널오브젝트를직접적으로수정하게하는커널해킹기법입니다. 5. References 5-1. 참고문헌 [1] Greg Hoglund, James Butler, Rootkits : Subverting the Windows Kernel (book) [2] 이봉석, 고급개발자들만이알고있던디바이스드라이버구조와원리그리고제작노하우

(book) [3] Sven B.Schreiber, Undocumented Windows 2000 Secrets A Programmer s Cookbook (book) [4] 정덕영, Windows 구조와원리 2 판 (book) [4] 드라이버쪼물딱거리기 3 탄, http://somma.egloos.com/2731001 [5] rootkit.com, http://www.rootkit.com [6] 드라이버온라인, http://www.driveronline.org 5-2. 도움이될만한사이트 [1] http://www.rootkit.com Rootkits 책의저자인 Grug Hoglund 가운영하는곳으로전세계의해커들이커널해킹과루트킷에관련된최신기술이나정보를교류하는곳이다. [2] http://www.driveronline.org 윈도우디바이스드라이버개발자커뮤니티로서이분야에서는우리나라에서가장규모가큰곳이다. [3] http://www.kosr.org 역시윈도우디바이스드라이버개발자커뮤니티로서상당히많은정보가있다. [4] http://www.osronline.org 전세계에서가장큰윈도우디바이스드라이버개발자커뮤니티로서굉장히많은자료와정보가존재한다. [5] http://www.microsoft.com/whdc/ - Microsoft 에서윈도우디바이스드라이버개발자들에게도움을줄수있도록많은자료와정보를제공하는사이트. [6] http://www.microsoft.com/technet/sysinternals/ - 지금은 Microsoft 에인수된 Sysinternals 사이트. LiveKd 와같이드라이버개발시에유용한툴과소스가있다. [7] http://goedel.chonbuk.ac.kr/wcham/ - 함운철교수님의개인홈페이지. 커널디버깅관련자료들이많다. [8] http://www.zap.pe.kr 여리님의개인홈페이지. 커널해킹에관한몇가지결과물과아이디어가있다. [9] http://dualpage.muz.ro 듀얼님의개인블로그. [10] http://somma.egloos.com - somma 님의개인블로그.