高級WIN2KROOTKIT檢測技術
發表于:2007-05-25來源:作者:點擊數:
標簽:
摘要:本文描述了一種檢測內核與用戶級rootkit的新技術.此技術利用處理器的單步執行模式,來測定系統內核與DLL中執行指令的數量,從而達到檢測rootkit和后門的目的.同時還討論了其在Win2k下的代碼實現. --背景知識 一個在計算機 安全 領域中重要的問題是,如何判
摘要:本文描述了一種檢測內核與用戶級rootkit的新技術.此技術利用處理器的單步執行模式,來測定系統內核與DLL中執行指令的數量,從而達到檢測rootkit和后門的目的.同時還討論了其在Win2k下的代碼實現.
--背景
知識 一個在計算機
安全領域中重要的問題是,如何判斷給定的主機是否已被入侵.由于以下兩點這項工作變的非常困難:
1.攻擊者可以利用未知漏洞進入系統.
2.當進入系統后,入侵者可通過安裝rootkit和后門來隱藏自身(例如:隱藏進程,通訊渠道,文件等).本文將集中討論在Win2K系統下rootkit的檢測問題.
--傳統rootkit檢測技術中的一些問題
傳統的rootkit檢測程序(那些我們經常在
UNIX系統中見到的)只能檢測一些已知的rootkit(這點使它變的像反病毒程序)或進行一些內核存儲的掃描.例如
Linux中就有一些工具掃描內核中的syscall table.這顯然不夠好,因為已經有了很多并不更改syscall table的rootkit,而Win2k下也可
開發出類似的rootkit.
那檢測程序是不是還應該掃描內核代碼空間?這樣我們就有了一個運行在內核模式中的Tripwire.但這還不夠好,因為在大多數的操作系統中,我們可以寫出即不更改SST(syscall table)也不更改代碼的內核級rootkit.在系統中有很多可以勾連的函數指針(例見[2]).
以我看,存儲掃描技術決不會成為rootkit檢測的終結.這主要是因為我們不能確定具體的監測存儲區域.
那到底怎樣檢測出我們系統中的入侵者呢?
首先我們以rootkit中所使用的技術,將其分為兩類:
*通過更改系統結構來隱藏某對象的(如運行的進程)和
*更改內核執行路徑(例:勾連那些負責枚舉活動進程的內核函數)來達到同樣目的的.
--更改系統數據結構的rootkit
這類的rootkit不太多.有意思的例子包括fu rootkit(見[3]),通過刪除內核中PsActiveProcessList鏈上的進程對象來隱藏進程.ZwQuerySystemInformation等函數是不能發現這些隱藏進程的.但同時,因為Windows的線程分派器(dispatcher, scheduler)使用另外的數據結構,這些"隱藏"進程仍可運行(被分配到CPU使用時間).Windows的線程分派器使用以下三個(注1)數據結構:
*pKiDispatcherReadyListHead
*pKiWaitInListHead
*pKiWaitOutListHead
后兩個是處于"等待"狀態的線程鏈頭.他們之間稍有不同,但對我們來說并不重要.
從上面的信息我們可以找到一種檢測隱藏進程的方法.及讀取線程分派器使用的數據結構,而不是PsActiveProcessList.
當檢測rootkit時我們應該盡可能的觸及更底層的內核數據結構.
有一點應該注意,直接從線程分派器使用的鏈中刪除要隱藏的進程是不可能的,因為隱藏的進程將分配不到CPU使用時間.
--更改執行路徑的rootkit
這類的rootkit較為普及.他們通過修改或增加內核或系統DLL中的指令來達到目的.檢測這類rootkit的問題是,我們不知道rootkit在什么地方做了那些修改.它可以勾連DLL中的函數,系統服務列表(System Service Table),改變內核函數的內容或修改內核中一些奇怪的函數指針.
--執行路徑分析(Execution Path Analysis)
EPA關注這樣一個事實:如果入侵者通過修改執行路徑隱藏了一些對象,那么當調用一些典型的系統和庫的函數時,系統將運行一些多余的指令.
舉個例子,如果入侵者為了隱藏文件和進程而修改了ZwQueryDirectoryFile()和ZwQuerySysteminformation(),那樣和干凈的系統相比,這些系統函數就會執行更多的指令.不管入侵者采用勾連或在代碼中加入jmp指令,或其他任何方法.指令增加的原因是rootkit必須進行它的任務(在這個例子中是隱藏文件和進程).
但是Windows 2000的內核是一個非常復雜的程序,即使在干凈的系統中,某些系統函數每次運行的指令個數也是不同的.然而我們可以用統計學來解決這個問題.但首先,我們需要一種測定指令個數的方法......
--指令計數器的實現
單步執行模式是Intel處理器的一個好的特性,我們可以用它來實現指令計數.當處理器處在這個模式時,每執行完一條指令,系統將產生一個除錯異常(de
bug exception, #DB).要進入這個模式,需要設置EFLAGS寄存器中的TF位(詳見[6]).
當執行int指令時,處理器會自動清TF位并進行權限切換.這意味著,如果要進行內核模式下的指令計數,則必須在中斷處理程序開頭設置TF位.因為我們將要測定一些系統服務中的指令個數,勾連中斷向量0x2e,也就是Windows 2000下的系統服務調用門會變得很有效.
但是,因為存在用戶模式的rootkit,也應該測定在ring3級運行的指令個數.只要在用戶模式下設置TF位一次就可以了,從內核返回時,處理器會自動恢復這一位.
以上的計數方法通過內核驅動器實現.如圖2所示,驅動加載后勾連IDT 0x1和0x2e.為和用戶級程序交互.驅動勾連一個系統調用,用戶級程序通過這個特定的系統調用來開關計數器.
--一些測試
我們可以使用上一段中描述的方法來測定任意系統服務中執行的指令個數.
例如,來檢查是否有人試圖隱藏任意文件,我們可以開始一個簡單的測試:
pfStart();
FindFirstFile("C:\\WINNT\\system32\\drivers", &FindFileData);
int res = pfStop();
如果有rootkit隱藏任意文件,則執行的指令數要比干凈的系統多.
如果運行這個測試上百次,并計算執行指令數的平均值,我們會發現這個值是非常不確定的.考慮Win2k的復雜性,這一點也不讓人吃驚.但對于我們的檢測目的來說,這種現象是不能接受的.但如果我們將得到的那些值的頻率分布用條形圖表示出來,會發現圖中有一個明顯的頻率高點.如圖4和5中所表示那樣的,即使是在系統負載很大時,頻率高點所對應的數值保持不變.很難解釋這個令人吃驚的現象,可能是因為在循環中同一個系統服務被調用幾百次后,與這個系統服務相關的緩沖最后會被填入固定的值.
假想現在有人安裝了隱藏文件的rootkit,如果我們重復測試并繪制相應的條形圖,就會發現頻率高點向右移了,這是因為rootkit需要進行隱藏文件的工作.
在現在的代碼實現中,只進行了少量的測試,包括典型的服務如:文件系統讀取,枚舉進程,枚舉注冊表項以及Socket讀取.
這些測試將有效地檢測出著名的NTRootkit(見[1]),或最近比較流行的Hacker Defender(見[4]),包括它自帶的
網絡后門,當然還包括很多其他的后門.但要檢測出一些更好的后門還要加入一些新的測試.
--誤報和執行路徑跟蹤
雖然對頻率高點的檢測有助于我們處理系統的不確定因素,但有時會發現測試得到的值有小的差值,一般來說不大于20.
有時這會是一個很嚴重的問題,因為我們不能確定那些多出來的指令意味著被入侵或只是正常的誤差.
為解決這個問題,我們使用了執行路徑記錄模式.和單一的EPA模式比較,系統增加了對執行路徑的記錄(包括地址和運行的指令),首先,系統記錄下正常情況下的執行路徑,以后的每一次運行將產生diff文件(正常系統和現行系統之間的比較).
我們應該使用好的反編譯器來分析那些不一樣的地方,以此判定他們是否可疑.圖6是一個diff文件的例子.
現階段的diff文件只記錄下指令的地址,以后可能將兩次測試的不同結果存為PE格式文件,并可用IDA等工具分析.
--檢測 ”offset-in-the-code” 的變化
想象有這樣一個rootkit,它基本和上面提到的 fu rootkit (見[3]) 一樣,但不從PsActiveProcessList中,而是從分派器使用的數據結構中移除進程.我說過那不可能,因為隱藏的進程將分配不到運行時間......
然而,rootkit可以同時更改分派器代碼中所使用數據結構的地址(offset),換句話說,就是使其使用不同的鏈表.但只有分派器使用這個”新的” 鏈表,而系統其他地方還是使用”舊的”鏈表...... (見圖7).
雖然這種技術不會改變執行指令的個數,我們還是能檢測到它,但需要進一步的完善現有的工具.這項功能現在還沒有實現,但應該不是很難.
--針對EPA的攻防
我們可以想到一些能騙過EPA類檢測工具的方法,先把它們分為兩類.
1. 針對特定工具的欺騙
2. 對EPA類技術的通用攻擊
首先,我們考慮一下通用的攻擊方法和怎樣防止這類攻擊.接著討論針對特定工具的攻擊以及怎樣通過多態來預防.
--對EPA類技術的通用攻擊
首先,惡意程序可以勾連包含除錯處理程序(debug handler)地址的IDT入口1,這樣將暫停記錄運行的指令數.當它完成工作時,再恢復 IDT入口1.這樣rootkit中所執行的指令數不會被記錄.
我們可以使用intel的除錯寄存器來防止這類的攻擊.可以使用DR0和DR1寄存器對IDT入口1進行寫保護.并且為防止rootkit向除錯處理程序的開始處寫入Jmp指令,還需對其進行讀保護.換句話說,我們不想讓rootkit發現除錯處理程序的地址.但單純對IDT入口進行讀保護是不行的,系統會藍屏.但有一簡單的解決方法,就是增加額外的一層.見圖9.
還有一種攻擊的方法,在rootkit運行時,其將TF位清零,并在惡意操作完成時恢復TF位,這樣檢測工具也只能發現運行的指令數和正常的系統有細微差別.
另外,rootkit還能檢查TF位, 如發現被跟蹤,則不進行惡意操作.這種行為并不會影響rootkit的正常工作,因為只有被檢測的進程才被設置TF位.
我們可以防止這種攻擊,應該注意到的是運行每一個系統指令前,都會運行我們的除錯處理程序.以下是簡單的防預方法:
如果除錯處理程序發現上一個運行指令是pushf(將EFLAGS寄存器壓入堆棧),則運行如下操作.
and [esp], 0xfffffeff;
及清TF位.同樣,如果下一條指令是popf(從堆棧載入EFLAGS的值),則運行如下操作.
or [esp],0x100;
及設TF位.這樣rootkit就不能更改TF位.
這樣的預防幾乎可夠了,但還不充分.Rootkit仍能以以下方法發現其被跟蹤:
setTFbit();
if (checkTFbit()!=1) {
//we are traced!
}
所以我們需要更改反檢測部分的操作,使其可以記錄TF位有沒有被rootkit更改(比如增加一個TFbitset變量).
popf/pushf不是存取EFLAGS寄存器的唯一指令,其它像iret/int等指令也可以[注2],因此還要加入對這些指令的檢測.
對EGLAGS寄存器的防護部分還沒有被實現.一部分原因是通過對diff文件的分析也可以發現這類攻擊.但以后會增加相應代碼.
--對特定工具的攻擊
如果攻擊者了解關于特定檢測工具的一切,他會有很多種欺騙的手段.比如,可以更改保存指令數的那個變量.
不過這類攻擊具有很強的針對性,如果有很多不同(或非單一版本)的EPA類工具,這樣的攻擊將不會有效.
當然,我們還是希望可以阻止這類攻擊,強大的多態代碼生成器可能是唯一的方法.當管理員安裝檢測工具是,會產生一個獨特的內核驅動和測試程序.
多態代碼生成器部分還沒有被實現.
--相關工作
像文章開頭所述,筆者還沒有發現任何對rootkit的檢測方法,不是基于存儲掃描的.
EPA技術并不被OS所局限,筆者在
linux下也實現了一相關工具,參5中有對其的詳述以及簡單的代碼實現.
References
[1] Greg Hoglund, et al, ROOTKIT home, te
.net://rootkit.com,
[2] palmers, Sub proc_root Quando Sumus, Phrack Magazine, issue 58, 2001.
[3] fuzen_op, fu rootkit, telnet://rootkit.com,
[4] Holy Father, Hacker Defender Home, http://rootkit.host.sk,
[5] Jan Rutkowski, Execution path analysis, Phrack Magazine, issue 59, 2002.
[6] IA-32 Intel Architecture Software Developer’s Manual, vol1-3.
注1: 作者相信這三個鏈表包含了系統中所有的線程.但還需進一步研究.
注2: 參6上列舉了所有和EFLAGS寄存器交互的指令.
原文轉自:http://www.kjueaiud.com
老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月
|