본문 바로가기

Security

[Reversing] rootkit 1

Rootkit1

해커들이 시스템을 해킹할 때 시스템 이용자가 해킹당하고 있음을 알지 못하도록 하기 위해 사용하는 도구(프로그램 등)를 말한다. 

루트킷을 설치하는 목적은 해커들이 나중에 시스템에 접근할 때 들키지 않으려는 것이다. 즉, 해커들은 이 도구를 사용해서 컴퓨터의 제어권을 가로채고 자신들이 하는 일을 감출 수 있다.

커널 모드와 유저 모드

<프로세스 디자인>


Ring 0~3까지 총 4가지 권한이 존재하고, Windows에서는 Ring 0와 Ring 3 만을 사용한다.

Ring 3는 유저 모드, Ring 0는 커널 모드라고 한다.

Ring 3는 유저 레벨 프로그램의 코드가 실행되며, 특별한 명령어(int 2E, SYSENTER)를 통해 Ring 0 권한에 진입할 수 있다.

Ring 0에서는 하드웨어에 직접 접근하거나 커널의 가상메모리, 그 밖의 중요한 레지스터나 데이터에 접근하는 것이 가능하다.

특히 유저모드에서 접근이 불가능항 0x80000000 이상인 커널의 가상메모리에 접근이 가능하다.

API 함수 호출 과정을 분석해본다.

ex) 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 함수 중, 어떤 함수를 호출할지 정하는 인덱스가 되어서, 나중에 커널 모드로 제어가 넘어갔을 때 참조하게 됩니다. 

<각각의 프로세스의 CreateFile()호출은 한곳의 NtCreateFile()로 이동된다.>

Native API를 후킹한다면, 위 그림과 같이 유저레베의 모든 프로세스에 적용되면서 결국은 전역적으로 후킹이 가능하다.



간단한 루트킷 제작

빌드를 하기 위해선 DDK(Driver Development Kit)이 필요한데 현재 Windows 버전에서는 WDK가 존재한다.

루트킷을 제작하기 위한 간단한 소스 코드

#include <ntddkbd.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;
}

빌드하기 위해선 .c파일 뿐만 아니라 MAKEFILE, SOURCE 파일도 필요하다

#
# 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> 


TARGETNAME=KBasic
TARGETPATH=OBJ
TARGETTYPE=DRIVER
SOURCES=KBasic.c
                                                   <SOURCE> 













'Security' 카테고리의 다른 글

[ Pwnable ] SIS / System 2  (0) 2013.04.01
[ Pwnable ] SIS / System 1  (0) 2013.04.01
[Pwnable] 2013 CodeGate / Vuln 300  (6) 2013.03.15
[Pwnable] BOF 원정대  (0) 2012.11.06
Linux란?  (2) 2012.04.19