摘要:特洛伊木馬作為一種新型的計算機網絡入侵程序,比其他病毒對網絡環境中計算機信息資源的危害都要大。提出利用木馬的一個重要特征——自啟動特性對其進行監控。通過掛接系統服務,對注冊表和文件系統進行監控,從而實現木馬檢測。與傳統的檢測方法相比,這種方法能有效地檢測已知的和新出現的木馬。由于是在內核中實現監控,一般木馬很難逃避這種檢測。
關鍵詞:木馬; 自啟動特性; 系統服務調度表; 掛接
中圖分類號:TP309.5文獻標志碼:A
文章編號:1001-3695(2007)05-0141-03
0引言
隨著網絡技術的迅速發展,網絡安全日益引起人們的重視,因為計算機病毒、特洛伊木馬、網絡蠕蟲等惡意軟件會給正常的社會生活造成巨大的損失。在這些惡意軟件中,特洛伊木馬因為其獨特的作用,備受黑客的青睞,被廣泛使用。
特洛伊木馬是指一種計算機程序,這種程序通常偽裝成一個正常的程序,以欺騙的方式誘使用戶運行,運行以后潛伏在入侵主機中,偷偷地搜集用戶的敏感資料;當接收到控制端發送來的特定命令時,就將這些敏感資料通過網絡發送出去,造成泄密事件,或控制入侵主機,造成鎖定主機、重新啟動甚至破壞系統等,具有極大的危害性。特洛伊木馬不同于普通的計算機病毒,病毒的危害一般是造成數據的破壞或是造成網絡的擁塞,而木馬的危害在于信息的泄漏。特別是對政府、軍隊等保密性要求比較高的部門來說,木馬的危害性更大。
目前,木馬檢測所采用的技術主要是特征碼檢測技術,即將木馬看做是一種特殊的病毒,提取木馬樣本的特征碼,放到病毒庫中;掃描系統時,如果被掃描的文件與特征碼符合,則斷定其是木馬程序。特征碼技術對檢測已知病毒、木馬和蠕蟲等惡意代碼非常有效,算法簡單,檢測迅速,因此目前也被業界所廣泛使用。但特征碼技術有一個先天缺陷就是只能檢測已知的惡意代碼,面對每天大量涌現的新惡意代碼卻無能為力。
本文提出一種新的檢測方法,此方法利用木馬所共同具有的一個特征來進行檢測,使其不僅能夠檢測已知的木馬程序,而且能夠檢測新出現的或未知的木馬。
1木馬的共有特征
自第一個特洛伊木馬誕生以來,經過多年的發展,特別是隨著互聯網的普及,到現在為止,已經有幾萬種木馬程序。雖然這些程序使用不同的程序設計語言編寫,在不同的環境下運行,但是木馬不同于普通的病毒程序,因為它的主要目的是相似的,都是為了遠程控制和竊取資料,因而所有的木馬存在一些共同的特征。其中,一個木馬必須具備的特征可以總結為以下幾個:
(1)隱蔽性
隱蔽性是木馬的首要特征。木馬程序為了悄悄地長期運行于入侵主機中,往往會千方百計地隱藏自己,不被發現。比較簡單的木馬一般要隱藏自己的窗口;技術比較復雜一些的木馬會將自己偽裝成系統進程或是系統服務,還有的木馬將自己的代碼注入到別的合法進程中去;技術比較高級一些木馬會以驅動程序的形式修改內核,讓用戶查看不到它的存在。
(2)自動運行性
木馬為了長期控制入侵主機,一般會修改系統的注冊表或配置文件,以便在系統重新啟動以后,自動加載木馬程序;如果一個木馬程序不能自動運行,那么每次重啟,入侵者都要重新攻擊。在注冊表的某些項例如HKLM\\Software\\Microsoft\\Windows\\Current Version\\Run中設置內容為“c:\\Windows\\system32\rojan.exe”,則系統啟動以后會自動運行trojan.exe這個程序。修改系統的win.ini、system.ini、autorun.bat等系統配置文件也可以達到同樣的效果。
(3)功能特殊性
木馬的目的就是控制入侵主機或者竊取敏感資料,因而木馬必然會具有一些特殊的功能,如搜索計算機的口令、記錄鍵盤操作、遠程抓屏,甚至會鎖定鍵盤和鼠標、刪除系統文件、破壞系統等功能。
(4)網絡通信
為了遠程控制入侵主機,木馬程序肯定會有網絡通信功能。初期的木馬會在服務器端開一個端口,監聽控制端發來的命令。現在的木馬為了更加隱蔽自己,不再開啟通信端口,而是利用ICMP包通信,或者是采用反彈端口形式實現通信。但不管采用哪種技術,網絡通信是木馬必須具有的功能。
一個成功的木馬必須具備上面的五個特征,如果用S表示木馬成功植入和運行,C1~C4表示上述的四個木馬必備的特征,則可用表達式如下表示它們之間的關系:
因此,可以利用上述的任何一個特征來防范木馬入侵。一旦阻止了一個木馬程序的某一特征的實現,它就不能成功安裝或不能完成入侵以及竊取等功能。本文主要針對木馬的自啟動特性來完成對木馬的防范。
2木馬自啟動的實現
為了使木馬程序在系統重新啟動以后能夠自動運行,木馬程序利用了很多操作系統的特性。例如修改注冊表,很多木馬利用了注冊表中RUN、RUNSERVICE等鍵值,實現自啟動;還有的木馬修改系統配置文件,如win.ini、system.ini文件等。下面介紹木馬最為常用的自啟動機制:
(1)系統啟動文件夾
在Windows的文件系統中,有個文件夾是專門存放系統啟動以后自動運行的程序。下面給出系統的文件夾:
C:\\Windows\\start menu\\programs\\startup
C:\\WINDOWS\\All Users\\Start Menu\\Programs\\Startup
這是最基本、最常用的Windows啟動方式,主要用于啟動一些應用軟件的自啟動項目,如Office的快捷菜單。一般用戶希望啟動時所要啟動的文件也可以通過這里啟動,只需把所需文件或其快捷方式放入文件夾中即可。這個文件夾是可以更改的,雖然文件夾中的內容在默認狀態下可以被用戶看得一清二楚,但通過改動還是可以達到相當隱蔽的啟動目的。
(2)系統配置文件
由于系統的配置文件對于大多數的用戶來說都是相當陌生的,這就造成了這些啟動方法相對來說都是相當隱蔽的。有的木馬就是通過修改配置文件實現自啟動的。這兩個系統配置文件是WIN.INI和SYSTEM.INI。
WIN.INI文件格式如下:
[Windows]
Load=trojan.exe
這樣設置,程序Trojan就會在系統啟動以后自動在后臺運行。
SYSTEM.INI文件格式如下:
[Boot]
Shell=Explorer.exe
可以將Shell的內容改為Shell=Explorer.exe trojan.exe,這樣,系統啟動后就會自動運行Explorer和Trojan兩個程序。
(3)注冊表啟動
注冊表中的啟動應該是被使用最頻繁的啟動方式,但這樣的方式也有一些隱蔽性較高的方法。常規的啟動方法是在下列鍵值中設置要啟動的程序:
HKLM\\Software\\Microsoft\\Windows\\Current Version\\Run
HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce
HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\RunServices
HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\RunServicesOnce
HKCU\\Software\\Microsoft\\Windows\\Current Version\\Run
HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce
例如,在HKLM\\Software\\Microsoft\\Windows\\Current Version\\Run中,新建一個字符串型的值,字符串的內容為C:\\WINDOWS\\System32 \ewtrojan.exe,那么系統再次啟動以后,就會自動運行newtrojan.exe這個程序。除此之外,注冊表中還有一些地方經常被特洛伊木馬所利用。例如在HKEY_CLASSES_ROOT\xtfile\\shell\\open\\command中,系統默認的值為%SystemRoot%\\system32\\NOTEPAD.EXE%1,這樣就將以.txt為后綴的文本文件和NOTEPAD.EXE這個應用程序關聯起來,每次用戶打開文本文件時,系統就會自動調用NOTEPAD這個應用程序。而有的木馬,如冰河,就修改了這個鍵值,將其修改為%SystemRoot%\\system32\\SYSEXPLR.EXE %1,這樣,當用戶每次打開文本文件時,系統就會自動調用SYSEXPLR這個程序,這實際上是一個木馬程序。木馬程序運行后,再去啟動NOTEPAD程序,這樣用戶可能很難察覺系統已經運行了木馬程序。綜上可以看出,只要能夠從底層對上述的幾個文件和目錄以及注冊表中與自啟動相關的目錄進行監控,就可以監控木馬的入侵。而如何從底層進行監控呢,筆者采用的是從驅動層掛接系統服務調度表的技術。
3Windows系統服務調用機制
所謂系統服務是由操作系統提供的一個函數集,應用程序可以通過API函數直接或間接地調用系統服務。在Windows操作系統中,應用程序是運行在Win32子環境中的。Win32子環境為應用程序提供了一套動態鏈接庫。其中包括Kernel32.dll、Advapi32.dll、User32.dll和Gdi32.dll等。應用程序調用系統服務主要是通過上面的動態鏈接庫提供的API函數實現的。
在操作系統中存在兩種模式,即用戶模式和內核模式。一般的應用程序都是運行在用戶模式,只有操作系統等關鍵組件才運行于內核模式。將系統分為用戶模式和內核模式有利于系統的安全和穩定。從用戶模式調用本機系統服務是通過NTDLL.DLL來實現的。例如Kernel32.dll通過Ntdll.dll這個動態鏈接庫來真正地觸發系統調用服務,Ntdll.dll執行INT指令產生陷阱,由用戶態進入到內核態,系統服務真正地實現是在ntoskrnl.exe中完成的。也就是說NTDLL.DLL只是系統服務調用接口在用戶模式下的一個外殼。
創建一個文件和創建一個注冊表的項對于Windows的系統服務調用機制是一樣的,只是調用的函數不同而已。下面就以注冊表為例。而注冊表操作的系統服務是在ntoskrnl.exe中實現的,所以以ntoskrnl.exe為例。它們之間的關系如圖1所示。
當應用程序在注冊表中創建一個新的項目時,就會調用Advapi32.dll 中的RegCreateKey函數,RegCreateKey函數檢查傳進來的參數是否有效,并將它們都轉換成Unicode碼。接下來,RegCreateKey就會調用Ntdll.dll中的NtCreateKey函數。由于每一個系統服務都對應著一個系統服務號,NtCreateKey函數將系統服務號填入到寄存器EAX中,然后再將參數在堆棧中的指針賦給寄存器EDX,最后觸發INT 2E指令,從用戶態進入到內核態。系統服務調用模型大體如下:
mov eax, ServiceId
lea edx, ptrParameter
int 2eh
ret
其中,ServiceId是系統服務號,ptrParameter是參數在堆棧中的位置。
進入內核態之后,系統調用KiSystemService函數,內核根據系統服務號在中斷描述表(IDT)中查找相應的系統服務指針。這個指針指向函數ZwCreateKey,然后執行這個服務程序。服務程序首先將參數從用戶態的堆棧空間拷貝到內核態的堆棧空間,最后執行具體的服務功能。
Windows中默認存在兩個系統服務調度表,它們對應了兩類不同的系統服務。這兩個調度表分別是KeServiceDescriptorTable和KeServiceDescriptorTableShadow。系統服務調度表KeServiceDescriptorTable定義了在ntoskrnl.exe中實現的系統服務,通常在kernel32.dll/advapi32.dll中提供函數接口均是調用的這個系統服務調度表中的函數;KeServiceDescriptor-TableShadow除了包含上面的系統服務,還包含在Win32k.sys中實現的相關Win32USER和GDI函數,它們是屬于另一類系統服務調用,它提供了內核模式實現的USER和GDI服務。
在Windows 2000操作系統中存在兩類系統服務。一類是Win32內核API經過Kernel32.dll/advapi32.dll進入NTDLL.dll后使用int 0x2e中斷進入內核,最后在ntoskrnl.exe中實現了真正的函數調用;另一類是Win32 USER和GDI API直接通過User32.dll/Gdi32.dll進入了內核,最后是在Win32k.sys中實現了真正的函數調用。
要實現對注冊表和文件系統的寫操作的監控,就需要將系統服務調度表中相應的函數指針重新定位,使它指向本文自定義的函數,在該函數進行完預處理之后,再根據具體情況決定,或者調用原來的系統服務函數,或直接運行后面的程序,這就是系統服務掛接(HOOKING)技術。
4掛接系統服務調度表實現監控
掛接(HOOKING)技術也稱為鉤子技術,是Windows操作系統中一種通用的技術,它可以攔截或監聽可執行代碼在執行過程中的一些信息,可以更改操作系統的行為。可以幫助人們了解系統內部結構、運作機制等。被廣泛應用于事件追蹤、修改系統行為等操作中。
為了實現文件系統以及注冊表的監控,首先要在系統服務調度表中找到需要替換的函數指針,將這個指針指向本文自定義的函數;當調用相應的系統服務時,首先就會執行本文自定義的函數。這樣,就實現了系統服務的掛接。
由于文件系統和注冊表監控只是Hook的內核中的函數不同而已,在此仍以RegCreateKey為例。當它調用Ntdll.dll中的NtCreateKey時,通過軟中斷進入到內核態,每個在Ntdll.dll中導出的以Nt開頭的系統服務占位函數在內核中都有一個相應的以Zw開頭函數與之對應,系統就會根據中斷服務號在系統服務調度表中查找到ZwCreateKey函數,然后執行調用這個函數。如圖2所示,現在,將系統服務調度表中的函數指針指向本文自定義的函數myZwCreateKey,這樣,執行系統服務調用時,就會先執行函數myZwCreateKey,在這個函數中進行筆者所需要的預處理。首先顯示目前試圖添加自啟動特性的進程,然后再根據使用者的選擇。如果用于允許該進程自啟動,則執行原來的ZwCreateKey函數;否則跳過這個系統服務函數,直接執行后面的代碼。
由于系統服務調度表是在內核的ntoskrnl.exe中定義的,如果要對其進行修改,必須使修改程序也要運行在內核態。這樣就需要編寫驅動程序,驅動程序是運行在內核態的。關于驅動程序的編寫在這里就不作詳細描述,下面只給出監控注冊表的掛接注冊程序的主要示意代碼。
//聲明系統服務表
extern PSRVTABLE KeServiceDescriptorTable ;
//定義系統服務入口的宏定義
#define SYSCALL(_function)ServiceTable->ServiceTable[ *(PULONG) ((PUCHAR) _function+1) ]
//掛接注冊表系統服務函數
void HookRegistry(void)
{
//保存原來的服務函數
OldZwCreateKey=SYSCALL(ZwCreateKey);
//掛接自定義函數
SYSCALL(ZwCreateKey)=myZwCreateKey;
}
文件系統監控的掛接代碼與上述代碼基本一樣,只是把ZwCreateKey函數換成NTCreateFile即可。
程序編譯后得到驅動程序,由應用程序加載該驅動程序,就完成了對文件系統和注冊表的監控。由于是在內核態實現的,一般的木馬程序很難逃過這種檢測,具有很好的可靠性。
5結束語
目前檢測特洛伊木馬的應用軟件大多是采用特征碼技術,特征碼技術對檢測已知的木馬等惡意代碼效率很高,但對新出現的木馬無能為力。本文提出并且實現了一種根據木馬的自啟動特性來對其進行監控的方法。實驗證明,本方法能夠成功地檢測出已知的木馬,如冰河、BO2K、SUBSEVEN等,同時,能夠檢測到新的木馬以及有自啟動特性的程序。
本文第2章已經總結了木馬具有五個特性,能夠監控其中任何一個特性,都可以阻止一個木馬程序的入侵。本文只是拋磚引玉地實現了利用自啟動特性來監控木馬入侵。筆者下一步工作是綜合木馬的這五個特性中的全部或一部分,來判斷一個程序或進程是否為木馬。一個程序具有的這些特性越多,則與木馬的相似度越高。
參考文獻:
[1]張友生,米安然.計算機病毒與木馬程序剖析[M].北京:北京科海電子出版社,2003:213-303.
[2]BAKER A, LOZANO J.The Windows 2000 Device Driver Book[M]. [S.l.]:Prentice Hall PTR, 2000:6-300.
[3]RUSSINOVICH M,COGSWELL B.Regmon for Windows NT/9x. [EB/OL]. (2005-08-28)[2005-09-09].http://www.sysinternals.com/ntw2k/source/regmon.shtml.
[4]IVANOV I. API Hooking Revealed[EB/OL].(2005-08-28)[2005-09-09].http://www.codeproject.com/system/hooksys.asp.
[5]RICHTER J. Windows 核心編程[M].王建華,等譯.北京:機械工業出版社,2000:30-43
[6]王雨,傅鶴崗. 掛接系統服務調度表對Win2k的訪問控制[J]. 計算機工程與設計,2005,2(6):407-409.
注:“本文中所涉及到的圖表、注解、公式等內容請以PDF格式閱讀原文”