39
工學碩士學位論文 원본 이미지 비교에 의한 커널 백도어 검사 및 복구 Kernel Backdoor Check and Restoration Through Original Image Comparison 2003 年 2 月 仁荷大學校 大學院 電子計算工學科

원본 이미지 비교에 의한 커널 백도어 검사 및 복구 Kernel …ii Abstract Recently, Kernel Backdoor is introduced as a new method of attacking a system as reports

  • Upload
    others

  • View
    0

  • Download
    0

Embed Size (px)

Citation preview

Page 1: 원본 이미지 비교에 의한 커널 백도어 검사 및 복구 Kernel …ii Abstract Recently, Kernel Backdoor is introduced as a new method of attacking a system as reports

工學碩士學位論文

원본 이미지 비교에 의한 커널 백도어

검사 및 복구

Kerne l Backdoor Check and Res tora t ion

Through Or ig ina l Image Compar ison

2003 年 2 月

仁荷大學校 大學院

電子計算工學科

金 一 勇

Page 2: 원본 이미지 비교에 의한 커널 백도어 검사 및 복구 Kernel …ii Abstract Recently, Kernel Backdoor is introduced as a new method of attacking a system as reports

工學碩士學位論文

원본 이미지 비교에 의한 커널 백도어

검사 및 복구

Kerne l Backdoor Check and Restora t ion

Through Orig ina l Image Compar ison

2003 年 2 月

指導敎授 金 基 昌

이 論文을 碩士學位論文으로 提出함

仁荷大學校 大學院

電子計算工學科

金 一 勇

Page 3: 원본 이미지 비교에 의한 커널 백도어 검사 및 복구 Kernel …ii Abstract Recently, Kernel Backdoor is introduced as a new method of attacking a system as reports

이 論文을 金一勇의 碩士學位論文으로 認定함.

2003 年 2 月 日

主審 印

副審 印

委員 印

Page 4: 원본 이미지 비교에 의한 커널 백도어 검사 및 복구 Kernel …ii Abstract Recently, Kernel Backdoor is introduced as a new method of attacking a system as reports

i

요 약

최근 시스템 침해사례가 점차 늘어나고 있는 상황에서 새로운 시스템

공격방법이 소개되었는데 바로 커널 백도어이다. 커널 백도어란 시스템의

침입자가 다음 침입을 쉽게하기 위하여 시스템 커널내의 특정부분을 변경하여

비밀리에 설치한 도구이다. 커널 백도어의 심각성은 커널 자체를 수정하기

때문에 탐지가 매우 어렵다는 것이다. 커널 백도어의 주된 공격 방법은

시스템 콜 테이블을 변형하거나 시스템 콜 코드를 수정하는 것이다. 커널

백도어는 커널을 수정하기 때문에 기존의 백도어 탐지 도구로는 탐지가

불가능하다. 따라서 커널 백도어 탐지에 대한 여러가지 연구가 진행되고

있는데 대부분의 커널 백도어 탐지 도구들은 커널내의 특정 심볼의 주소를

참조하여 이 주소가 변경 되었는지를 조사하고 변경 되었으면 커널 백도어로

판정하고 이에 대응하는 조치를 취하는 기법을 사용한다. 이러한 기법은 단지

시스템 콜 테이블의 변형에 대한 대응만 할 뿐 시스템 콜 코드를 수정하는

커널 백도어에 대한 대응은 되지 않는다. 이러한 방법으로 시스템 콜 코드의

변형이 탐지가 된다하더라도 복구는 거의 불가능하다. 다만 현재의 모든

탐지도구들은 시스템을 재시작하여 커널 백도어로 의심이 되는 커널 모듈을

다시 로딩되지 않도록 하는 방법을 사용한다. 이에 본 논문에서는 순수한

커널 이미지인 커널의 부트 이미지와 현재 메모리에 로딩되어 실행되고 있는

커널 이미지를 비교하여 커널 백도어를 탐지하고, 이 정보를 이용하여 커널

백도어에 의해 변경된 커널의 특정부분을 시스템의 재시작없이 원래의 상태로

복구하는 기법을 제안한다.

Page 5: 원본 이미지 비교에 의한 커널 백도어 검사 및 복구 Kernel …ii Abstract Recently, Kernel Backdoor is introduced as a new method of attacking a system as reports

ii

Abstract

Recently, Kerne l Backdoor is introduced as a new method of attacking a

system as reports of cracking increases . It is a hacking tool that is

installed by the intruder to make the next invasion easy. Because Kernel

Backdoor is set by modifying the kernel code in confidence, it is very

difficult to be sensed; it converts the system call table or a system call

itself. It could make a system fall into a serious situation. These types of

backdoors are impossible to detect through existing Kernel Backdoor

detecting methods. Depending on recent researches, they are detected by

checking specific symbols that could be assaulted by the attackers whether

kernel codes are changed or not. Moreover, these methods could not

determine revised system call codes and retrive them. Therefore, the

system should have been rebooted to recover from the Kernel Backdoor.

This paper introduces a new technique that detects and recovers from

Kernel Backdoor without restarting the system. It achieves its aim by

comparing the working kernel image with the original boot image.

Differences between them are detected which could mean a possible attack

by an intruder. It pinpoints the modified code area and recovers the

original code by using the boot image.

Page 6: 원본 이미지 비교에 의한 커널 백도어 검사 및 복구 Kernel …ii Abstract Recently, Kernel Backdoor is introduced as a new method of attacking a system as reports

iii

목 차

제 1 장 서 론......................................................................1

제 2 장 관련 연구 ..............................................................3

2.1 커널의 구조.......................................................................................... 3

2.2 시스템 콜의 동작원리........................................................................... 4

2.3 LKM(Loadable Kernel Module) ........................................................... 6

2.4 LKM 백도어의 종류 및 공격 방법........................................................ 7

2.5 기존의 LKM 백도어 탐지 기법 및 문제점...........................................11

제 3 장 원본 이미지 비교에 의한 커널 백도어 검사 및

복구 시스템........................................................................14

3.1 커널의 부트 이미지.............................................................................14

3.2 /dev/kmem 으로부터 시스템 콜 테이블 주소 가져오기 .......................15

3.3 각 커널 버전별 시스템 콜 코드 크기 정보..........................................18

3.4 원본 이미지 비교에 의한 커널 백도어 탐지 및 복구...........................19

제 4 장 실험 및 실험 결과 .............................................25

4.1 커널 백도어 탐지 실험........................................................................25

4.2 실험 결과 ............................................................................................27

제 5 장 결론......................................................................29

참고 문헌..............................................................................30

Page 7: 원본 이미지 비교에 의한 커널 백도어 검사 및 복구 Kernel …ii Abstract Recently, Kernel Backdoor is introduced as a new method of attacking a system as reports

1

제 1 장 서 론

최근 시스템 침해사례가 점차 늘어나고 있는 상황에서 새로운 시스템

공격기법이 소개되었는데 바로 커널 백도어이다. 커널 백도어란 시스템의

침입자가 다음 침입을 쉽게하기 위하여 시스템의 커널내 특정부분을 임의로

수정하여 비밀리에 설치한 도구이다. 일반적인 백도어의 경우 보안 기술의

고도화로 인해 관리자가 쉽게 탐지, 복구를 할 수 있다. 하지만, 커널

백도어의 경우 커널을 직접 수정하여 커널영역에서 수행되므로 탐지자체가

매우 어렵다.

대부분의 커널 백도어들은 현재 실행중인 커널에 동적으로 사용자의 코드를

추가할 수 있는 기능을 가진 LKM(Loadable Kernel Module)이라는 커널

모듈의 형태로서 커널에 로딩된다. 이러한 커널 백도어의 대표적인 동작들은

커널의 시스템 콜을 변경한다거나 파일이나 프로세스를 숨길 수도 있으며

쉽게 루트(Root)권한을 획득할 수 있도록 해준다.

이에 대한 지금까지의 대응 방법은 커널 백도어가 주로 시스템 콜 테이블을

