摘要:內(nèi)核級Rootkit是破壞內(nèi)核完整性的最大威脅,它通常通過冒充或篡改合法模塊加載到內(nèi)核。在對內(nèi)核級Rootkit防范技術(shù)進行對比分析的基礎(chǔ)上,提出一種認(rèn)證和檢測相結(jié)合的內(nèi)核模塊加載機制,該機制將內(nèi)核模塊區(qū)分為信任模塊和非信任模塊,加載前者時首先驗證其完整性,加載后者時,驗證其身份和完整性,并實時檢測其對內(nèi)核數(shù)據(jù)的修改。實驗表明,該機制能防范內(nèi)核級Rootkit通過內(nèi)核模塊方式入侵。
關(guān)鍵詞:Rootkit;內(nèi)核級Rootkit;內(nèi)核模塊;Linux
DOIDOI:10.11907/rjdk.151376
中圖分類號:TP309.5
文獻標(biāo)識碼:A 文章編號:16727800(2015)006017003
作者簡介作者簡介:談潘攀(1983-),女,湖南澧縣人,碩士,成都師范學(xué)院計算機科學(xué)系講師,研究方向為計算機網(wǎng)絡(luò)、信息安全、信息技術(shù)。
0 引言
在運行系統(tǒng)中動態(tài)加載或卸載內(nèi)核模塊是大部分現(xiàn)代操作系統(tǒng)具備的基本功能。 Rootkit是攻擊者向計算機系統(tǒng)中植入的、能夠隱藏自身蹤跡并保留超級用戶訪問權(quán)限的惡意程序[1]。它主要分為用戶級和內(nèi)核級兩種,內(nèi)核級Rootkit可入侵操作系統(tǒng)內(nèi)核層,通常會在內(nèi)核空間更改和插入執(zhí)行代碼,它是破壞內(nèi)核完整性的最大威脅。利用模塊機制是內(nèi)核級Rootkit入侵內(nèi)核的常用手段。
1 傳統(tǒng)模塊加載機制安全弱點
內(nèi)核級Rootkit利用傳統(tǒng)內(nèi)核模塊加載機制進入內(nèi)核的方式主要有兩種:一是冒充合法模塊,系統(tǒng)管理員使用正常的加載命令將其加載到系統(tǒng);二是修改靜態(tài)內(nèi)核模塊文件,待系統(tǒng)重啟后加載到系統(tǒng)。研究表明,為了達到入侵目的,其主要修改內(nèi)核空間的下列關(guān)鍵數(shù)據(jù):①系統(tǒng)調(diào)用函數(shù);②系統(tǒng)調(diào)用表;③系統(tǒng)調(diào)用入口函數(shù);④中斷描述符表;⑤虛擬文件系統(tǒng)。
2 相關(guān)防范技術(shù)
2.1 驅(qū)動程序簽名認(rèn)證技術(shù)
Windows采取驅(qū)動程序簽名技術(shù)防范Rootkit[2]。為防止內(nèi)核級Rootkit通過驅(qū)動程序方式加載到內(nèi)核,驅(qū)動程序廠商首先需從認(rèn)證中心如erisign申請獲得軟件發(fā)布證書(SPC), 廠商使用SPC對驅(qū)動程序簽名,簽名信息依據(jù)驅(qū)動程序類別的不同可以作為一個單獨的文件存放,也可以嵌入到驅(qū)動程序文件映像中,簽名后的驅(qū)動程序不能再被修改,否則驗證簽名會失敗。當(dāng)驅(qū)動程序加載到內(nèi)核時,系統(tǒng)會認(rèn)證驅(qū)動程序的證書和簽名,只有證書的合法性和驅(qū)動程序的完整性驗證均通過才能將驅(qū)動加載到內(nèi)核。
2.2 內(nèi)核密封技術(shù)
Linux采用內(nèi)核密封技術(shù)保護內(nèi)核的安全性[3]。Linux使用一種被稱為LIDS的工具保護安全性,LIDS采用能力機制實現(xiàn)了內(nèi)核密封功能,只允許在系統(tǒng)啟動時加載內(nèi)核模塊,系統(tǒng)運行時密封內(nèi)核,包括root用戶在內(nèi)都不能為系統(tǒng)加載模塊。密封內(nèi)核是通過改變相應(yīng)的能力位,使執(zhí)行加載模塊的進程都會被拒絕執(zhí)行。密封內(nèi)核后,除非利用lidsadm和口令,否則系統(tǒng)不允許改變能力位。
2.3 檢測技術(shù)
(1)檢測文件完整性。部分檢測工具通過檢測文件的完整性以防范Rootkit,當(dāng)測定文件被更改時,判定該文件為不安全文件,典型工具如Tripwire和AIDE。Tripwire的工作原理是對每個要監(jiān)控的文件產(chǎn)生一個數(shù)字簽名,保留下來,當(dāng)文件當(dāng)前的數(shù)字簽名與保留的數(shù)字簽名不一致時,則說明現(xiàn)在這個文件必定被改動過了。AIDE通過創(chuàng)建一個指定文件的數(shù)據(jù)庫進行檢測,數(shù)據(jù)庫中包含了許多文件的屬性,如許可、節(jié)點數(shù)、用戶、組、文件大小、創(chuàng)建時間、修改時間、訪問時間等。系統(tǒng)管理員指定對哪些文件和目錄進行跟蹤加密校驗。
(2)檢測內(nèi)核地址。部分檢測工具通過檢測內(nèi)核地址來檢測是否感染Rootkit,當(dāng)檢測到內(nèi)核地址發(fā)生改變后,判定內(nèi)核已經(jīng)感染Rootkit。如Kern_check是一個針對重定向系統(tǒng)調(diào)用函數(shù)的對Rootkit進行檢測的工具,其工作原理是通過比較當(dāng)前內(nèi)存中系統(tǒng)調(diào)用表(通過/dev/kmem)和Linux內(nèi)核編譯產(chǎn)生原始內(nèi)核符號表來檢測內(nèi)核級Rootkit,該映射存于系統(tǒng)/boot/system.map,兩個表的一些表項值不同表明系統(tǒng)調(diào)用函數(shù)被重定向。
3 認(rèn)證與檢測相結(jié)合的內(nèi)核模塊加載機制
通過對防范內(nèi)核級Rootkit技術(shù)的綜合分析可知,防范技術(shù)大致可以分為兩類:一類是主動型,它要求抬高“門檻”,設(shè)置權(quán)限,防止內(nèi)核級Rootkit冒充合法身份進入內(nèi)核;另一類是被動型,它要求加強監(jiān)測,通過檢測相關(guān)數(shù)據(jù)的變化,判定是否發(fā)生Rootkit入侵。從防范手段上看,主動防范可以把不想加載的文件拒之門外,但同時也使合法的模塊要加載到內(nèi)核,也要多一道手續(xù),給用戶造成諸多不便;被動防范可以檢測相關(guān)文件和數(shù)據(jù)的完整性情況,有助于保護系統(tǒng)認(rèn)為重要的文件和數(shù)據(jù),但被動防范是在Rootkit入侵之后,對系統(tǒng)已經(jīng)造成了破壞,并且隨著更隱秘、更高級的入侵手段的出現(xiàn),被動防范可能會束手無策。從防范效果上看,兩種防范手段各有所長,但隨著各種網(wǎng)絡(luò)攻擊手段越來越隱秘,越來越難以防范,兩種手段都出現(xiàn)了不能攔截或檢測的Rootkit。本文設(shè)計一種認(rèn)證和檢測相結(jié)合的內(nèi)核模塊加載機制,將兩種技術(shù)的優(yōu)點結(jié)合起來,從內(nèi)核模塊的身份、完整性、行為3個層面進行防護,切實堵住Rootkit入侵內(nèi)核的渠道。
3.1 整體框架
本文設(shè)計的內(nèi)核模塊加載機制,將內(nèi)核模塊區(qū)分為“信任模塊”和“非信任模塊”。信任模塊指那些管理員認(rèn)為肯定可信的模塊,如用于實驗的模塊、管理員自身開發(fā)的驅(qū)動程序等。對于“信任模塊”,系統(tǒng)不需要驗證其身份,只需要驗證其完整性,即確認(rèn)其是否被篡改過。除信任模塊之外的模塊,就是“非信任模塊”,如第三方開發(fā)的模塊、從互聯(lián)網(wǎng)上下載的驅(qū)動等。在加載“非信任模塊”時,要從內(nèi)核模塊的身份、完整性和行為3個層面進行鑒別。驗證模塊身份,確定模塊來源是否可信;驗證模塊完整性,確定模塊是否被非法篡改;驗證模塊行為,確定內(nèi)核是否因為加載模塊發(fā)生異常改變。如圖1所示,加載內(nèi)核模塊前,首先查看是否為信任模塊,若是,則驗證其完整性,不是,則驗證模塊自身攜帶的證書確認(rèn)模塊的身份。通過了證書認(rèn)證,就和信任模塊一樣,驗證其完整性。內(nèi)核模塊加載到內(nèi)核后,如果該模塊不是系統(tǒng)的信任模塊,要實時檢測內(nèi)核關(guān)鍵數(shù)據(jù)的變化情況,如果內(nèi)核關(guān)鍵數(shù)據(jù)發(fā)生了異常改變,則發(fā)出報警信號,由系統(tǒng)管理員決定是否卸載已經(jīng)加載的模塊。
3.2 工程實現(xiàn)方案
上述機制的實現(xiàn),首先需要一個CA認(rèn)證中心,用于審定模塊開發(fā)者資質(zhì),向信任的模塊開發(fā)者頒發(fā)證書,并負(fù)責(zé)證書的管理;其次要有專門的簽名工具,用于對模塊簽名;還要對系統(tǒng)內(nèi)核進行修改,改變以前的加載流程,引入身份驗證、完整性驗證、內(nèi)核數(shù)據(jù)檢測等環(huán)節(jié)。本文在實驗室里初步實現(xiàn)上述環(huán)節(jié),簡述如下:
(1) 模塊簽名。可加載內(nèi)核模塊是一種ELF格式的文件,其具體信息包含在每一個被稱為“section”的信息塊中,如指令信息、數(shù)據(jù)信息等。模塊簽名就是模塊的開發(fā)者使用公開的簽名工具對模塊打上特定的“烙印”。首先,模塊開發(fā)者向指定的CA認(rèn)證中心申請證書,申請證書成功后,基于公開密鑰算法為模塊簽名(如RSA算法),使用某種摘要算法計算模塊文件的摘要值(如md5算法),這里的摘要內(nèi)容是ELF文件中后綴為“.text”和“.data”的section,計算得到的摘要值經(jīng)過唯一私鑰加密,即得到模塊的簽名信息。如圖2所示,簽名后的模塊增加了兩個section,一個是簽名信息,一個是開發(fā)者向CA認(rèn)證中心申請的證書。
(2) 信任模塊的管理和驗證。信任模塊是專門為管理系統(tǒng)認(rèn)為可信的模塊所設(shè)計的數(shù)據(jù)結(jié)構(gòu),包括模塊名、模塊的摘要值,以及計算模塊摘要的算法:
內(nèi)核初始化時,初始化函數(shù)首先讀取記錄了每一個信任模塊信息的配置文件,形成上述數(shù)據(jù)結(jié)構(gòu)的數(shù)據(jù)鏈,即為系統(tǒng)的信任模塊管理鏈。系統(tǒng)管理員可以使用命令查詢、增加、刪除當(dāng)前信任模塊管理鏈中的模塊。
當(dāng)某模塊請求加載到內(nèi)核時,系統(tǒng)首先查看該模塊名是否存在于本系統(tǒng)的信任模塊鏈上。如果在,則說明它是信任模塊,使用登記的計算摘要算法重新計算該模塊的摘要,即ELF文件中后綴為“.text”和“.data”的section給的摘要,并與登記的摘要值對比,只有完全一致才允許加載。
(3) 驗證非信任模塊。對于非信任模塊,首先認(rèn)證模塊的證書,認(rèn)證通過后再認(rèn)證模塊的簽名,只有證書和簽名的認(rèn)證都通過,才被判斷為可以加載。如圖3所示,內(nèi)核對非信任模塊的驗證是通過處于內(nèi)核態(tài)的模塊加載進程與處于用戶態(tài)的監(jiān)聽進程交互達到的[4],它們之間的交互通過進程間的通信機制實現(xiàn)。監(jiān)聽進程作為守護進程在系統(tǒng)啟動時運行,一直處于監(jiān)聽模式,等待內(nèi)核態(tài)進程發(fā)出的認(rèn)證請求。若當(dāng)前加載的模塊是非信任模塊,內(nèi)核加載進程將發(fā)出認(rèn)證請求,監(jiān)聽進程在收到認(rèn)證請求后,調(diào)用證書服務(wù)函數(shù)認(rèn)證指定的模塊證書和簽名信息,并將認(rèn)證結(jié)果傳遞給內(nèi)核,由內(nèi)核決定是否加載模塊。
認(rèn)證證書的過程就是建立一條從模塊自身攜帶的證書到根證書的證書鏈,如果能夠建立這樣一個證書鏈并且證書鏈上的證書都是有效的,則通過證書驗證,如果不能建立這樣一個證書鏈或者建立的證書鏈上有的證書已經(jīng)過期,則不能通過證書驗證。通過了證書驗證的模塊,將進一步驗證其簽名信息,從已經(jīng)通過驗證的模塊證書中取出公鑰,解密簽名信息,得到出廠時的模塊摘要值,并重新計算此時模塊的摘要值,兩相對比,如果一致說明模塊沒有被篡改,否則模塊的完整性遭到破壞,系統(tǒng)拒絕加載。
(4) 實時檢測內(nèi)核地址數(shù)據(jù)。內(nèi)核加載模塊大致可分為以下幾步:①加載模塊文件到內(nèi)存;②注冊加載的模塊到相關(guān)內(nèi)核隊列中;③執(zhí)行模塊初始化操作;④必要時記錄模塊間的依賴關(guān)系。模塊對內(nèi)核的修改發(fā)生在第③步以后,為確定內(nèi)核不因加載模塊發(fā)生異常改變,需要此時檢測內(nèi)核關(guān)鍵數(shù)據(jù)。
系統(tǒng)隨開機啟動一個用于啟動檢測程序的守護進程,用于接收內(nèi)核加載模塊進程發(fā)來的信號,在沒有信號到來時處于休眠狀態(tài),接收到信號后啟動檢測程序,并根據(jù)檢測結(jié)果判斷是否發(fā)出報警信號。當(dāng)模塊加載完成第③步時,內(nèi)核加載進程通過進程間的通信機制向守護進程傳遞請求檢測信號,隨即守護進程啟動檢測程序。
內(nèi)核級Rootkit主要通過重定向中斷描述符表、系統(tǒng)調(diào)用表、系統(tǒng)調(diào)用函數(shù)等入侵內(nèi)核,檢測程序主要對相關(guān)內(nèi)核地址進行檢查,發(fā)現(xiàn)是否有內(nèi)核地址被重定向。在/boot目錄下有一個system.map文件,該文件在編譯內(nèi)核時生成,它包含了系統(tǒng)的內(nèi)核符號地址。這些符號地址就是檢測過程中用來參照的正確地址。/dev/kmem是一個字符設(shè)備文件,它保存了系統(tǒng)中所有虛存的一個映像。讀取/dev/kmem設(shè)備文件,可以獲取當(dāng)前系統(tǒng)中相關(guān)內(nèi)核地址數(shù)據(jù)。檢測步驟如下[5]:①打開/dev/kmem,在/dev/kmem中獲取中斷描述符表在內(nèi)存中的首地址,查找sys_call_table 獲取系統(tǒng)調(diào)用表地址;②比較/dev/kmem中的中斷描述符表的地址與system.map中的地址,如果相同則轉(zhuǎn)下一步,否則發(fā)出報警信號,并轉(zhuǎn)下一步;③比較/dev/kmem中的系統(tǒng)調(diào)用表地址與system.map中的地址,如果相同則轉(zhuǎn)下一步,否則發(fā)出報警信號,并轉(zhuǎn)下一步;④比較/dev/kmem中每一個系統(tǒng)調(diào)用函數(shù)的地址與system.map中的地址,一旦發(fā)現(xiàn)地址不一樣則發(fā)出報警信號,如果相同,則未發(fā)現(xiàn)異常,檢測結(jié)束。
4 結(jié)語
本文在Linux系統(tǒng)下實現(xiàn)了一種防范Rootkit入侵的內(nèi)核模塊加載機制。實驗證明,該機制能克服傳統(tǒng)加載機制安全上的弱點,有效防范內(nèi)核級Rootkit利用動態(tài)加載模塊機制入侵內(nèi)核。如何保護系統(tǒng)關(guān)鍵進程,防止守護進程被惡意中止,以及如何盡可能減小系統(tǒng)性能開銷,則有待進一步研究。
參考文獻:
[1]趙帥,伍延軍,賀也平.基于虛擬機架構(gòu)的內(nèi)核Rootkit防范方案[J].計算機工程與應(yīng)用,2011, 47(11):7274.
[2]Microsoft.Digital signatures for kernel modules on systems running windows vista [EB/OL].http://www.microsoft.com.
[3]LIDS.Linux intrusion detection system[EB/OL]. http://www.lids.org.
[4]陳斌斌,吳慶波,魏立峰. Kylin系統(tǒng)的內(nèi)核級Rootkit防護[J].計算機工程,2008,34(22):156158.
[5]石晶翔,陳蜀宇,黃晗輝.基于Linux系統(tǒng)調(diào)用的內(nèi)核級Rootkit技術(shù)研究[J].計算機技術(shù)與發(fā)展,2010,20(4):175178.
責(zé)任編輯(責(zé)任編輯:孫 娟)