-
Windows 루트킷 원리> Information Security/Windows 2017. 7. 16. 11:44
루트킷 원리
Windows 환경에서의 루트킷은 DOS 스텔스 바이러스에서부터 유래되었다. 스텔스(Stealth) 방식의 바이러스는 프로세스와 프로세스 사이에 자신을 은닉하는 방법으로써, 일반적인 프로세스 확인(ex:작업관리자)로는 탐지되지 않는다.
루트킷의 은닉하는 특성 때문에 공격자가 침입 후 재진입 할 목적으로 생성하는 백도어로써 존재하기도 한다.
Windows OS에서는 운영체제를 구동하기 위한 핵심코드를 커널 레벨에 둠으로써, 일반적인 응용프로그램과 분리하였다. Ring0의 커널모드, Ring3의 유저모드로 구성되어 있다. 루트킷은 커널레벨에서의 API 호출과정을 이용하여 프로세스를 은닉하는 경우가 있다. 커널모드에서는 유저모드보다 높은 권한을 필요로 하기 때문에 커널모드에서의 루트킷은 CPU나 메모리에 직접 접근이 가능할 뿐 아니라, 탐지하기 어렵다.
일반적인 프로그램 실행 시 CPU와 메모리에서의 동작
‘ABC.exe’라는 파일이 실행 될 때, 가장 먼저 메모리에 공간을 할당한다.프로세스에 대한 정보는 가상메모리 공간에 존재하는데, 가상메모리가 생성된다는 것은 프로세스 하나 이상이 생성되어 실행되고 있다는 의미다. 메모리 공간에 프로세스 공간을 생성하면, CPU에서는 프로세스의 명령어를 실행하기 위해 CPU에서 자원을 일정기간 동안 할당 받는다. 이 때, 메모리에 로드 된 명령어를 ‘스레드’가 실행하는데, 같은 프로세스에 있는 자원과 상태를 공유한다.
프로세스에 대한 정보는 가상메모리 공간에 존재한다. 가상메모리가 생성된다는 것은 프로세스 하나 이상이 실행되고 있다는 의미이다.
※ DLL과 SLL
Windows에서는 프로그램이 실행될 때 마다 자주 사용 되는 함수들은 라이브러리 형태로 존재한다. Windows OS에 내장되어있는지, 프로그램 자체에 포함되어있는지에 따라 DLL과 SLL로 구분될 수 있다.
DLL (Dynamic Link Library,
동적 연결 라이브러리)
SLL (Static Link Library,
정적 연결 라이브러리)
Windows에 내장된 dll
프로그램이 필요로 할 때마다 호출하여 이용
프로그램 자체에 포함된 라이브러리
프로그램 마다 다르게 구현될 수 있다.
ex ) win32.dll , ntdll.dll 등
ex )
<Process Walking>
악성코드가 루트킷 형태로 은닉하기 위해서는 현재 동작하고 있는 프로세스들 중에서 은닉하기 좋은 프로세스를 탐색할 것이다. 이 과정이 Process Walking 이다. 대상 시스템의 메모리 상에서 프로세스 목록을 탐색하는데 사용되는 API함수는 아래와 같다.
CreateToolhelp32Snapshot( )
동작중인 프로세스들의 스냅샷 정보 가져옴
Process32First( )
스냅샷에 기록되어 있는 첫 번째 프로세스
Process32Next( )
프로세스 목록 탐색 가능
은닉을 가능하게 하는 기술로써 IAT Hooking, SSDT Hooking, DKOM 등이 있다.
user/kernel mode
유저영역과 커널영역을 구분하는 기준은 '권한'이다. Ring3의 유저영역보다 Ring0의 커널영역에 더 높은 권한이 요구되며, 하드웨어 컨트롤러, OS 코드, 레지스터와 같이 시스템에 중요한 부분을 담당하는 부분을 커널영역에 둠으로써 쉽게 접근할 수 없는 환경으로 구성하였다.
※ 가상메모리 공간에서의 커널 영역 : 0x800000 이상
예를 들어, 파일을 생성하는 API인 OpenProcess( )는 유저영역과 커널영역에 걸쳐 최종적으로 Native API 함수인 NtOpenProcess ( )을 호출한다.
※ Native API
Win32 API
Native API
CreateFile( )
NtCreateFile( )
ReadFile( )
NtReadFile( )
CreateProcess( )
NtCreateProcess( )
OpenProcessToken( )
NtOpenProcessToken( )
WriteProcessMemory( )
NtWriteProcessMemory( )
이 때, 함수를 호출하는 부분을 유저영역과 커널영역을 나누어 보면 다음과 같다.
ex) OpenProcess( ) API함수의 호출과정
◆ User mode
1. Kernel32.dll(OpenProcess -> OpenProcessW(CALL _imp_NtOpenProcess)
2. NTDLL.dll (_imp_NtOpenProcess( int 0x2E(SYSENTER) )
※int 0x2e (SYSENTER)
유저모드에서 커널모드로 제어이행
(소프트웨어 인터럽트 발생, 유저스택을 커널스택으로 변경시킴)
Windows 2000까지만 커널로의 이행을 수행.
> KiSystemService() 거침
Windowx XP이후부터는 SYSENER을 통해 커널모드로 이행.
※ user32.dll kernel32.dll, ntdll.dll과 같은 DLL파일은 유저영역에 존재한다.
참고)
ntdll.dll에 존재하는 'Zw'는 커널과 연결시켜줌
ex) ZwOpenprocess
kernel32!OpenProcess > ntdll!ZwOpenProcess > ntdll!KiFastSystemcall > Systenter(명령) > msr(레지스터) > nt!KiFastCallEntry(커널) > nt!NTOpenProcess(커널)
◆ Kernel mode
3. 커널모드로 접근
> KiFastCallEntry() 거친 후, Native API인 nt!NTOpenProcess를 가져온다.
커널모드에서 더 자세한 과정은 아래와 같다.
1. KiFastCallentry () -> KiSystemService()2. KiSystemService() : SSDT 주소 값 얻어오고,어플리케이션에서 호출한 API에 맞는 Native API 주소 찾아내서 호출이 때, KiSystemService()는 KeServiceDescriptorTaable에 접근함3. KeServiceDescriptorTable :※KeServiceDescriptorTable의 구성요소(1) SSDT의 주소(2) -(3) NumberOfservice = Native API의 총 갯수(4) KiArgumentTable의 주소 값이 때, KiArgumentTable은 SSPT(System Service Parameter Table)이라고도 불림SSDT의 Native API와 1:1 대응.4. KeServiceDescriptorTable에서 (1)SSDT 주소값 이용하여Native API함수의 엔트리 주소값 얻어옴※SSDT주소(KiServiceTable) + [eax인덱스*4] = Native API 함수 주소=> KiSystemService()의 코드와 동일함.5. Native API함수로 진입ex) CreateFileA() 일 경우, NtCreateFileA()로 진입-----------------------------------------------------------
<참고>
CodeEngn_안티바이러스 자가보호 무력화에 대한 연구- 구사무엘, 김슬기
hi.pe.kr 날으는물고기 blog.pages.kr/448
해커스쿨 초보자를 위한 kernel based windows rootkit 1부 - Beist
http://hisjournal.net/doc/[KUCIS_Project]_Rootkit_Scanner_by_CERT-IS.pdf
보안공학연구논문지 2010년 8월
윈도우 XP 컨러기반 API후킹 탐지도구 설계 및 개발 - 김완경, 소우영
DKOM을 이용한 은닉기법 - 이동수
codeengn.com/archive/ReverseEnginerring/Hooking
Debugging - 코어시큐리티
윈도우 포렌식 실전가이드 - 고원봉
루트킷을 이용한 악성코드 탐지 - 국가사이버안전센터
http://sysenter.tistory.com/entry/SYSENTER
http://ryangs.egloos.com/v/758078
FORENSIC PROOF
728x90반응형'> Information Security > Windows' 카테고리의 다른 글
루트킷 - 프로세스 은닉에 이용되는 기술 (1) 2014.10.30 Win32 API 기초 (0) 2014.06.17 악성코드 탐지 - 툴 사용법 (0) 2014.05.30 Stealth (프로세스 은폐기법) (2) 2012.06.11 API Code Patch (0) 2012.06.11