변경하여 공격을 수행한다는 점에 착안하여 시스템 콜의 주소를 검사하는

방법이 사용되고 있다. 그리고, LKM은 커널의 동적데이터 영역에 생성되므로

원래 커널의 주소공간과는 다르다는 점을 이용하여 주소 공간의 영역을

조사하는 방법이 사용된다. 하지만 이렇게 주소만을 가지고 검사하는

방법으로는 얼마전 소개된 커널 코드를 직접 수정하는 공격방법에 무기력해

질 수밖에 없다. 이러한 LKM 백도어의 공격에 대해 가장 안전한 대응 방법은

시스템에서 LKM을 지원하지 않도록 설정하는 것이다. 하지만 이러한 방법도

얼마전 LKM의 지원이 없어도 커널을 수정하는 방법이 소개되어 더 이상

Page 8: 원본 이미지 비교에 의한 커널 백도어 검사 및 복구 Kernel …ii Abstract Recently, Kernel Backdoor is introduced as a new method of attacking a system as reports

2

안전하지 않게되었다.

본 논문에서는 이러한 여러가지 문제점에 대응하여 시스템이 부팅시

사용되는 커널 이미지와 현재 실행중인 커널 이미지를 사용자 영역에서

비교하여 커널 백도어에 의한 커널 이미지의 변경여부를 검사하고 시스템의

재시작 없이 이를 복구하는 시스템을 제안한다.

본 논문의 구성은 다음과 같다. 제2장에서는 관련연구들을 소개한다. 우선

커널의 구조와 커널내 시스템콜의 동작, 커널 모듈, LKM 백도어의 종류 및

공격방법, 기존의 탐지 방법에 대해서 소개하고, 그에대한 문제점을 제시한다.

제3장에서는 본 논문에서 제안하는 원본 이미지 비교에 의한 커널 무결성

검사 및 복구에 대해 설명한다. 제4장에서는 실험 및 실험 결과를 보이고,

마지막 제5장에서는 결론 및 향후 연구방향에 대해 설명하고 끝을 맺는다.

Page 9: 원본 이미지 비교에 의한 커널 백도어 검사 및 복구 Kernel …ii Abstract Recently, Kernel Backdoor is introduced as a new method of attacking a system as reports

3

제 2 장 관련 연구

2 . 1 커널의 구조

커널은 부팅시에 하드웨어를 초기화하고 메모리상에 커널자신을 구축하여,

디스크상에 존재하는 파일들과 응용 프로그램들이 커널에서 동작할 수 있도록

한다. 이때 작업을 수행하기 위하여 시스템의 다양한 리소스들을

프로세스들에게 분배 및 회수하는 관리작업을 수행하게 되며, 수행중인

시스템 안정성도 커널이 책임지게 된다. 이와 같은 작업을 위하여 커널은

시스템의 하드웨어와 직접적으로 상호작용을 하게된다.

이러한 작업을 수행하는 커널이 하드웨어 리소스와 상당히 밀접한 관계를

갖고 설계되어져 있음을 알 수 있다. 실제 커널은 매우 복잡한 형태로

이루어져 있는데 이를 시스템 리소스 관점에서 살펴보면 매우 단순화 된다.

시스템 리소스들을 CPU, 메모리, 그리고 다른 여러 디바이스들로 분리시킨

관점에서 보면, CPU 관리는 프로세스 매니저, 메모리 관리는 메모리 매니저,

마지막으로 여러 디바이스들을 관리하는 가상 파일시스템으로 분리 되어있다.

그리고 여기에 덧붙여서 시스템에 구축된 커널이 네트워크 상의 작업을

수행하는 네크워크 모듈이 추가되어 질 수 있다. 다음 [그림 2-1]은

커널내에서 리소스 관리별로 분류된 모듈의 구조와 관계를 나타낸다.

대부분의 사용자 영역에서의 응용프로그램들은 커널과의 통신을 시스템 콜

인터페이스를 통해서 하게된다. 파일에 대한 관리, 메모리에 대한 관리,

프로세스에 대한 관리 이 모든 것이 시스템 콜을 통해서 이루어 진다[14].

Page 10: 원본 이미지 비교에 의한 커널 백도어 검사 및 복구 Kernel …ii Abstract Recently, Kernel Backdoor is introduced as a new method of attacking a system as reports

4

User Application

System Libraries

User Level

Kernel Level

System Call Interface (x86 interrupt 0x80)

Trap Trap

File System

Process Management(IPC, Scheduling,

Memory Management,Process Accounting, etc)

Buffer Cache

CharacterDevice Driver

Block DeviceDriver

Hardware Interface

[그림 2-1] 커널 구조도

2 . 2 시스템 콜의 동작원리

시스템 콜(system call)이란 프로세스가 커널에 서비스를 요청하는 것이다.

커널은 시스템 콜 인터페이스를 제공하며, 이것은 헤더파일 형태로 사용자

Page 11: 원본 이미지 비교에 의한 커널 백도어 검사 및 복구 Kernel …ii Abstract Recently, Kernel Backdoor is introduced as a new method of attacking a system as reports

5

프로세스에 제공된다. 사용자 프로세스는 직접적으로 혹은 라이브러리를

통해서 커널에 접근하게 되며, 시스템 콜은 호출이되는 순간 사용자 영역에서

커널 영역으로 전환되어 수행된다. 따라서, 시스템 콜이 호출되면 커널의

코드가 사용자 프로세스의 context 아래에서 동작하게 되는 것이다. 실제로

시스템 콜은 운영체제가 제공하는 라이브러리라고 생각하면 된다.

Intel 계열의 CPU인 i386 환경에서 시스템 콜은 인터럽트를 사용해서

구현된다. 인터럽트 0x80이 이를 위해서 예약되어 있다.

…xyz()

...

xyz() { … int 0x80 …}

system_call : … sys_xyz() ... ret_from_sys_call : … iret

sys_xyz() {………}

User Mode Kerne l Mode

System call invocation in application

program

Wrapper routine in libc standard

library

System call handler

System call service routine

[그림 2-2] 시스템 콜 작동원리

[그림 2-2]을 보면 사용자 영역에서 시스템 콜을 호출하는 과정을 볼 수

있다. 사용자 프로그램에서 라이브러리에 있는 xyz()라는 시스템 콜을

호출하면, xyz() 라이브러리는 인터럽트 번호 0x80을 호출한다. 커널은

인터럽트 서비스 루틴에의해 시스템 콜을 받아들이며 핸들러를 통해

sys_xyz() 서비스 루틴을 호출하여 실행하고, 끝이나면 ret_from_sys_call()을

통해 다시 사용자 프로그램으로 리턴한다[14].

Page 12: 원본 이미지 비교에 의한 커널 백도어 검사 및 복구 Kernel …ii Abstract Recently, Kernel Backdoor is introduced as a new method of attacking a system as reports

6

2 . 3 L K M ( L o a d a b l e K e r n e l M o d u l e )

운영체제는 일반적으로 Micro Kernel과 Monolithic Kernel로 구분된다.

Micro Kernel은 다수의 완전히 분리된 모듈(또는 프로세스)로 구성되며, 각

프로세스간에는 메시지 교환방식을 이용하여 통신하게 된다. 반면, Monolithic

Kernel의 경우 내부적으로 여러 하위 모듈로 나위어진 하나의 커다란

프로세스가 커널을 이루게 된다. 즉, 커널이 커다란 하나의 실행 이미지로

이루어진다[15].

Module Kernel Properinit_module() register_capability()

capabilities()

cleanup_module() unregister_capability()

printk()…...

[그림 2-3] 모듈을 커널에 링크

LKM이란 이렇게 커다란 하나의 실행 이미지로 이루어진 Monolithic

Kernel에 Micro Kernel의 동적인 기능을 추가하기 위한 메커니즘으로, 시스템

콜 또는 커널의 자원 요청에 따라 동적으로 필요한 모듈만을 로드하거나

언로드하는 기능을 제공한다. 또한 커널 코드를 수정한 후 다시 컴파일

하거나 재부팅 하지않고 커널 모듈을 개발할 수 있다는 장점이 있다.

커널 모듈에는 정적 적재(static loading)와 동적 적재(dynamic loading)가

Page 13: 원본 이미지 비교에 의한 커널 백도어 검사 및 복구 Kernel …ii Abstract Recently, Kernel Backdoor is introduced as a new method of attacking a system as reports

7

있는데, 전자의 경우는 커널이 부팅이 될 때 적재가 되는 것을 말하며, 후자의

경우 커널이 실행되고 있는 도중에 적재가 되는 것을 말한다.

[그림 2-3]은 실행중인 리눅스 커널에 새로운 기능을 추가하기 위해

모듈에서의 등록과정, 등록 해제과정 그리고 함수호출 과정을 보여주고 있다.

2 . 4 L K M 백도어의 종류 및 공격 방법

백도어는 패스워드 크래킹을 통해 루트(Root)권한을 획득한 침입자가

패스워드 없이도 시스템에 재차 접근할 수 있도록 비밀리에 설치한

프로그램이다. 그 중 LKM 백도어는 LKM이 이미 실행중인 커널의 일부를

추가, 변경할 수 있다는 점에 착안하여 1997년 Phrack Magazine에

소개되었다. 이후 LKM 백도어는 그 기법이 점차적으로 고도화, 다양화되고

있는 추세이다[13].

대부분의 LKM 백도어는 정상적인 시스템 콜을 가로채서 공격자가 만든

시스템 콜 함수가 실행되도록 하는 방법을 사용한다. 즉, 시스템 콜은 커널내

전역변수인 시스템 콜 테이블에 정의된 시스템 콜 함수의 주소를 참조하여

수행되는데, LKM 백도어는 이 시스템 콜의 주소를 공격자가 만든 시스템 콜

함수의 주소로 바꾸는 역할을 하는 것이다. 그리고 최근에는 이러한 시스템

콜을 가로채지 않고 시스템 콜 함수의 코드를 직접 수정하는 방법 또한

소개되었다[1][2]. 본 단락에서는 어떠한 LKM 백도어의 기법이 있는지

살펴본다.

2.4.1 시스템 콜 가로채기

시스템 콜 가로채기 기법은 LKM 백도어가 커널의 전역변수인 시스템 콜

Page 14: 원본 이미지 비교에 의한 커널 백도어 검사 및 복구 Kernel …ii Abstract Recently, Kernel Backdoor is introduced as a new method of attacking a system as reports

8

테이블의 해당 시스템 콜 엔트리의 주소를 공격자의 시스템 콜 함수의 주소로

바꾸어 공격자가 원하는 작업을 수행 하도록 하는것이다. [그림 2-4]는

이러한 과정을 보여준다.

sys_ l lseek

sys_getdents

sys_se lec t

sys_getdents

sys_ l lseek

sys_se lec t

hacked_getdents

sys_cal l_ table[] _text

LKM backdoo r

[그림 2-4] 시스템 콜 가로채기

LKM 백도어가 로드되면 전역변수인 sys_call_table[]을 참조하고,

가로채기를 원하는 시스템 콜 엔트리의 주소를 LKM 백도어내의 원하는

함수주소로 바꾸어준다.

이러한 시스템 콜 가로채기 기법은 루트 권한 얻기, 프로세스나 파일 숨기기,

네트워크 문자열 숨기기, 실행중인 프로세스의 uid, gid 변경, 모듈 숨기기

등의 기능을 수행할 수 있다. 현재까지 알려진 거의 모든 LKM 백도어가

이러한 방법을 사용하고 있다.

Page 15: 원본 이미지 비교에 의한 커널 백도어 검사 및 복구 Kernel …ii Abstract Recently, Kernel Backdoor is introduced as a new method of attacking a system as reports

9

루트권한 얻기

[그림 2-5]는 루트권한을 얻을 수 있는 LKM 백도어의 코드중 일부이다.

LKM 백도어는 전역변수인 sys_call_table[]을 참조하여 로그인 시 호출되는

원본 sys_getuid를 hacked_getuid로 바꾸고 hacked_getuid에서는 공격자가

임의로 지정한 사용자의 uid로 getuid가 요청이 되었을 때 루트의 권한을

주게된다.

extern sys_call_table[];static int hacked_getuid(void);

int init_module(void){ … org_getuid = sys_call_table[__NR_getuid]; sys_call_table[__NR_getuid] = hacked_getuid;}

void cleanup_module(void){ sys_call_table[__NR_getuid] = org_getuid;}

static int hacked_getuid(void){ if(uid == HACKER_UID) { // set uid, euid, gid, egid to 0( root) ;

return 0; } ...}

[그림 2-5] 루트권한을 얻기 위한 LKM 백도어

파일 감추기

getdents 는 ls 명령을 실행할 때 호출되는 시스템 콜이다. 이 시스템 콜을

공격자가 만든 시스템 콜로 바꾸어주면 공격자가 만든 파일은 사용자

Page 16: 원본 이미지 비교에 의한 커널 백도어 검사 및 복구 Kernel …ii Abstract Recently, Kernel Backdoor is introduced as a new method of attacking a system as reports

10

영역에서는 보이지 않게된다.

L K M 백도어 자신을 숨기기

각각의 시스템에는 현재 실행중인 LKM을 보여주는 명령들이 있다. LKM

백도어도 이에 대한 조치가 없으면 쉽게 발견될 수 있다. 따라서 최근의 모든

LKM 백도어에서는 자기 자신을 숨기는 기법이 포함되어 있다.

현재 커널에 로드된 LKM을 사용자 영역에서 확인하려면 get_kernel_syms

라는 시스템 콜과 모듈의 이름을 가지고 있는 모듈 리스트가 사용된다. 우선

모듈 리스트 중 자신의 모듈 구조체를 찾아 모듈의 이름을 나타내는 영역을

NULL로 해주면 되고, get_kernel_syms 시스템 콜을 공격자의 시스템 콜로

변경하여 LKM 백도어 자신의 심볼들은 나타나지 않도록 해주면 된다.

2 . 4 . 2 시스템 콜 코드 변경

지금까지 LKM 백도어가 시스템 콜을 가로채는 기법을 살펴보았다. 이러한

기법은 시스템 콜 엔트리가 공격자의 LKM 내의 코드를 나타내고 있게 된다.

하지만 LKM의 주소영역은 커널의 기본적인 주소공간인 _text 와 _edata

사이가 아닌 동적 데이터의 주소공간이 된다. 이 점을 착안한다면 시스템

콜을 가로채는 기법은 쉽게 발견할 수 있다. 이러한 점을 보완하여 얼마전

시스템 콜 테이블을 접근하지 않고, 시스템 콜의 코드 영역을 직접 수정하는

기법이 소개되었다[12].

[그림 2-6]은 원본 시스템 콜의 코드 중 일부를 공격자의 코드에 백업해

두고 원본 코드를 공격자의 코드로 점프하도록 수정하고, 공격자의 코드가

Page 17: 원본 이미지 비교에 의한 커널 백도어 검사 및 복구 Kernel …ii Abstract Recently, Kernel Backdoor is introduced as a new method of attacking a system as reports

11

모두 수행되면 다시 원본 시스템 콜의 나머지 부분이 수행되도록 점프하는

것을 보여준다.

or ig in code

rest code

mal ic ious code

jump to rest code

hook_code

movl hook_code, %eaxjmp *%eax

① copy

② overwr i te

7 by tes

[그림 2-6] 시스템 콜 코드 수정

2 . 5 기존의 L K M 백도어 탐지 기법 및 문제점

기존의 백도어는 공격자의 프로세스, 디렉토리, 파일 그리고 접속 사실까지도

숨길 수 있다. 하지만 이들은 ps, df, netstat, top, lsof 와 같은 사용자

프로그램을 변경하여 원하는 기능을 제공하는 것이다. 따라서 이러한

백도어는 파일의 사이즈, 사용되는 시스템 콜의 추적, 그리고 파일의 무결성을

검사하여 쉽게 탐지할 수 있다.

하지만 LKM 백도어는 사용자 영역의 프로그램을 수정하지 않고, 직접

커널의 일부를 변경하기 때문에 탐지가 쉽지않다. 따라서 LKM 백도어를

탐지하기 위해서는 KSTAT, Btrom등의 LKM 백도어 탐지 프로그램의 도움을

받아야만 했다.

Page 18: 원본 이미지 비교에 의한 커널 백도어 검사 및 복구 Kernel …ii Abstract Recently, Kernel Backdoor is introduced as a new method of attacking a system as reports

12

기존의 LKM 백도어 탐지에 관한 연구는 크게 두 가지 방향으로 진행되었다.

우선 첫번째 방법은 대부분의 LKM 백도어가 시스템 콜 핸들러의 주소를

변경하는 방법을 사용한다는 점에 착안하여, 현재 커널 메모리 정보를

담고있는 /dev/kmem 과 커널 이미지가 컴파일되는 시점에서 수집된 커널의

심볼 정보를 담고 있는 System.map파일을 비교하는 방법이다. 두번째 방법은

LKM의 실행 이미지가 커널의 코드나 데이터 영역, 즉 _text 에서 _edata

까지의 영역에 위치하지 않고 동적 데이터 영역에 위치한다는 점에 착안한

주소 영역을 조사하는 방법이다[7][8][9][10]. 본 장에서는 각각의 방법을

통한 LKM 백도어 탐지 기법들을 소개하고 이에 대한 문제점을 알아본다.

2.5.1 특정 커널 심볼의 주소를 비교하는 기법

커널은 자신이 컴파일될 때 커널 내 심볼 정보를 담은 System.map 파일을

생성한다. 이 파일에는 커널 내에서 사용되는 함수나 변수의 정보를 담고

있는데, 이 정보를 이용하여 커널 백도어에 의해 변형된 커널을 탐지할 수

있다. 시스템 콜 테이블이나 각각의 시스템 콜 핸들러에 대한 정보 또한

System.map 파일에 저장되어 있다.

/dev/kmem은 현재 실행중인 커널의 정보를 볼 수 있는 파일이다. 즉,

System.map 파일로부터 시스템 콜 테이블의 정보를 읽어와서 그 정보를

/dev/kmem에서 찾을 수 있고, 각각의 시스템 콜 엔트리에 대해서도 위와

같이 정보를 얻어올 수 있다. 이렇게 수집된 정보를 이용하여 System.map 의

정보와 /dev/kmem으로 부터의 정보가 서로 상이할 경우 이를 커널 백도어로

판정할 수 있는것이다. 이 기법은 KSTAT(Kernel Security Therapy Anti-

Tools)에 의해 사용된다.

Page 19: 원본 이미지 비교에 의한 커널 백도어 검사 및 복구 Kernel …ii Abstract Recently, Kernel Backdoor is introduced as a new method of attacking a system as reports

13

하지만 이러한 방법의 경우 System.map 파일을 사용자가 쉽게 접근할 수

있기 때문에 변경에 대해 무방비 상태가 된다. 악의적인 공격자가 커널을

수정한 후 그 정보를 가지고 System.map 파일을 수정한다면 위의 방법으로는

탐지가 불가능하게 된다.

2.5.2 심볼의 주소 범위를 통한 검사 기법

순수한 커널의 경우 시스템 콜 테이블은 커널의 데이터 영역에 위치하게

되며, 각 시스템 콜 핸들러들은 커널의 코드 영역에 위치하게 된다. 반면

LKM의 주소 영역은 커널 내 메모리 할당 함수인 vmalloc에 의해 리턴되는

동적 데이터 영역이 된다. 따라서 LKM을 통해 시스템 콜 핸들러의 주소를

변경하는 경우 그 주소는 커널의 코드 또는 데이터 영역이 아닌 동적 데이터

영역에 위치하게 된다.

1 2 0 x 1 0 0 0x1f f

i 3 8 6 _ endbase _tex t _e tex t _eda ta _ e n d

[그림 2-7] 커널의 첫 2MB의 layout

[그림 2-7]은 커널의 처음 2MB의 배열을 보여주고 있다. 이 중 커널의

코드 영역은 _text 부터 _etext 까지가 되고, 데이터 영역은 _data(_etext)

부터 _edata가 된다. 하지만 LKM이 로드되는 위치는 _edata의 뒤쪽이 된다.

따라서 LKM 백도어가 시스템 콜 테이블을 변경한다 하더라도 주소의 영역을

검사 함으로써 쉽게 탐지가 가능하다. 이 기법은 BTRom에 의해 사용된다.

하지만 이러한 방법또한 얼마전 소개된 시스템 콜의 코드를 직접 수정하는

경우 탐지가 불가능하게 된다.

Page 20: 원본 이미지 비교에 의한 커널 백도어 검사 및 복구 Kernel …ii Abstract Recently, Kernel Backdoor is introduced as a new method of attacking a system as reports

14

제 3 장 원본 이미지 비교에 의한 커널 백도어 검사 및

복구 시스템

시스템이 시작될 때 메모리로 로드되는 이미지가 바로 커널의 부트이미지

이다. 악의적인 사용자가 메모리에 로드된 커널의 이미지를 변경하더라도

커널의 원본 이미지는 항상 디스크상에 존재하게 된다. 이러한 점을 이용하여

본 논문에서는 커널의 부트이미지 비교를 통해서 현재 실행중인 커널의 변경

여부를 검사하고 복구하는 시스템을 제안한다.

위의 제안을 만족하기 위해 우선 커널의 부트 이미지 분석이 필요하며,

악의적인 공격자에 의해 변경될 우려가 없는 시스템 콜 테이블의 주소 정보를

얻는 방법이 필요하고, 또한 시스템 콜 코드를 비교하기 위해서 각 시스템

콜의 크기 정보를 구축하여야 한다. 이후 이러한 방법에 의해 얻어진 정보와

/dev/kmem 을 비교하여 커널의 변경 여부를 조사한다.

3 . 1 커널의 부트 이미지

커널의 부트 이미지는 시스템이 시작될 때 메모리로 로드되는 실행

이미지이다. 보통 부트 이미지는 시스템의 시작에 필요한 정보들과 압축된

커널 그리고 압축된 커널을 해제할 프로그램으로 구성이 되어있다. 본

절에서는 리눅스의 부트 이미지를 분석하도록 한다.

일반적으로 리눅스 커널의 부트 이미지는 zImage 라는 이름으로 [그림 3-

1]과 같은 배열을 가지고 있다. bootsect는 시스템이 시작될 때 BIOS에 의해

메모리로 로드되고, setup은 BIOS로부터 시스템 정보를 얻어와 커널을

메모리에 적절하게 로드하는 역할을 하며, head.o와 misc.o 는 압축된 형태의

커널 이미지인 piggy.o의 압축 해제를 위한 코드 이다.

Page 21: 원본 이미지 비교에 의한 커널 백도어 검사 및 복구 Kernel …ii Abstract Recently, Kernel Backdoor is introduced as a new method of attacking a system as reports

15

boo t s ec t se tup vm l i nux .ou t

z Image

head .o m i sc .opiggy.o

(gz ipped ke rne l )

vm l i nux (compressed ke rne l )

Ke r ne l image

unz ipped p iggy.o

[그림 3-1] 리눅스 커널 부트 이미지의 레이아웃

이와 같은 분석을 통해 커널의 부트 이미지로부터 커널의 원본 이미지를

구할 수 있다. 하지만 이와 같은 방법으로 구한 커널의 원본 이미지는

일반적인 실행 파일의 형식인 ELF(Excutable and Linkable Format) 형식이

아닌 raw binary 형태이므로 커널 내의 심볼 정보나 재배치 정보는 생략되어

있다. 이후 시스템 콜 코드를 비교할 때 코드의 크기 정보를 심볼 정보로부터

얻어야 하는데 커널 이미지에는 이 정보가 생략되어 있으므로 따로 시스템 콜

코드의 크기 정보의 구축이 필요하다.

3 . 2 / d e v / k m e m 으로부터 시스템 콜 테이블 주소 가져오기

일반적으로 현재 메모리에 로딩된 커널의 시스템 콜 테이블의 주소는 해당

커널이 컴파일되는 시점에서 생성된 System.map 파일을 통해 쉽게 알아낼 수

있다. 하지만 앞의 2.5.1절 에서 언급한것과 같이 악의적인 사용자가 쉽게

수정할 수 있으므로 다른 방법이 필요하다. 따라서 이 절에서는 i386 기반의

시스템에서 idt(Interrupt Descriptor Table) 레지스터를 통한 시스템 콜

테이블의 주소를 얻는 방법을 사용한다.

Page 22: 원본 이미지 비교에 의한 커널 백도어 검사 및 복구 Kernel …ii Abstract Recently, Kernel Backdoor is introduced as a new method of attacking a system as reports

16

i386 계열의 CPU에는 IDTR이라는 레지스터가 존재하는데, 이 레지스터는

메모리 내 시스템의 IDT가 존재하는 베이스 주소와 IDT 엔트리 개수가

저장되는 레지스터이다. [그림 3-2]와같이 IDTR 레지스터는 하드웨어

인터럽트나 예외사항, 시스템 콜 등이 발생하면 IDTR 베이스 주소로부터 해당

이벤트에 대한 게이트(gate)를 호출한다.

IDT Base Address IDT Limit

47 16 15 0

Gate for Interrupt #n

Gate for Interrupt #3

Gate for Interrupt #2

Gate for Interrupt #10

8

16

(n-1)^8

IDTR

IDT

[그림 3-2] IDT와 IDTR의 관계

[그림 3-2]의 각 인터럽트 게이트에는 segment selector, low offset, high

offset, DPL(Descriptor Privilege Level)등이 있다. 이 중 offset과 segment

selector의 정보를 가지고 자신이 원하는 세그먼트의 해당 인터럽트 게이트의

주소를 구하게 된다.

i386 계열의 CPU에서 시스템 콜의 인터럽트 게이트는 0x80으로 예약되어

있다. 따라서 IDTR의 베이스 주소로부터 8 × 0x80 만큼 떨어진 위치에

Page 23: 원본 이미지 비교에 의한 커널 백도어 검사 및 복구 Kernel …ii Abstract Recently, Kernel Backdoor is introduced as a new method of attacking a system as reports

17

시스템 콜의 게이트가 위치하게 된다. 이 시스템 콜 게이트에서 offset과

segment selector의 정보를 통해 시스템 콜의 ISR(Interrupt Service

Routine)의 위치를 알 수 있다. [그림 3-3]은 이러한 과정을 간략하게

나타내고 있다.

sys tem gate0x80

Interruptvector

system_cal l : … cal l sys_cal l_table[] ...

ke rne l code segment

offset

IDT

[그림 3-3] system_call 호출 과정

시스템 콜의 ISR 내에 전역변수인 sys_call_table[]을 호출하는 부분이 있고,

이를 참조하면 시스템 콜 테이블의 주소를 얻을 수 있다.

제안된 시스템의 구현 부분은 [그림 3-4]와 같다. Assembly어의 sidt

명령으로 시스템 내의 idtr의 값을 읽어오고, /dev/kmem을 통해 idtr의 base

주소로부터 0x80만큼 떨어진 곳에서 시스템 콜의 idt를 읽어온다. 이제 idt의

offset으로 특정연산을 수행하면 시스템 콜의 ISR(Interrupt Service

Routine)의 주소를 구할 수 있다. 그리고 시스템 콜의 ISR에서 시스템 콜

테이블을 호출하는 assembly어인 "call sys_call_table[]"의 기계어 opcode

"\xff\x14\x85"를 찾을 수 있다. 그러면 해당 opcode의 operand가 실제

시스템 콜 테이블의 주소가 된다.

Page 24: 원본 이미지 비교에 의한 커널 백도어 검사 및 복구 Kernel …ii Abstract Recently, Kernel Backdoor is introduced as a new method of attacking a system as reports

18

struct { unsigned short limit; unsigned int base;} __attribute__ ((packed)) idtr;

struct { unsigned short off1; unsigned short sel; unsigned char none, flags; unsigned short off2;} __attribute__((packed)) idt;

void get_kmem_syscall_table(void){

… asm(“sidt %0” : “=m” (idtr)); // idtr의 값을 읽어온다.

… read_kmem(kmem, &idt, idtr.base + (8 * 0x80), sizeof(idt)); sys_call_off = (idt.off2 << 16) | idt.off1;

… p = (char *)memmem(syscall, CALLOFF, “\xff\x14\x85”, 3); // call sys_call_talbe[]의 opcode 패턴을 찾는다. p_sys_call_table = *(unsigned *)(p+3); ...}

[그림 3-4] 시스템 콜 테이블 주소를 가져오는 주요 코드

3 . 3 각 커널 버전별 시스템 콜 코드 크기 정보

리눅스 시스템에서 커널을 컴파일하면 vmlinux라는 ELF 형식의 바이너리

파일이 생성된다. 이 vmlinux에서 심볼 정보와 재배치 정보를 생략하고 raw

binary 형식으로 만든 것이 커널의 부트 이미지에 포함되어 있는 커널의

이미지이다. 따라서 커널 컴파일 시 생성된 vmlinux가 커널 부트 이미지의

원본이 되므로 이 파일을 ELF 형식에 따라 분석을 하면 심볼정보를 얻을 수

있다.

시스템 콜 코드는 커널에 어떠한 특별한 조치가 없는한 버전마다 항상

Page 25: 원본 이미지 비교에 의한 커널 백도어 검사 및 복구 Kernel …ii Abstract Recently, Kernel Backdoor is introduced as a new method of attacking a system as reports

19

동일하다. 이러한 점을 이용하여 커널 버전별 시스템 콜 코드의 크기 정보를

구축 할 수 있다.

ELF 형식인 vmlinux의 여러 섹션 중에서 각 심볼의 정보를 담은 심볼

테이블을 가져오면 커널 내에서 사용되는 모든 변수 및 함수에 대한 정보를

얻을 수 있고, 이 중 각 시스템 콜 함수의 정보만을 가져온다. 이 정보에는

시스템 콜 번호, 함수의 시작위치, 함수의 크기가 들어가게 된다.

3 . 4 원본 이미지 비교에 의한 커널 백도어 탐지 및 복구

3.3절의 과정을 통해 수집된 정보는 커널 부트 이미지에서 추출한 순수 커널

이미지와 IDTR을 통해 얻은 시스템 콜 테이블의 주소, 그리고 각 시스템 콜

코드의 크기와 시작위치 등이다. 이러한 정보들을 바탕으로 하여 우선 순수

커널로부터 시스템 콜 테이블을 추출하고, 이 시스템 콜 테이블과 현재

메모리에 로딩된 커널의 시스템 콜을 비교함으로써 커널의 변경 여부를

검사하게 된다.

3.4.1 순수 커널로부터 시스템 콜 테이블 추출하기

3.2절의 과정을 통해 커널내의 시스템 콜 테이블의 주소를 알 수 있다. 이때

주소는 커널이 메모리에 로딩되었을때의 가상 주소가 된다. 일반적으로

커널은 가상메모리 0xC0100000에 로딩되므로 IDTR을 통해 얻은 시스템 콜

주소에서 커널의 시작위치를 빼면 순수 커널의 시스템 콜 위치가 된다.

일반적으로 시스템 콜은 256개로 예약 되어 있으므로, 시작 위치에서 4 ×

NR_SYSCALL(256)의 위치까지가 실제 시스템 콜 테이블이 된다. 관련

코드는 [그림 3-5]와 같다.

Page 26: 원본 이미지 비교에 의한 커널 백도어 검사 및 복구 Kernel …ii Abstract Recently, Kernel Backdoor is introduced as a new method of attacking a system as reports

20

void get_kimg_syscall_table(void){

… sct_off = p_sys_call_table - 0xC0100000; memcpy(img_sct, kernel_img + sct_off, sizeof(img_sct)); ...}

[그림 3-5] 커널 원본 이미지로부터 시스템 콜 테이블을 얻는 주요 코드

3.4.2 현재 실행중인 커널의 시스템 콜 테이블 추출하기

일반적으로 실행중인 커널의 심볼에 접근하는 방법은 /dev/kmem을 통해서

이루어진다. /dev/kmem에서 접근을 원하는 심볼의 가상주소를 오프셋으로

하고 읽으면 해당 심볼의 값을 얻을 수 있다.

3.2절에서 이미 시스템 콜 테이블의 커널내 가상주소를 얻었으므로

/dev/kmem을 통해 해당 가상주소에서 시스템 콜 테이블의 크기 만큼을

읽으면 실행중인 커널의 시스템 콜 테이블을 얻을 수 있다.

3.4.3 시스템 콜 테이블 변경 여부 검사 및 복구

3.4.1절과 3.4.2절에서 추출한 시스템 콜 테이블의 각 엔트리는 해당 시스템

콜의 주소를 나타낸다. 만약 악의적인 공격자에 의해 시스템 콜 테이블이

변경되었다면 각 엔트리의 단순 비교로써 쉽게 알아낼 수 있고 이를 복구할

수 있다. [그림 3-6]는 이러한 과정의 주요 코드이고, [그림 3-7]은

순서도이다.

Page 27: 원본 이미지 비교에 의한 커널 백도어 검사 및 복구 Kernel …ii Abstract Recently, Kernel Backdoor is introduced as a new method of attacking a system as reports

21

void compare_syscall_table(void){ … for(i=0; i<NR_SYSENT; i++) { if(kmem_sct[i] != img_sct[i]) { // 시스템 콜 엔트리 단순 비교 mark_changed(i); // i번째 엔트리가 변경되었음을 체크 … } }}

[그림 3-6] 시스템 콜 테이블 엔트리를 비교하는 주요 코드

원본이미지로 부터 얻은 i번째 시스템 콜 img_sct[i]

커널의 i번째 시스템 콜 kmem_sct[i]

img_sct[i] ==kmem_sct[i]

i <= NR_SYSCALL

kmem_sct[i] = img_sct[i]

i++T

T

F

[그림 3-7] 시스템 콜 테이블에 대한 변경 여부 검사 및 복구 알고리즘

Page 28: 원본 이미지 비교에 의한 커널 백도어 검사 및 복구 Kernel …ii Abstract Recently, Kernel Backdoor is introduced as a new method of attacking a system as reports

22

3.4.4 시스템 콜 코드 변경 여부 검사 및 복구

3.3절에서는 각 시스템 콜의 시작 주소와 코드 크기 정보를 구축 하였다. 이

정보를 이용하여 각 시스템 콜 코드의 변경 여부를 검사하고 복구 할 수 있다.

하지만 복구의 경우 다음과 같은 문제 때문에 사용자 영역에서는 복구가

불가능하고 커널 영역에서만 복구가 가능하다.

§ 복구하려는 시스템 콜이 다른 사용자의 서비스를 수행하고 있는 경우

해당 시스템 콜을 사용하는 사용자에게는 큰 문제가 될 수 있다.

§ 시스템 콜을 복구하는 도중 인터럽트나 다른 기타 사항에 의해

블록된 이후 다른 사용자의 시스템 콜 요청을 받는 경우 또한 문제가

발생할 수 있다.

따라서 이러한 문제를 해결하기 위해서는 LKM을 이용하여 커널 영역에서

모든 인터럽트를 클리어(clear)시킨 상태에서 복구를 수행하여야 한다.

사용자 영역에서 시스템 콜 코드의 변경여부를 검사한 후 코드가 바뀌었으면

이 정보, 즉 시스템 콜의 번호, 시작주소, 크기 정보를 로그에 저장하고 이

정보를 LKM에서 읽어들여 시스템 콜 코드를 복구한다. 단 복구시에는 반드시

인터럽트를 클리어 시켜야한다. [그림 3-8]는 시스템 콜 코드의 변경여부를

사용자 영역에서 탐지하는 과정의 중요 코드이다. 저장된 시스템 콜 코드

정보에서 해당 시스템 콜 코드의 크기를 가져오고, 커널의 시스템 콜

테이블을 참조하여 해당 시스템 콜의 코드를 가져온다. 그리고 커널

이미지로부터 원본 시스템 콜 코드를 가져오고, 이를 1바이트씩 단순

비교한다. 만약 시스템 콜 코드가 변경되었다면 이 정보를 로그에 기록한다.

기록된 정보는 이후 LKM에서 참조하여 복구하는데 사용한다.

Page 29: 원본 이미지 비교에 의한 커널 백도어 검사 및 복구 Kernel …ii Abstract Recently, Kernel Backdoor is introduced as a new method of attacking a system as reports

23

void compare_syscall_code(void){ … for(i=0; i<NR_SYSENT; i++) { code_sz = get_code_size(i) ; // code size DB로 부터 va = (unsigned long) img_sct[i]; // syscall_table 의 주소 kmem_code = get_kmem_syscall_code(…); … org_code = get_img_syscall_code(…); … for(j=0; j<code_sz; j++) if(org_code[j] != kmem_code[j]) changed = 1; … if(changed) logging_changed_syscall(i); // logging }}

[그림 3-8] 사용자 영역에서 시스템 콜 코드를 비교하는 주요 코드

이제 시스템 콜 코드 변경여부를 확인하였다. 만약 악의적인 사용자에 의해

시스템 콜 코드가 변경되었다면 이 시스템 콜에 대한 정보가 로그 파일에

기록된다. 이후 LKM에서는 이 정보를 참조하여 시스템 콜 코드를 복구한다.

[그림 3-9]는 LKM에서 시스템 콜 코드를 변경하는 주요 코드이다.

시스템 콜 코드 복구를 위해 LKM은 로그 파일의 정보를 읽어오고, 이

정보들을 파싱해서 해당 구조체를 할당하여 정보를 저장하고, 해당 구조체를

리스트에 저장한다. 여기서 생성된 모든 리스트에 대해서 시스템 콜 코드를

복구하는데, 복구하기전 반드시 인터럽트를 클리어 시키는 과정이 필요하며

복구를 마치면 인터럽트를 원상태로 복구시킨다.

[그림 3-10]은 사용자 영역의 프로그램과 LKM 사이의 관계를 간략화해서

보여준다.

Page 30: 원본 이미지 비교에 의한 커널 백도어 검사 및 복구 Kernel …ii Abstract Recently, Kernel Backdoor is introduced as a new method of attacking a system as reports

24

extern sys_call_table[];

void parse_log(void) // 로그 정보 파싱{ ...}

void recover_syscall_code(void){ … _cli(); // 인터럽트 클리어 sys_call_table[i]를 org_syscall_code로 복구 ; _sti(); // 인터럽트 복구 ...}

[그림 3-9] LKM에서 로그 정보를 참조하여 시스템 콜을 복구하는 주요 코드

원본이미지로 부터 얻은 i번째 시스템 콜 코드

org_sys_code[i]

커널의 i번째 시스템 콜 코드kmem_sys_code[i]

코드 크기만큼한 바이트씩 비교

i <= NR_SYSCALL

Log에 기록

i++

코드 크기 DB로부터 i번째시스템 콜 코드 크기를 가져옴

코드가 바뀌었으면

로그의 정보를 읽는다

Clear Interrupt

시스템 콜 코드 복구

Store Interrupt

user space kernel space

[그림 3-10] 시스템 콜 코드 변경여부 검사 및 복구

Page 31: 원본 이미지 비교에 의한 커널 백도어 검사 및 복구 Kernel …ii Abstract Recently, Kernel Backdoor is introduced as a new method of attacking a system as reports

25

제 4 장 실험 및 실험 결과

본 장에서는 본 논문에서 제안한 3장의 원본 이미지 비교에 의한 커널

백도어 검사 및 복구 시스템을 구현하여 커널 백도어를 탐지하고, 커널

백도어에 의해 변형된 커널을 복구할 수 있는지를 확인한다.

본 실험은 Wow Linux 7.1에서 이루어 졌으며, 커널은 가장 최근의

안정버전인 Linux Kernel 2.4.18을 사용하였다. Pentium III 750Mhz의

중앙처리장치와 1GB 메모리 사양의 시스템을 실험에 사용하였다.

실험은 현재 알려진 커널 백도어에 대해 기존의 커널 백도어 탐지 도구들과

본 논문에서 제안한 시스템에서의 탐지 여부를 알아보고, 또한 외부에서 실제

운영중인 리눅스 서버들에 대해 커널 백도어에 의한 변형이 있었는지를

검사한다.

4 . 1 커널 백도어 탐지 실험

[ 실험 1 ] 기존의 커널 백도어 탐지 도구와의 비교실험

본 실험은 기존의 알려진 커널 백도어에 대한 기존의 커널 백도어 탐지

도구에 대한 탐지 여부와 본 논문에서 제안한 시스템의 탐지 여부를 비교하는

실험이다.

[표 4-1]은 기존의 알려진 커널 백도어와 그 기법을 정리한 것이다. 커널

백도어는 2장에서 분류한 방법과 같이 시스템 콜 테이블을 변경하는 방법과

시스템 콜 코드를 수정하는 방법으로 분류하였다. [표 4-2]는 기존의 커널

백도어 탐지 도구를 정리한 것이다. 이 또한 2장에서의 분류와 같이 심볼

주소를 검사하는 방법과 심볼의 주소 범위를 조사하는 방법으로 분류하였다.

Page 32: 원본 이미지 비교에 의한 커널 백도어 검사 및 복구 Kernel …ii Abstract Recently, Kernel Backdoor is introduced as a new method of attacking a system as reports

26

[표 4-1] 알려진 커널 백도어 비교

기법 시스템 콜 테이블 변경 시스템 콜 코드 변경

이름 adore knark SuckIT Anti-btrom

주요기능

� 파일, 프로세스 숨기기

� 루트 권한 주기

� 자기자신 숨기기

LKM 지원없이

커널 백도어

설치가능

커널 코드를 직접

수정

[표 4-2] 기존의 커널 백도어 탐지 도구

기법 심볼 주소 검사 심볼 주소 범위 검사

이름 KSTAT Btrom

탐지방법

System.map 파일 참조하여 각

시스템 콜 테이블 엔트리 주소

비교

각 시스템 콜 엔트리 주소의

범위를 검사

[ 실험 2 ] 운영중인 리눅스 서버들에 대한 커널 백도어 검사

본 실험은 실제 운영중인 외부의 여러 서버들에 대해 커널 백도어에 의한

시스템의 변경여부를 검사한다. 실험 대상 시스템은 외부의 여러 회사와

연구실 그리고 개인의 도움을 받아 총 32대의 시스템에 대하여 실험이

진행되었다. 검사 대상 시스템은 모두 리눅스 기반의 서버이고, 커널 버전

2.4이상의 시스템이다.

Page 33: 원본 이미지 비교에 의한 커널 백도어 검사 및 복구 Kernel …ii Abstract Recently, Kernel Backdoor is introduced as a new method of attacking a system as reports

27

4 . 2 실험 결과

[ 실험 결과 1 ]

[표 4-3] 기존 탐지도구와 제안된 탐지도구의 비교실험 결과

KSTAT Btrom 제안된 시스템(aegis )

adore ○ ○ ○

knark ○ ○ ○

SuckIT ○ ○ ○

Anti-btrom × × ○

[표 4-3]은 기존 커널 백도어 탐지 도구와 제안된 시스템에서의 각 커널

백도어 탐지 여부의 결과를 보여주는 표이다. 단, KSTAT의 결과는

System.map 파일의 변형이 없었다고 가정한 상태에서의 결과인데, 만약 해당

파일을 변형한다면 KSTAT은 어떠한 커널 백도어도 탐지할 수 없다. 반면

Btrom은 각 시스템 콜 핸들러의 주소 범위로써 검사하기 때문에 adore,

knark, SuckIT은 탐지할 수 있었다. 하지만 시스템 콜 코드를 수정하는 Anti-

btrom은 탐지할 수 없었다.

제안된 시스템은 커널의 원본 비교를 통해 시스템 콜 테이블을 변경하는

adore, knark, SuckIT은 물론 시스템 콜 코드를 변경하는 Anti-btrom 또한

탐지할 수 있었다.

Page 34: 원본 이미지 비교에 의한 커널 백도어 검사 및 복구 Kernel …ii Abstract Recently, Kernel Backdoor is introduced as a new method of attacking a system as reports

28

[ 실험 결과 2 ]

[표 4-4]는 현재 운영중인 리눅스 서버 시스템에 대해 제안된 시스템을

이용하여 커널 백도어를 탐지한 결과를 나타내는 표이다.

[표 4-4] 대상 서버의 탐지 결과

대상 기관 및 서버수 탐지 여부

(주) 나루기술 � 2대 발견되지 않음

(주) SOVIK � 5대 발견되지 않음

(주) XCE � 2대 발견되지 않음

AI Lab (인하대) � 3대 발견되지 않음

SC Lab (인하대) � 5대 발견되지 않음

기타 � 15대 발견되지 않음

실험 결과 약 30여대의 리눅스 시스템 중 커널 백도어가 탐지된 시스템은

없었다. 이러한 결과가 나온 이유는 커널 백도어가 알려진지 얼마되지 않았고,

커널 백도어를 설치하기 위해서는 우선 공격대상 시스템에 대한 루트 권한을

획득하여야 하기 때문이다. 그리고 실험 시스템의 수도 적어 실제 상황을

알아 보기엔 부족하였다.

Page 35: 원본 이미지 비교에 의한 커널 백도어 검사 및 복구 Kernel …ii Abstract Recently, Kernel Backdoor is introduced as a new method of attacking a system as reports

29

제 5 장 결론

기존의 LKM 백도어 기법들은 단순히 시스템 콜 테이블의 정보를

수정함으로써 공격자의 변형된 시스템 콜이 수행되도록 하는 기법들이

대부분이었다. 이에 대부분의 LKM 백도어 탐지 도구들도 시스템 콜 테이블의

정보만을 가지고 LKM 백도어를 탐지하였다. 하지만 시스템 콜 코드를

수정하는 기법이 소개되고 이러한 기법의 LKM 백도어가 발표되면서 기존의

LKM 백도어 탐지 도구들로써는 정확한 탐지가 불가능하게 되었다.

LKM 백도어에 대한 탐지가 어느 정도 가능하다 하더라도 시스템이 가동중인

경우 이를 복구한다는 것은 거의 불가능하였다. 따라서 시스템을 다시

시작하고 이 과정에서 LKM 백도어를 검출하여 시스템에 설치되지 않도록

하는 기법들이 소개되어있다.

이에 본 논문에서는 시스템을 재시작하지 않고 커널의 부트 이미지와 현재

실행중인 커널의 이미지를 비교하여 현재 실행중인 커널에 어떠한 변경이

있는지 검사하고, 이상이 있으면 이를 복구하는 시스템을 제안하였다. 그리고

제안된 시스템을 통해 기존의 LKM 백도어에 대한 탐지와 복구 실험을 하였고,

실험 결과 기존에 알려진 대부분의 LKM 백도어에 의한 커널의 변경여부를

탐지할 수 있었고 이에 대한 복구도 할 수 있었다.

하지만 본 논문에서 제안한 시스템은 시스템 콜에 관련된 부분만을 검사하기

때문에 네트워크 관련 LKM 백도어에 관해서는 탐지 및 복구가 불가능하며,

그리고 커널을 변형시킨 LKM 백도어에 관한 처리 부분도 미흡하다.

향후 네트워크 관련 LKM 백도어에 관한 연구와 시스템 복구후 LKM

백도어에 관한 처리가 연구되어야 할 것이다.

Page 36: 원본 이미지 비교에 의한 커널 백도어 검사 및 복구 Kernel …ii Abstract Recently, Kernel Backdoor is introduced as a new method of attacking a system as reports

30

참고 문헌

[1] sd, Linux on-the-fly kernel patching whitout LKM, Phrack 58-07,

http://www.phrack.com/phrack/58/p58-0x07, 2001.

[2] Silvio Cesare, Runtime Kernel Kmem Patching, Corezine volume 2,

http://khdp.org/docs/project/Corezine/2/Corezine-2-2.txt, 1999.

[3] palguez, Weakening the Linux Kernel, Phrack 52-18, http://

www.phrack.org/phrack/52/P52-18, 1998.

[4] Massimo Bernaschi, Emanuele Gabrielli, Luigi V. Mancini, "Operating

System Enhancements to Prevent the Misuse of System Calls," Proc. of the

ACM Conference on Computer and Communications Security, 2000.

[5] Christina Warrender, Stephanie Forrest, Barak Pearlmutter, "Detecting

Intrusions Using System Calls: Alternative Data Models," Proc. of the IEEE

Symposium on Security and Privacy, 1999.

[6] Terrance Mitchem, Raymond Lu, Richard O'Brien, Kent Larson, "Linux

Kernel Loadable Wrappers," Proc. of the IEEE DARPA, 2000.

[7] Pietro Iglio, "TrustedBox: a Kernel-Level Integrity Checker," Proc. of

the IEEE 15th Annual Computer Security Applications Conference, 1999.

[8] Pragmatic, Complete Linux Loadable Kernel Modules, http://packetst

orm.decepticons.org/docs/hack/LKM_HACKING.html, 1999.

[9] Dino Dai Zovi, Kernel Rootkits, http://rr.sans.org/threats /rootkits.php,

2001.

Page 37: 원본 이미지 비교에 의한 커널 백도어 검사 및 복구 Kernel …ii Abstract Recently, Kernel Backdoor is introduced as a new method of attacking a system as reports

31

[10] Toby Miller, Detecting Loadable Kernel Modules, http://www.s0ftpj.

org/docs/lkm.htm, 2001.

[11] Jonathan Clemens, Knark: Linux Kernel Subversion, http://www.san

s.org/newlook/resources/IDFAQ/knark.htm, 2000.

[12] Ricardo Quesada, Anti BTRom, http://www.securitybugware.org

/Linux/797.html, 1999.

[13] 정현철, 커널 기반 루트킷 분석 보고서, http://www.certcc.or.kr/paper

/incident_note/in2000004.html, 2000.

[14] Daniel P.Bovet, Understanding the Linux Kernel, pp. 233-248,

O'Reilly, 2001.

[15] Alessandro Rubini, Linux Device Drivers, 2nd edition, O'Reilly, 2001.

[16] Michael Beck, Linux Kernel Internals, 2nd edition, pp. 279-292,

Addison Wesley, 1997.

[17] 김성수, 김기창, "리눅스 커널 모듈 백도어 방지에 관한 연구," 제 28회

한국정보과학회 추계학술발표회 논문집(I), pp. 634-636, 2001.

[18] 홍철호, 고영웅, 김영필, 유혁, "커널 백도어 모듈 탐지 및 차단에 관한

연구," 제 17회 한국정보처리학회 춘계학술발표 논문집(하), pp. 971-974,

2002.

[19] 김일용, 김기창, "커널이미지 비교에 의한 커널 무결성 검사 및 복구," 제

29회 한국정보과학회 추계학술발표회 논문집(I), pp. 562-564, 2002.

Page 38: 원본 이미지 비교에 의한 커널 백도어 검사 및 복구 Kernel …ii Abstract Recently, Kernel Backdoor is introduced as a new method of attacking a system as reports

32

감사의 글

이제 새로운 시작을 위해 지난 2년여의 석사과정을 마무리 할 때가

되어갑니다. 많은 것을 배우고 또 많은 것을 경험했던 지난 시간들, 소중한

기억들이 저의 새로운 생활에 많은 도움이 될것입니다. 지난 2년여간의

소중한 기억들을 되돌아 보며 그동안 도움을 주셨던 분들게 이 글을 빌어

감사의 말을 전합니다.

부족했던 저에게 언제나 밝고 해박한 지식과 정으로 대해주시고 아껴주신

김기창 교수님께 마음에서 우러나오는 감사를 드립니다. 또한 바쁘신

와중에도 깊은 관심으로 지켜봐주신 전자계산공학과의 모든 교수님들께도

감사 드립니다.

저에게 대학원 생활과 더불어 새로운 사회경험을 쌓을 수 있도록 배려해

주신 한서대학교 심종익 교수님께도 감사 드립니다.

제 대학원 생활의 시작에 가장 큰 도움을 주신 동호형, 회사일 같이하며

많은걸 배울수 있었던 우리 연구실 대장 대성이형, 자칭 연구실의

마스코트이며 순수한 마음을 가진 병룡이형, 연구실 생활과 회사일 같이 했던

성수형, 선애, 우리 연구실 최고의 정리의 달인이자 낙천적인 성격의 정섭이형,

웃는 모습이 활짝핀 장미꽃이라고 우기는 윤이형, 우리 연구실의 막내이자

귀염둥이 호익, 연구실 생활과 더불어 회사일 거기에 얼마전 결혼까지 정말

힘들 것 같은 일경이형, 너무 말라서 안쓰러운 영욱이형, 진정한 제주인의

참모습 장태씨, 이 모든 연구실 가족들에게도 감사의 말을 전합니다.

그리고 같은 연구실에서 생활하진 않았지만 같이 보냈던 즐거웠던 시간들을

기억하며 선호형, 종현이형, 호석이형, 영호, 용환, 용집, 상근. 재훈에게도

Page 39: 원본 이미지 비교에 의한 커널 백도어 검사 및 복구 Kernel …ii Abstract Recently, Kernel Backdoor is introduced as a new method of attacking a system as reports

33

고맙다는 말을 하고싶습니다.

지난 8년간의 대학생활에서 언제나 나의 기억속에 남을 우리 전자계산공학과

학생회…. 언제나 형처럼 옆에서 지켜봐주던 태삼이형, 나의 대학 생활에

커다란 영향을 준 성웅이형, 동기들 보다 더 많은 시간을 같이 보낸 94학번

선배들(호일이형, 성우형, 수진이형, 병기형, 정길이형, 덕호형, 그리고 특히

미안한것도 많고 고마운것도 많은 무성이), 영원히 나의 기억속에 남을 우리

동기들(언제나 믿음직한 승빈이, 우리 연구실 새내기로 들어오는 상현이,

신혼의 단꿈에 젖어있을 미옥이, 올해는 남자친구 만들겠다고 호언장담하는

윤경이, 길눈은 좀 어둡지만 언제나 씩씩하게 생활하는 여군장교 예비역 성희,

자바의 대가이지만 지금은 열심히 C 포팅을 하고 있는 실력파 보형이),

그리고 일일이 이름을 나열하진 못하지만 지난 세월 속에서 저에게

힘이되어주었고 같은 추억들을 가진 모든 선배님, 동기, 후배님들께도

감사한다는 말을 전합니다.

고향을 떠나 타지에서 생활하며 커다란 안식처가 되어 주었던 나의 고마운

친구들(상열이, 려주, 주형이), 4~5살차이의 터울을 따뜻한 관심과 배려로

매워 주셨던 동문 선배님들(의철이형, 승훈이형, 진만이형, 재홍이형, 준현이형,

계홍이형), 그리고 많은 관심을 가져주지 못해 언제나 미안했던 후배들(남헌,

재홍, 형주, 성희, 상준, 진수, 충선, 혜선, 승현, 동영, 기조, 창연, 지연,

종윤이) 모두 고맙습니다.

마지막으로 지금까지 저에게 가장 큰 힘을 주시고 언제나 사랑과 믿음으로

저를 보살펴 주신 아버님, 어머님 두분 부모님과 동생 일혁이에게 진심으로

사랑한다는 말과 함께 이 논문을 드립니다.

2003년 1월 일용이가 모든 분께 감사드리며…