張貴民 , 李清寶 , 張 平 , 程三軍
1(解放軍信息工程大學(xué),河南 鄭州 450001)
2(數(shù)學(xué)工程與先進(jìn)計(jì)算國(guó)家重點(diǎn)實(shí)驗(yàn)室,河南 鄭州 450001)
3(信息保障技術(shù)重點(diǎn)實(shí)驗(yàn)室,北京 100072)
4(河南省人民檢察院,河南 鄭州 450000)
代碼復(fù)用攻擊(code reuse attack,簡(jiǎn)稱CRA)正嚴(yán)重威脅著網(wǎng)絡(luò)系統(tǒng)的安全.CRA 并不向內(nèi)存中植入任何惡意代碼,而是首先在內(nèi)存中的已有代碼中尋找可用的指令序列(即gadget),然后劫持控制流,使這些gadget 得到執(zhí)行從而實(shí)現(xiàn)攻擊.因此,CRA 能繞過(guò)數(shù)據(jù)執(zhí)行阻止技術(shù)(data executive prevention,簡(jiǎn)稱DEP)[1]和W⊕X 等內(nèi)存保護(hù)機(jī)制,典型CRA 包括return-into-libc(RILC)[2]、ROP[3]、JOP[4]、COOP[5]等.
CRA 防御方法總體可分為3 類(lèi):代碼隨機(jī)化防御方法、控制流完整性保護(hù)方法和CRA 特征檢測(cè)方法.
(1)代碼隨機(jī)化防御方法
代碼隨機(jī)化防御方法通過(guò)增加攻擊者獲取gadget 的難度,來(lái)防御代碼復(fù)用攻擊.ASLR[6]通過(guò)隨機(jī)化動(dòng)態(tài)鏈接庫(kù)和可執(zhí)行文件的加載地址,使攻擊者無(wú)法定位gadget.之后,不同粒度的隨機(jī)化方法[7,8]被先后提出,以增強(qiáng)ASLR 方法的安全性.但攻擊者仍可通過(guò)內(nèi)存泄漏[9]找到gadget,例如JIT-ROP 攻擊[10].為了應(yīng)對(duì)內(nèi)存泄漏+代碼復(fù)用攻擊,研究者提出了動(dòng)態(tài)隨機(jī)化方法.Isomeron[11]和Remix[12]分別利用雙函數(shù)副本執(zhí)行和函數(shù)內(nèi)基本塊變換的方式實(shí)現(xiàn)對(duì)函數(shù)內(nèi)部的隨機(jī)化,但都無(wú)法防御函數(shù)級(jí)復(fù)用攻擊;TASR[13]實(shí)現(xiàn)了對(duì)程序整個(gè)代碼段內(nèi)存位置的隨機(jī)變化,但代碼段內(nèi)容不變.因此,一旦攻擊者定位到該程序所在內(nèi)存即可掌握其所有代碼特征.另外,該方法僅對(duì)C 語(yǔ)言程序?qū)嵤┍Wo(hù),應(yīng)用范圍受限.
(2)控制流完整性保護(hù)方法
控制流完整性保護(hù)方法通過(guò)阻止攻擊者篡改控制流,使 gadget 序列得不到執(zhí)行.CFI[14]基于控制流圖(control-flow graph,簡(jiǎn)稱CFG)防御所有控制流劫持攻擊,但開(kāi)銷(xiāo)較大,實(shí)用性差.為了降低開(kāi)銷(xiāo),CCFI[15]、Contextsensitive CFI[16]和CFI-KCraD[17]等方法通過(guò)結(jié)合對(duì)程序語(yǔ)義的分析,保證控制流在一定層度上的完整性,提高了方法的實(shí)用性.但控制流被劫持的風(fēng)險(xiǎn)依然存在[18],例如CFI-KCraD 中的方法只能防御指令片段的復(fù)用,而無(wú)法防御函數(shù)級(jí)復(fù)用.
(3)CRA 特征檢測(cè)方法
CRA 特征檢測(cè)方法通過(guò)監(jiān)控當(dāng)前是否存在代碼復(fù)用攻擊的執(zhí)行特征來(lái)檢測(cè)和阻止攻擊的實(shí)現(xiàn).ROPecker[19]通過(guò)檢測(cè)是否執(zhí)行了超過(guò)某個(gè)數(shù)量(閾值)的gadget 來(lái)檢測(cè)代碼復(fù)用攻擊,其問(wèn)題在于難以確定合理的閾值,且無(wú)法防御利用長(zhǎng)gadget 實(shí)施的攻擊[20].ROPdefender[21]基于call 指令與ret 指令的匹配來(lái)防御ROP攻擊,但call 和ret 指令并不總是成對(duì)出現(xiàn),且該方法無(wú)法防御除ROP 外的其他代碼復(fù)用攻擊,如JOP、COOP等.文獻(xiàn)[22]提出通過(guò)檢測(cè)ret 指令的執(zhí)行頻率來(lái)推斷ROP 攻擊,但無(wú)法防御JOP、CPROP[23]等攻擊.
除了上述防御方法外,SoftBound[24]、Baggy Bounds Checking[25]等方法通過(guò)檢測(cè)內(nèi)存錯(cuò)誤,從源頭上來(lái)防御攻擊,但開(kāi)銷(xiāo)太大;文獻(xiàn)[26]基于編譯器來(lái)消除用于構(gòu)建gadget 的指令,該方法依賴源碼且必須對(duì)所有程序模塊進(jìn)行處理,實(shí)現(xiàn)復(fù)雜;文獻(xiàn)[27]通過(guò)阻止對(duì)代碼的讀操作使攻擊者無(wú)法通過(guò)直接掃描內(nèi)存獲取gadget,但攻擊者仍可通過(guò)其他內(nèi)存泄漏方式獲取到gadget 并構(gòu)造攻擊;CPI[28]通過(guò)保護(hù)代碼指針的完整性來(lái)防御代碼復(fù)用攻擊,但該方法已被證明是可以被繞過(guò)的[29];DFI[30]基于靜態(tài)分析的到達(dá)定義集合對(duì)數(shù)據(jù)進(jìn)行保護(hù),但需要源碼且需要處理所有相關(guān)庫(kù)和模塊.
另外,還有通過(guò)代碼和數(shù)據(jù)隔離的方法[31],可防御內(nèi)存泄漏攻擊,卻無(wú)法防御return-into-libc 攻擊.
通過(guò)分析當(dāng)前代碼復(fù)用攻擊的防御方法,發(fā)現(xiàn)依然還存在以下幾個(gè)方面的問(wèn)題.
1)代碼隨機(jī)化方法通過(guò)阻止攻擊者獲取有效的gadget 信息來(lái)預(yù)防代碼復(fù)用攻擊,尤其是動(dòng)態(tài)隨機(jī)化,但攻擊者仍可借助側(cè)信道攻擊[32]等方式繞過(guò)該類(lèi)防御方法.
2)控制流完整性保護(hù)方法阻止攻擊者執(zhí)行g(shù)adget 串,但研究表明,即使在細(xì)粒度控制流完整性保護(hù)下,攻擊者仍可劫持控制流執(zhí)行特定代碼.
3)基于CRA 特征檢測(cè)的方法在代碼復(fù)用攻擊運(yùn)行階段檢測(cè)和阻止攻擊的進(jìn)一步執(zhí)行,但無(wú)法涵蓋當(dāng)前各種新型代碼復(fù)用攻擊的所有特征,防御能力有限.
代碼隨機(jī)化方法和控制流完整性保護(hù)方法能夠在一定程度上增加CRA 實(shí)現(xiàn)的難度,但總會(huì)出現(xiàn)能夠突破防護(hù)的新型攻擊;基于CRA 特征檢測(cè)的方法不關(guān)注如何阻止攻擊的發(fā)起,而是著眼于如何盡快在攻擊發(fā)起后檢測(cè)并阻止其進(jìn)一步執(zhí)行,但問(wèn)題在于該類(lèi)方法無(wú)法跟上代碼復(fù)用攻擊技術(shù)更新的速度,對(duì)新型攻擊無(wú)能為力.針對(duì)上述問(wèn)題,本文提出一種基于程序運(yùn)行特征監(jiān)控的代碼復(fù)用攻擊防御方法(running characteristics monitoring,簡(jiǎn)稱 RCMon).該方法首先對(duì)CRA 的基本原理進(jìn)行分析,并在此基礎(chǔ)上定義了程序運(yùn)行特征模型(running characteristics model,簡(jiǎn)稱RCMod).該模型由一系列程序關(guān)鍵節(jié)點(diǎn)處的運(yùn)行特征模式組成,即各關(guān)鍵節(jié)點(diǎn)之間調(diào)用的關(guān)鍵系統(tǒng)調(diào)用的類(lèi)型以及執(zhí)行的總次數(shù)等統(tǒng)計(jì)特征.另外,還基于RCMod 設(shè)計(jì)了防御CRA 的安全驗(yàn)證自動(dòng)機(jī)模型;然后,利用二進(jìn)制插樁技術(shù)直接向被保護(hù)程序(目標(biāo)程序)可執(zhí)行文件中的所有關(guān)鍵節(jié)點(diǎn)處植入監(jiān)控代碼,使目標(biāo)程序運(yùn)行到關(guān)鍵節(jié)點(diǎn)時(shí)陷入到Hypervisor;之后,由Hypervisor 在訓(xùn)練階段構(gòu)建目標(biāo)程序的運(yùn)行特征庫(kù);最后,Hypervisor 按照安全驗(yàn)證自動(dòng)機(jī)模型對(duì)目標(biāo)程序的實(shí)時(shí)運(yùn)行特征進(jìn)行監(jiān)控,從而實(shí)現(xiàn)對(duì)代碼復(fù)用攻擊的防御.
攻擊者實(shí)施代碼復(fù)用攻擊或其他攻擊的目的都是為了執(zhí)行某些特定操作.RCMon 的研究基于這樣一種假設(shè),即攻擊者在實(shí)施惡意操作時(shí)難免要通過(guò)系統(tǒng)調(diào)用和操作系統(tǒng)進(jìn)行交互.由于不借助任何系統(tǒng)調(diào)用的攻擊所能實(shí)施的操作有限,如非控制數(shù)據(jù)攻擊[33],這類(lèi)攻擊并不在本文的討論范圍.
RCMon 的設(shè)計(jì)目標(biāo)是:
1)不需要程序源碼和定制的編譯器,不改變系統(tǒng)配置和模塊,可兼容于遺留代碼(legacy code);
2)能夠防御當(dāng)前已知的各類(lèi)CRA(詳見(jiàn)第3.1 節(jié)表5),對(duì)未知的新型CRA 也具有一定的防御能力;
3)在對(duì)目標(biāo)程序進(jìn)行保護(hù)時(shí),要使目標(biāo)程序、操作系統(tǒng)和其他應(yīng)用程序的開(kāi)銷(xiāo)均保持在可接受范圍.
本文第1 節(jié)描述RCMon 的總體架構(gòu)及相關(guān)模型設(shè)計(jì).第2 節(jié)論述RCMon 的具體設(shè)計(jì)和實(shí)現(xiàn)方法.第3 節(jié)實(shí)現(xiàn)RCMon 原型系統(tǒng)并對(duì)其進(jìn)行測(cè)試.第4 節(jié)討論RCMon 的局限性.第5 節(jié)對(duì)全文工作進(jìn)行總結(jié).
RCMon 的總體架構(gòu)如圖1 所示,由目標(biāo)程序插樁階段(Instrumentation phase)、訓(xùn)練階段(Training phase)和運(yùn)行階段(Running phase)這3 部分組成.
Fig.1 Overall architecture of RCMon圖1 RCMon 方法總體架構(gòu)
插樁階段直接處理目標(biāo)程序的可執(zhí)行文件,由插樁模塊(instrumentation module)將特定指令序列(即監(jiān)控指令)植入到目標(biāo)程序中的某些關(guān)鍵節(jié)點(diǎn),其中,監(jiān)控指令中含vmcall 指令[34]以及標(biāo)識(shí)程序關(guān)鍵節(jié)點(diǎn)的重要信息,最終生成一個(gè)新的可執(zhí)行文件;訓(xùn)練階段是在一個(gè)已開(kāi)啟了虛擬機(jī)監(jiān)控器Hypervisor 的客戶機(jī)環(huán)境中運(yùn)行由插樁階段生成的新可執(zhí)行文件,該Hypervisor 能夠監(jiān)控程序運(yùn)行過(guò)程中執(zhí)行的所有關(guān)鍵系統(tǒng)調(diào)用和vmcall 指令,從而獲得系統(tǒng)調(diào)用執(zhí)行信息和目標(biāo)程序的關(guān)鍵節(jié)點(diǎn)信息,然后由運(yùn)行特征統(tǒng)計(jì)分析模塊(RCs statistic module)根據(jù)這些信息建立目標(biāo)程序的運(yùn)行特征庫(kù),并通過(guò)加密和度量模塊(encryption and measurement module)處理后存儲(chǔ)在特征文件中,作為下一步驗(yàn)證目標(biāo)程序行為特征是否正常的依據(jù),最后通過(guò)多次訓(xùn)練以提高特征庫(kù)的完備性;運(yùn)行階段,首先由度量和解密模塊(measurement and decryption module)負(fù)責(zé)驗(yàn)證目標(biāo)程序特征文件的完整性并解密該文件,然后將該文件加載到Hypervisor 內(nèi)存中,并加載運(yùn)行目標(biāo)程序.在目標(biāo)程序運(yùn)行過(guò)程中,Hypervisor 根據(jù)監(jiān)控得到的關(guān)鍵系統(tǒng)調(diào)用執(zhí)行信息,在每次監(jiān)控指令標(biāo)識(shí)的關(guān)鍵節(jié)點(diǎn)處驗(yàn)證目標(biāo)程序在該節(jié)點(diǎn)處的運(yùn)行特征是否正常:若不正常,則表明程序遭到攻擊,立即終止程序運(yùn)行;若正常,則根據(jù)運(yùn)行特征庫(kù)中對(duì)下一步要執(zhí)行的關(guān)鍵系統(tǒng)調(diào)用的信息設(shè)置每個(gè)關(guān)鍵系統(tǒng)調(diào)用對(duì)應(yīng)的看門(mén)狗計(jì)數(shù)器(watchdog counter,簡(jiǎn)稱WDC),由它實(shí)現(xiàn)對(duì)每次關(guān)鍵系統(tǒng)調(diào)用的合法性進(jìn)行驗(yàn)證.通過(guò)這兩種安全機(jī)制,實(shí)現(xiàn)對(duì)代碼復(fù)用攻擊的有效防御.
CRA[2-5,10,23,35,36]的本質(zhì)都是通過(guò)串連以間接跳轉(zhuǎn)(indirect jump)指令、間接調(diào)用(indirect call)指令以及ret指令結(jié)尾的gadget 來(lái)實(shí)現(xiàn)對(duì)內(nèi)存中已有代碼的復(fù)用,而根據(jù)復(fù)用代碼的粒度不同,存在指令片段復(fù)用和函數(shù)級(jí)復(fù)用兩種類(lèi)型,如圖2 所示.在圖2 中,實(shí)線箭頭表示正常的控制流,當(dāng)攻擊者發(fā)現(xiàn)當(dāng)前內(nèi)存中存在gadget1~gadget5 這5 個(gè)可利用的指令序列時(shí),則通過(guò)篡改棧、寄存器或者虛函數(shù)表指針等方式實(shí)現(xiàn)代碼復(fù)用攻擊;圖中虛線箭頭表示該攻擊的執(zhí)行過(guò)程,圖中instruction1i和instruction2i+k為indirect jump 指令,該攻擊示例中既包含了對(duì)程序自身函數(shù)func1 和func2 中指令片段的復(fù)用,也包含了對(duì)庫(kù)函數(shù)func4 的函數(shù)級(jí)復(fù)用.根據(jù)前文假設(shè),gadget1~gadget5 中必定存在某個(gè)gadget 調(diào)用了相關(guān)系統(tǒng)調(diào)用以實(shí)現(xiàn)攻擊目標(biāo),而且由于gadget 間的跳轉(zhuǎn)執(zhí)行改變了程序的原有執(zhí)行過(guò)程,這勢(shì)必將改變目標(biāo)程序原有的系統(tǒng)調(diào)用執(zhí)行過(guò)程.因此,通過(guò)對(duì)異常系統(tǒng)調(diào)用的及時(shí)檢測(cè)和阻止可實(shí)現(xiàn)對(duì)攻擊的有效防御,RCMon 正是基于該論斷進(jìn)行研究的.
Fig.2 An example of CRA圖2 CRA 示例
為了檢測(cè)異常行為,必須首先界定什么是正常行為.如果借助若干個(gè)程序執(zhí)行過(guò)程中的關(guān)鍵節(jié)點(diǎn)將程序的整個(gè)執(zhí)行過(guò)程分成多個(gè)不同的執(zhí)行域,那么每個(gè)區(qū)域都有自己需要的系統(tǒng)調(diào)用的類(lèi)型和數(shù)量,將其稱為該區(qū)域的運(yùn)行特征.當(dāng)關(guān)鍵節(jié)點(diǎn)的選取恰當(dāng)時(shí),通過(guò)驗(yàn)證每個(gè)區(qū)域的運(yùn)行特征,即可實(shí)現(xiàn)對(duì)代碼復(fù)用攻擊的檢測(cè)和阻止.基于對(duì)CRA 實(shí)現(xiàn)方式的分析,由關(guān)鍵節(jié)點(diǎn)劃分的區(qū)域必須能夠覆蓋CRA 采用的以indirect jump,indirect call和ret 指令為結(jié)尾的指令片段,且要盡量實(shí)現(xiàn)就近覆蓋.最直接的想法是以所有的上述3 類(lèi)指令作為關(guān)鍵節(jié)點(diǎn)進(jìn)行劃分,但考慮到監(jiān)控效率和實(shí)現(xiàn)復(fù)雜度,RCMon 選擇采用indirect call 和ret 指令作為關(guān)鍵節(jié)點(diǎn),并輔以調(diào)用點(diǎn)前后位置節(jié)點(diǎn),實(shí)現(xiàn)對(duì)所有已經(jīng)用于以及將來(lái)可能會(huì)用于CRA 中的轉(zhuǎn)移指令進(jìn)行覆蓋.圖2 中標(biāo)出了各個(gè)關(guān)鍵節(jié)點(diǎn)的信息,即對(duì)應(yīng)indirect call 和ret 指令的每個(gè)函數(shù)的入口(function enter,簡(jiǎn)稱FEN)節(jié)點(diǎn)和出口(function exit,簡(jiǎn)稱FEX)節(jié)點(diǎn),以及函數(shù)調(diào)用點(diǎn)前(before callsite,簡(jiǎn)稱BC)節(jié)點(diǎn)和調(diào)用點(diǎn)后(after callsite,簡(jiǎn)稱AC)節(jié)點(diǎn).之所以引入BC 和AC 節(jié)點(diǎn),是由于RCMon 為了達(dá)到不改變系統(tǒng)環(huán)境和模塊的目的,沒(méi)有對(duì)動(dòng)態(tài)鏈接庫(kù)中的函數(shù)(如圖2 中的func3 和func4)進(jìn)行插樁,因此無(wú)法監(jiān)控庫(kù)函數(shù)的入口和出口以及庫(kù)函數(shù)中又間接調(diào)用的其他庫(kù)函數(shù)的入口和出口.通過(guò)增加BC 和AC 節(jié)點(diǎn),RCMon 將庫(kù)函數(shù)中的所有執(zhí)行過(guò)程抽象為一個(gè)整體,不僅達(dá)到了不改變系統(tǒng)環(huán)境和模塊的目的,也實(shí)現(xiàn)了對(duì)庫(kù)函數(shù)執(zhí)行行為的有效監(jiān)控.通過(guò)上述4 類(lèi)關(guān)鍵節(jié)點(diǎn)的劃分,除indirect call和ret 指令外的其他可能指令(包括indirect jump 指令)構(gòu)建的所有g(shù)adget,都只能存在于由FEN 和BC、FEN 和FEX、AC 和FEN 以及BC 和AC 劃分的區(qū)域中.
基于上述分析,構(gòu)建了程序的運(yùn)行特征模型RCMod 來(lái)描述程序的正常運(yùn)行特征.為了描述RCMod 的構(gòu)建方法,首先給出描述程序的運(yùn)行特征的模式定義.
定義1.運(yùn)行特征模式(running characteristic pattern,簡(jiǎn)稱RCP)是一個(gè)4 元式(procID,fID,NT,SCCA),其中,
?procID:該運(yùn)行特征所屬程序的ID 編碼,即標(biāo)識(shí)某個(gè)被保護(hù)程序的整數(shù)值,由用戶指定.
?fID:關(guān)鍵節(jié)點(diǎn)所處函數(shù)體的ID 編碼,即標(biāo)識(shí)某個(gè)被保護(hù)程序中不同函數(shù)體的整數(shù)值,由算法自動(dòng)分配.
?NT:關(guān)鍵節(jié)點(diǎn)類(lèi)型.當(dāng)NT為1~4 時(shí),依次表示當(dāng)前關(guān)鍵節(jié)點(diǎn)為BC,FEN,FEX 和AC 節(jié)點(diǎn).
?SCCA:系統(tǒng)調(diào)用特征序列.假設(shè)運(yùn)行特征中涉及的系統(tǒng)調(diào)用共有Nsc(Nsc≥1)種,則SCCA={scca[i][j]|i∈[0,Nsc-1],j∈[0,1]},其中,scca[i][0]和scca[i][1]分別表示程序到達(dá)本節(jié)點(diǎn)時(shí)第i種系統(tǒng)調(diào)用已經(jīng)執(zhí)行了的總次數(shù)和在該節(jié)點(diǎn)到下一節(jié)點(diǎn)之間的區(qū)域內(nèi)將要執(zhí)行的次數(shù).
由定義1 可知,一個(gè)RCP 給出了某個(gè)程序在某個(gè)關(guān)鍵節(jié)點(diǎn)處的運(yùn)行特征.一個(gè)程序往往由多個(gè)函數(shù)實(shí)現(xiàn),包括對(duì)某些庫(kù)函數(shù)的調(diào)用,必然引入一定數(shù)量的關(guān)鍵節(jié)點(diǎn).假設(shè)一個(gè)程序共含有k個(gè)關(guān)鍵節(jié)點(diǎn),則至少含有k個(gè)RCP,因?yàn)楫?dāng)存在對(duì)某個(gè)函數(shù)的循環(huán)多次調(diào)用時(shí),每次循環(huán)時(shí)與該函數(shù)相關(guān)的各個(gè)節(jié)點(diǎn)的scca[i][0]都將發(fā)生變化,即生成新的RCP.該程序的運(yùn)行特征模式空間Ω={RCP1,RCP2,RCP3,…,RCPn}(n≥k,n∈N+),利用程序一次運(yùn)行中的運(yùn)行軌跡經(jīng)過(guò)的所有關(guān)鍵節(jié)點(diǎn)的RCP 的集合即可描述該程序本次運(yùn)行過(guò)程的運(yùn)行特征,詳見(jiàn)定理1.
定理1.設(shè)F為Ω的子集族且為C 族(即F為Ω的所有子集構(gòu)成的子集族),那么程序一次運(yùn)行的運(yùn)行特征一定可由集合R表示,且R∈F.
證明:從程序的所有運(yùn)行軌跡中任選一條軌跡,假設(shè)該條軌跡中含有的運(yùn)行特征模式為RCPi,RCPj,RCPk,…,RCPm(1≤i≤j≤k≤…≤m≤n;i,j,k,…,m∈N+),此時(shí):
集合R={RCPi,RCPj,RCPk,…,RCPm}即表示了該程序本次運(yùn)行的運(yùn)行特征;
因?yàn)镽CPi,RCPj,RCPk,…,RCPm∈Ω,所以R?Ω;
因?yàn)镕為Ω的子集族且為C 族,所以R∈F.定理1 得證.
R描述了程序一次執(zhí)行過(guò)程中的所有運(yùn)行特征,因此,R即是RCMod 模型的具體表現(xiàn)形式.□
在運(yùn)行階段,RCMon 采用兩種安全機(jī)制:基于關(guān)鍵節(jié)點(diǎn)陷入事件觸發(fā)的后向安全驗(yàn)證(backward safety verification,簡(jiǎn)稱BSV)和基于WDC 的前向安全驗(yàn)證(forward safety verification,簡(jiǎn)稱FSV).
BSV 是在由監(jiān)控指令導(dǎo)致的關(guān)鍵節(jié)點(diǎn)陷入時(shí)進(jìn)行的第1 類(lèi)驗(yàn)證,將陷入節(jié)點(diǎn)的procID、fID、NT以及當(dāng)前各個(gè)關(guān)鍵系統(tǒng)調(diào)用執(zhí)行的總次數(shù)scca[i][0](0≤i≤Nsc-1)與事先訓(xùn)練獲得的特征庫(kù)中的值進(jìn)行匹配驗(yàn)證.如無(wú)匹配項(xiàng),則說(shuō)明該節(jié)點(diǎn)之前的運(yùn)行過(guò)程已經(jīng)遭到攻擊,此時(shí)終止該程序的執(zhí)行;否則,繼續(xù)執(zhí)行FSV.BSV 機(jī)制保證了當(dāng)前關(guān)鍵節(jié)點(diǎn)的到來(lái)是合法的,只有通過(guò)BSV 機(jī)制驗(yàn)證過(guò)的指令序列(或整個(gè)函數(shù))才能成功執(zhí)行.
但BSV 存在一定的局限性.假設(shè)目標(biāo)程序遭到代碼復(fù)用攻擊并將控制流劫持到動(dòng)態(tài)鏈接庫(kù)中的代碼,如果之后控制流不再回到目標(biāo)程序的自身代碼執(zhí)行,即一直到攻擊完成都不會(huì)再到達(dá)含監(jiān)控代碼的下一個(gè)關(guān)鍵節(jié)點(diǎn),那么BSV 是無(wú)法防御該類(lèi)攻擊的;另外,如果攻擊者劫持一段時(shí)間控制流后再次到達(dá)另一個(gè)關(guān)鍵節(jié)點(diǎn),雖然此時(shí)BSV 能夠檢測(cè)到攻擊,但攻擊可能已經(jīng)執(zhí)行了想要執(zhí)行的惡意操作.因此,采用另外一種驗(yàn)證機(jī)制FSV 來(lái)彌補(bǔ)BSV 的不足.
在論述FSV 機(jī)制前,首先對(duì)本文提出的WDC 進(jìn)行說(shuō)明.看門(mén)狗也叫做看門(mén)狗計(jì)時(shí)器(watchdog timer,簡(jiǎn)稱WDT),是單片機(jī)中的一種安全機(jī)制.WDT 是一個(gè)計(jì)時(shí)器電路,在單片機(jī)開(kāi)始工作后啟動(dòng),微處理器控制單元(microprocessor control unit,簡(jiǎn)稱MCU)正常情況下會(huì)定期輸出一個(gè)信號(hào)給WDT,稱為喂狗,目的是使WDT 清零.而一旦受到干擾導(dǎo)致程序跑飛時(shí),MCU 將無(wú)法在規(guī)定時(shí)間內(nèi)執(zhí)行喂狗操作,最終導(dǎo)致WDT 超時(shí).此時(shí),WDT就會(huì)給MCU 一個(gè)復(fù)位信號(hào),使MCU 復(fù)位,從而防止MCU 死機(jī).本文提出的WDC 正是借鑒了WDT 的思想.WDC在這里是一個(gè)計(jì)數(shù)器而不是計(jì)時(shí)器,它接受一個(gè)數(shù)值作為臨界值.當(dāng)啟動(dòng)后,WDC 的數(shù)值通過(guò)事件觸發(fā)的方式增長(zhǎng),所關(guān)注事件(本文為所監(jiān)控的關(guān)鍵系統(tǒng)調(diào)用)每觸發(fā)一次,計(jì)數(shù)器加1.WDC 與WDT 的不同點(diǎn)還包括:WDC只有在恰好等于臨界值時(shí)接收到喂狗操作才說(shuō)明系統(tǒng)的運(yùn)行正常,否則都會(huì)發(fā)出異常警告.
FSV 在經(jīng)過(guò)后向驗(yàn)證后執(zhí)行,將找到的匹配項(xiàng)中的各個(gè)scca[i][1](0≤i≤Nsc-1)的值設(shè)置為對(duì)應(yīng)的各WDC的臨界值.RCMon 為每個(gè)受保護(hù)的目標(biāo)進(jìn)程維護(hù)著Nsc個(gè)WDC,它們分別由相應(yīng)的關(guān)鍵系統(tǒng)調(diào)用的執(zhí)行作為計(jì)數(shù)器加1 的觸發(fā)事件,即所關(guān)注的系統(tǒng)調(diào)用每執(zhí)行一次,WDC 的值加1,并以關(guān)鍵節(jié)點(diǎn)陷入事件作為喂狗操作.若WDC 在達(dá)到臨界值前接收到了喂狗操作,即下一個(gè)關(guān)鍵節(jié)點(diǎn)提前到達(dá),則說(shuō)明在本應(yīng)執(zhí)行該WDC 對(duì)應(yīng)的系統(tǒng)調(diào)用的某處指令并沒(méi)有得到執(zhí)行,程序遭到攻擊;若WDC 超過(guò)臨界值,則說(shuō)明此時(shí)執(zhí)行了多出正常范圍的系統(tǒng)調(diào)用,程序遭到攻擊;而只有當(dāng)WDC 正好在臨界值時(shí)接收到喂狗操作,才表明程序運(yùn)行過(guò)程符合其運(yùn)行特征.
FSV 的作用是保證目標(biāo)程序在該節(jié)點(diǎn)到下個(gè)節(jié)點(diǎn)之間執(zhí)行的所有關(guān)鍵系統(tǒng)調(diào)用符合運(yùn)行特征,可實(shí)時(shí)檢測(cè)攻擊的發(fā)生.但FSV 無(wú)法防御某些函數(shù)級(jí)復(fù)用攻擊,例如,當(dāng)攻擊者復(fù)用程序本身具有的函數(shù)時(shí),由于所有自身函數(shù)的入口和出口節(jié)點(diǎn)及其內(nèi)部的其他節(jié)點(diǎn)都是對(duì)該函數(shù)自身行為的約束,因此當(dāng)該函數(shù)完整執(zhí)行時(shí),FSV無(wú)法檢測(cè)到該類(lèi)復(fù)用攻擊.而當(dāng)結(jié)合BSV 之后,RCMon 則可對(duì)所有函數(shù)執(zhí)行的合法性進(jìn)行驗(yàn)證,此時(shí),復(fù)用函數(shù)無(wú)法在攻擊者設(shè)定的位置執(zhí)行,即可實(shí)現(xiàn)對(duì)該類(lèi)攻擊的有效防御.
RCMon 的安全驗(yàn)證機(jī)制BSV 和FSV 可抽象為一個(gè)帶輸出的有限自動(dòng)機(jī)模型M=(Q,Σ,Δ,δ,λ,q0),其中,
?Q={S0,S1,S2,S3,S4}為該模型的所有狀態(tài);
?Σ={get information of every critical system call,verification failed,verification successful,continue execution,exceed the critical value,below the critical value}為該模型的輸入字母表;
?Δ={vmcall in critical node,kicking the dog}為該模型的輸出字母表;
?δ為狀態(tài)轉(zhuǎn)移函數(shù),δ:Q×Σ→Q;
?λ為輸出函數(shù),λ:Q→Δ;
?q0為初始狀態(tài),q0=S0.
模型中的S0表示經(jīng)過(guò)插樁處理后的目標(biāo)程序的正常執(zhí)行狀態(tài);S1表示執(zhí)行后向驗(yàn)證狀態(tài);S2表示執(zhí)行前向驗(yàn)證狀態(tài);S3表示關(guān)鍵系統(tǒng)調(diào)用的執(zhí)行狀態(tài);而S4則表示異常狀態(tài),即目標(biāo)程序遭到攻擊.
模型M對(duì)應(yīng)的狀態(tài)轉(zhuǎn)移過(guò)程如圖3 所示.當(dāng)程序執(zhí)行到定義的關(guān)鍵節(jié)點(diǎn)時(shí),監(jiān)控指令得到執(zhí)行,當(dāng)其中的vmcall 指令執(zhí)行時(shí)使程序陷入到Hypervisor 中,并同時(shí)將節(jié)點(diǎn)信息(例如procID,fID以及NT)傳遞給Hypervisor,此時(shí),狀態(tài)機(jī)從S0進(jìn)入S1,并在狀態(tài)S1執(zhí)行后向驗(yàn)證.若后向驗(yàn)證失敗,則由狀態(tài)S1直接進(jìn)入狀態(tài)S4,產(chǎn)生警告,中斷目標(biāo)程序的運(yùn)行;否則,由狀態(tài)S1進(jìn)入狀態(tài)S2,在S2中執(zhí)行前向驗(yàn)證.只有當(dāng)出現(xiàn)WDC 超過(guò)臨界值或在喂狗操作提前到達(dá)時(shí),才由狀態(tài)S2進(jìn)入狀態(tài)S4,產(chǎn)生警告,并中斷目標(biāo)程序的運(yùn)行;否則,由狀態(tài)S2進(jìn)入狀態(tài)S0,目標(biāo)程序繼續(xù)運(yùn)行.
Fig.3 Model of safety verification automaton圖3 安全驗(yàn)證自動(dòng)機(jī)模型
向目標(biāo)程序中植入監(jiān)控指令,是構(gòu)建程序運(yùn)行特征庫(kù)和檢測(cè)程序異常行為的重要一環(huán).根據(jù)模型RCMod,需要在目標(biāo)程序中函數(shù)調(diào)用位置的前后以及所有本地函數(shù)的入口和出口處植入監(jiān)控指令,如圖2 所示.為了使RCMod 的實(shí)現(xiàn)不依賴于目標(biāo)程序源碼和編譯器,且實(shí)現(xiàn)一次插樁、永久監(jiān)控,RCMon 基于靜態(tài)二進(jìn)制插樁框架Dyninst[37]實(shí)現(xiàn)上述功能.
基于Dyninst 實(shí)現(xiàn)的監(jiān)控代碼植入算法如圖4 所示.首先,通過(guò)Dyninst API 獲取目標(biāo)程序中所有能夠進(jìn)行插樁的函數(shù)信息,同時(shí)為每一個(gè)可插樁函數(shù)分配一個(gè)fID,用于標(biāo)識(shí)不同函數(shù);然后,在每一個(gè)函數(shù)區(qū)域內(nèi)分別定位函數(shù)入口、出口和函數(shù)調(diào)用點(diǎn);之后,構(gòu)建4 類(lèi)關(guān)鍵節(jié)點(diǎn)監(jiān)控代碼snippet;最后,分別將構(gòu)造的監(jiān)控代碼植入到對(duì)應(yīng)的關(guān)鍵節(jié)點(diǎn)并生成新的可執(zhí)行程序.
植入的監(jiān)控代碼需要實(shí)現(xiàn)兩方面功能:一是報(bào)告當(dāng)前節(jié)點(diǎn)的標(biāo)識(shí)信息,包括procID,fID和NT;二是在執(zhí)行到關(guān)鍵節(jié)點(diǎn)時(shí)產(chǎn)生陷入.為了提高信息的傳遞效率,研究中采用寄存器作為傳遞信息的媒介,分別將procID,fID和NT保存到寄存器EAX、ECX 和EDX 中,然后,通過(guò)執(zhí)行特權(quán)指令vmcall 實(shí)現(xiàn)陷入,Hypervisor 通過(guò)讀取3 個(gè)寄存器獲得當(dāng)前關(guān)鍵節(jié)點(diǎn)的信息.為了避免在使用3 個(gè)寄存器時(shí)對(duì)它們內(nèi)容的保存和恢復(fù)的復(fù)雜性,實(shí)現(xiàn)時(shí),將監(jiān)控指令置于獨(dú)立的函數(shù)中實(shí)現(xiàn).
4 類(lèi)不同節(jié)點(diǎn)處調(diào)用的監(jiān)控函數(shù)的具體定義如圖5 所示,其中,參數(shù)functionID即圖4 所示算法中為每個(gè)函數(shù)分配的fID,procID則設(shè)定為唯一標(biāo)識(shí)該程序的某個(gè)整數(shù)值,NT直接根據(jù)對(duì)應(yīng)的節(jié)點(diǎn)設(shè)置為1~4.最后,將上述監(jiān)控函數(shù)封裝在一個(gè)動(dòng)態(tài)鏈接庫(kù)(算法1 中的mylib.so)中,利用loadLibrary函數(shù)將該庫(kù)加載到目標(biāo)程序的內(nèi)存空間,供目標(biāo)程序調(diào)用.
通過(guò)上述處理后,最終生成一個(gè)新的含監(jiān)控代碼的可執(zhí)行文件.該文件可完全脫離Dyninst 獨(dú)立運(yùn)行.監(jiān)控代碼植入后,程序控制流的變化情況如圖6 所示(注:圖6 是以funcX為本地函數(shù)為例進(jìn)行說(shuō)明的,當(dāng)funcX為庫(kù)函數(shù)時(shí),則只有BC 和AC 節(jié)點(diǎn),不存在BEN 和BEX 節(jié)點(diǎn)以及與user2vmmenter,user2vmmexit函數(shù)之間的控制流轉(zhuǎn)移).可見(jiàn),目標(biāo)程序的執(zhí)行過(guò)程已經(jīng)完全處在RCMon 的監(jiān)控之下.
Fig.4 Algorithm for instrumenting monitoring code圖4 監(jiān)控代碼植入算法
Fig.5 Definitions of instrumented functions圖5 植入函數(shù)的定義
Fig.6 Control flow before and after instrumenting code圖6 代碼植入前后的控制流
實(shí)現(xiàn)RCMon 必須對(duì)系統(tǒng)調(diào)用進(jìn)行監(jiān)控,從而構(gòu)建模型RCMod,實(shí)現(xiàn)對(duì)目標(biāo)進(jìn)程的運(yùn)行時(shí)監(jiān)控.Linux 操作系統(tǒng)中存在數(shù)百個(gè)系統(tǒng)調(diào)用,若對(duì)所有系統(tǒng)調(diào)用都進(jìn)行監(jiān)控,會(huì)導(dǎo)致較大的時(shí)間開(kāi)銷(xiāo)和空間開(kāi)銷(xiāo)(更多內(nèi)存用于存儲(chǔ)scca 數(shù)組和WDC).在保證監(jiān)控強(qiáng)度不變的條件下,為了降低監(jiān)控帶來(lái)的開(kāi)銷(xiāo),RCMon 選取了只與系統(tǒng)安全和各類(lèi)攻擊行為相關(guān)性較高的關(guān)鍵系統(tǒng)調(diào)用進(jìn)行監(jiān)控.
文獻(xiàn)[38]為了實(shí)現(xiàn)對(duì)惡意軟件行為的描述,通過(guò)對(duì)472 種Linux 下的惡意軟件進(jìn)行分析,總結(jié)提煉出了惡意軟件經(jīng)常使用的64 種系統(tǒng)調(diào)用;TASR[13]為了更好地防御內(nèi)存泄漏,在總結(jié)分析各類(lèi)攻擊實(shí)現(xiàn)機(jī)制的基礎(chǔ)上提出了最小攻擊間隔理論,并將所有的輸入類(lèi)和輸出類(lèi)系統(tǒng)調(diào)用作為關(guān)鍵系統(tǒng)調(diào)用進(jìn)行監(jiān)控.RCMon 在借鑒已有研究成果的基礎(chǔ)上,對(duì)各類(lèi)系統(tǒng)調(diào)用進(jìn)行了如下安全性分析.
(1)是否能夠用于改變系統(tǒng)內(nèi)某類(lèi)資源(含硬件資源和文件、進(jìn)程等軟件資源)的狀態(tài);
(2)是否能夠用于獲取更高操作權(quán)限;
(3)是否能夠用于查看或傳輸各類(lèi)信息.
通過(guò)上述分析,RCMon 最終選擇監(jiān)控82 種(NSC=82)與安全相關(guān)的關(guān)鍵系統(tǒng)調(diào)用,見(jiàn)表1,分別對(duì)應(yīng)于模型中的第0 種~第81 種系統(tǒng)調(diào)用.
Table 1 Critical system calls表1 關(guān)鍵系統(tǒng)調(diào)用
為了高效地監(jiān)控上述關(guān)鍵系統(tǒng)調(diào)用,且不改變操作系統(tǒng)內(nèi)核,RCMon 采用一種基于動(dòng)態(tài)指令替換的監(jiān)控方法實(shí)現(xiàn)該功能[35],即在系統(tǒng)運(yùn)行過(guò)程中,通過(guò)底層的Hypervisor 修改內(nèi)核代碼內(nèi)存,將要監(jiān)控的關(guān)鍵系統(tǒng)調(diào)用對(duì)應(yīng)的處理函數(shù)入口處(可通過(guò)事先分析操作系統(tǒng)的導(dǎo)出符號(hào)表system.map 得到各個(gè)關(guān)鍵系統(tǒng)調(diào)用處理函數(shù)的入口地址)的若干指令替換為vmcall 指令,使得關(guān)鍵系統(tǒng)調(diào)用執(zhí)行時(shí)產(chǎn)生陷入,從而達(dá)到監(jiān)控的目的.同時(shí),還需要在Hypervisor 中對(duì)被vmcall 替換的那些指令進(jìn)行模擬,保證系統(tǒng)調(diào)用的正常執(zhí)行.
以Ubuntu12.04 使用的3.2.0-29-generic-pae i386 的內(nèi)核為例,該內(nèi)核代碼中每個(gè)關(guān)鍵系統(tǒng)調(diào)用處理函數(shù)的入口處均為長(zhǎng)度為3 個(gè)字節(jié)的“push %ebp;movl %esp,%ebp”兩條指令,由于vmcall 指令的長(zhǎng)度也為3 個(gè)字節(jié),因此對(duì)于該發(fā)行版內(nèi)核來(lái)說(shuō),只需將函數(shù)入口處的頭3 個(gè)字節(jié)替換為vmcall 指令即可.
指令替換后,所有關(guān)鍵系統(tǒng)調(diào)用處理函數(shù)在執(zhí)行時(shí)都會(huì)由于vmcall 指令而陷入Hypervisor,此時(shí)獲取客戶機(jī)指令寄存器的值并進(jìn)行分析:若該值為某個(gè)關(guān)鍵系統(tǒng)調(diào)用處理函數(shù)的入口地址,則說(shuō)明當(dāng)前進(jìn)程調(diào)用了該系統(tǒng)調(diào)用;否則,vmcall 指令來(lái)自于對(duì)目標(biāo)程序關(guān)鍵節(jié)點(diǎn)的監(jiān)控指令,此時(shí)執(zhí)行運(yùn)行特征庫(kù)構(gòu)建或安全驗(yàn)證.最后,在Hypervisor 中仿真執(zhí)行被替換指令的功能.上述監(jiān)控機(jī)制的實(shí)現(xiàn)過(guò)程如圖7 所示.
Fig.7 Monitoring mechanism of critical system calls圖7 關(guān)鍵系統(tǒng)調(diào)用監(jiān)控機(jī)制
由RCMon 的實(shí)現(xiàn)過(guò)程可知,在Hypervisor 中執(zhí)行的安全驗(yàn)證過(guò)程是該方法最核心和最復(fù)雜的部分,同時(shí)也引入了較大開(kāi)銷(xiāo),對(duì)這部分的優(yōu)化,對(duì)于降低RCMon 的監(jiān)控開(kāi)銷(xiāo)具有重要作用.當(dāng)采用第2.1 節(jié)和第2.3 節(jié)中的方法完成對(duì)目標(biāo)程序運(yùn)行特征的構(gòu)建后,通過(guò)分析獲得的運(yùn)行特征,發(fā)現(xiàn)存在以下特點(diǎn):a)目標(biāo)程序正常運(yùn)行過(guò)程中往往不會(huì)包含對(duì)所有82 種關(guān)鍵系統(tǒng)調(diào)用的使用,而是存在某些未被使用的系統(tǒng)調(diào)用;b)相鄰關(guān)鍵節(jié)點(diǎn)RCP 中的scca[i][0](0≤i≤Nsc-1)局部或全部相同(在兩個(gè)關(guān)鍵節(jié)點(diǎn)間執(zhí)行所有82 種關(guān)鍵系統(tǒng)調(diào)用的可能性很小).基于上述特點(diǎn),提出兩種對(duì)RCMon 運(yùn)行時(shí)監(jiān)控過(guò)程的優(yōu)化方法以降低其監(jiān)控開(kāi)銷(xiāo).
(1)全局優(yōu)化
對(duì)于目標(biāo)程序正常運(yùn)行過(guò)程中不會(huì)使用的關(guān)鍵系統(tǒng)調(diào)用,只在目標(biāo)程序第1 個(gè)函數(shù)的入口節(jié)點(diǎn)處對(duì)這些關(guān)鍵系統(tǒng)調(diào)用對(duì)應(yīng)的WDC 進(jìn)行設(shè)置(全部設(shè)置為0),從而保證目標(biāo)程序一旦執(zhí)行這些系統(tǒng)調(diào)用即可導(dǎo)致WDC超過(guò)臨界值而報(bào)警.而在程序其他節(jié)點(diǎn)處執(zhí)行BSV 和FSV 時(shí),則不再對(duì)這些系統(tǒng)調(diào)用對(duì)應(yīng)的SCCA中的項(xiàng)進(jìn)行對(duì)比驗(yàn)證,也不再重置其對(duì)應(yīng)的WDC,即在程序入口處設(shè)置的WDC 將作用于程序的整個(gè)運(yùn)行過(guò)程.目標(biāo)程序未使用的系統(tǒng)調(diào)用可通過(guò)分析由訓(xùn)練階段得到的運(yùn)行特征獲得,并通過(guò)運(yùn)行特征文件告知Hypervisor 中的運(yùn)行特征監(jiān)控模塊.
(2)局部?jī)?yōu)化
當(dāng)存在相鄰兩個(gè)或多個(gè)關(guān)鍵節(jié)點(diǎn)中的scca[i][0](0≤i≤Nsc-1)完全一致的情況時(shí),表明在這些關(guān)鍵節(jié)點(diǎn)之間未執(zhí)行任何關(guān)鍵系統(tǒng)調(diào)用.此時(shí),將這些連續(xù)的節(jié)點(diǎn)看作一個(gè)整體,僅在第1 個(gè)和最后一個(gè)節(jié)點(diǎn)處執(zhí)行BSV 和FSV,中間節(jié)點(diǎn)則不再進(jìn)行任何驗(yàn)證.為實(shí)現(xiàn)該項(xiàng)優(yōu)化,首先在運(yùn)行特征中找到每個(gè)符合條件的連續(xù)節(jié)點(diǎn)的起始節(jié)點(diǎn)和最終節(jié)點(diǎn),然后反匯編插樁后的新可執(zhí)行程序,并根據(jù)中間關(guān)鍵節(jié)點(diǎn)的fID和NT的值定位到在這些節(jié)點(diǎn)處植入的調(diào)用監(jiān)控函數(shù)的代碼,然后使用nop 指令將其替代,從而避免目標(biāo)程序在這些節(jié)點(diǎn)處產(chǎn)生陷入.
通過(guò)上述處理,在未降低RCMon 方法安全性的條件下,減少了目標(biāo)程序陷入Hypervisor 的次數(shù),并降低了Hypervisor 中執(zhí)行安全驗(yàn)證的復(fù)雜度,實(shí)現(xiàn)了對(duì)RCMon 性能的提升和優(yōu)化.由第3.2 節(jié)中的測(cè)試可知,實(shí)施優(yōu)化后,RCMon 的性能提升了約29%(即(31%-22%)/31%).
本節(jié)首先驗(yàn)證RCMon 方法的有效性,即能否有效防御代碼復(fù)用攻擊,然后再測(cè)試該方法的監(jiān)控開(kāi)銷(xiāo).實(shí)驗(yàn)環(huán)境如下:主機(jī)CPU 為Intel CoreTMi7-5500U CPU@2.40GHz;內(nèi)存大小為4GB;客戶機(jī)操作系統(tǒng)采用的是3.2.0-29-generic-pae i386 內(nèi)核版本的Ubuntu12.04;Hypervisor 是基于Intel VT 技術(shù)設(shè)計(jì)的一個(gè)輕量級(jí)的虛擬機(jī)監(jiān)控器,該監(jiān)控器僅對(duì)無(wú)條件陷入事件[31]進(jìn)行處理,目的是最大化地降低監(jiān)控開(kāi)銷(xiāo);另外,采用二進(jìn)制文件插樁框架Dyninst-9.1.0[37]實(shí)現(xiàn)對(duì)監(jiān)控指令的植入.
為了測(cè)試RCMon 的有效性,首先以一個(gè)具體實(shí)例exam 程序來(lái)驗(yàn)證方法的可行性.
exam 的源碼如圖8 所示,為了便于實(shí)現(xiàn)代碼復(fù)用攻擊,該程序func函數(shù)中含緩沖區(qū)溢出漏洞.首先編譯得到可執(zhí)行文件exam,然后經(jīng)過(guò)代碼植入模塊植入監(jiān)控指令并生成新的可執(zhí)行程序exam_rcmon,并賦予該程序編號(hào)為128(可任意指定,能夠區(qū)分不同的被保護(hù)程序即可),即將圖5 中所示的全局變量procID初始化為128.然后經(jīng)過(guò)訓(xùn)練過(guò)程,獲得exam_rcmon 的運(yùn)行特征庫(kù),由于內(nèi)容較多,表2 僅列出了其部分運(yùn)行特征.其中,(128,5,2,SCCA1)為程序exam_rcmon 中func函數(shù)的FEN 節(jié)點(diǎn)的RCP,(128,5,1,SCCA2)為func中對(duì)read函數(shù)調(diào)用的BC節(jié)點(diǎn)的RCP,(128,5,4,SCCA3)為func中對(duì)read函數(shù)調(diào)用的AC 節(jié)點(diǎn)的RCP,(128,5,3,SCCA4)為func的FEX 節(jié)點(diǎn)的RCP.
Fig.8 Source code of exam圖8 exam 源碼
Table 2 Running characteristics database of exam_rcmon表2 exam_rcmon 的運(yùn)行特征庫(kù)
在進(jìn)行攻擊測(cè)試時(shí),通過(guò)內(nèi)存泄漏分別找到在攻擊中經(jīng)常使用的libc庫(kù)中的read、write和system函數(shù)的地址以及程序exam_rcmon 中func函數(shù)的地址,然后利用緩沖區(qū)溢出漏洞篡改控制流,分別對(duì)上述函數(shù)進(jìn)行復(fù)用攻擊.上述4 個(gè)測(cè)試的結(jié)果見(jiàn)表3.
根據(jù)測(cè)試結(jié)果,4 種代碼復(fù)用攻擊均以失敗告終.攻擊中,將func的ret 指令作為第1 個(gè)gadget 以實(shí)現(xiàn)向其他gadget 的轉(zhuǎn)移,因此直到func的FEX 節(jié)點(diǎn)之前都是正常的.而在該節(jié)點(diǎn)后,由于對(duì)ret 指令的目標(biāo)地址進(jìn)行了篡改,分別調(diào)用了read,write,system和func函數(shù)這4 類(lèi)指令序列.當(dāng)執(zhí)行write、read和system函數(shù)時(shí),會(huì)分別調(diào)用sys_write、sys_read和sys_execve系統(tǒng)調(diào)用,這3 類(lèi)系統(tǒng)調(diào)用常用于各類(lèi)攻擊中.但由于根據(jù)(128,5,3,SCCA4)設(shè)置的3 類(lèi)系統(tǒng)調(diào)用對(duì)應(yīng)的WDC 的臨界值均為0,因此當(dāng)復(fù)用上述函數(shù)時(shí),WDC 超過(guò)臨界值,導(dǎo)致FSV 失敗.當(dāng)復(fù)用func函數(shù)時(shí),由于func函數(shù)中會(huì)調(diào)用read函數(shù),此時(shí)scca[0][0]增加1 變?yōu)?,但特征庫(kù)中并沒(méi)有符合scca[0][0]=8 且procID、fID和NT分別為128、5 和1 的RCP 存在,因此BSV 失敗.另外,測(cè)試過(guò)程中沒(méi)有發(fā)現(xiàn)任何誤報(bào).通過(guò)上述測(cè)試,驗(yàn)證了RCMon 方法檢測(cè)代碼復(fù)用攻擊的可行性.同時(shí),借助RCMon 還可以對(duì)攻擊的發(fā)生位置進(jìn)行定位,這有助于攻擊發(fā)生后的軟件安全漏洞和攻擊實(shí)現(xiàn)機(jī)制的分析.
Table 3Results of attacking tests表3 攻擊測(cè)試結(jié)果
為了更好地驗(yàn)證RCMon 的有效性,除上述測(cè)試外,我們還對(duì)4 類(lèi)真實(shí)的應(yīng)用程序(nginx,proftpd,mcrypt 以及TORQUE)進(jìn)行了測(cè)試.測(cè)試中,分別采用來(lái)自http://www.elis.ugent.be/~svolckae 的4 種不同的ROP 對(duì)上述程序?qū)嵤┕?
?攻擊1 針對(duì)Web 服務(wù)器nginx,它首先讀取棧中的canary 值以及漏洞函數(shù)棧幀底部的返回地址,利用該地址計(jì)算出nginx 的基地址,然后基于對(duì)nginx 的已有知識(shí)構(gòu)造ROP 鏈,并利用nginx 中的棧緩沖區(qū)溢出漏洞(CVE-2013-2028)使ROP 鏈獲得執(zhí)行.
?攻擊2 針對(duì)ftp 服務(wù)器proftpd,它首先通過(guò)掃描proftpd 的可執(zhí)行文件和libc 庫(kù)定位構(gòu)造ROP 鏈所需要的gadget,然后從/proc/pid/maps 中讀取proftpd 和libc 的加載地址來(lái)確定gadget 的絕對(duì)地址,最后通過(guò)一個(gè)未授權(quán)的FTP 鏈接將含有ROP 鏈的buffer 發(fā)送到proftpd,并利用proftpd 中的棧緩沖區(qū)溢出漏洞(CVE-2010-4221)使其得到執(zhí)行.
?攻擊3 針對(duì)mcrypt(一個(gè)用于替換crypt 的加密程序),它首先從/proc 接口獲得mcrypt 和libc 庫(kù)的加載地址來(lái)構(gòu)造ROP 鏈,然后通過(guò)一個(gè)pipe 將ROP 鏈發(fā)送給mcrypt,并利用mcrypt 中的棧緩沖區(qū)溢出漏洞(CVE-2012-4409)執(zhí)行該ROP 鏈.
?攻擊4 針對(duì)TORQUE 資源管理器服務(wù)器,它首先讀取pbs_server 進(jìn)程的加載地址并構(gòu)造ROP 鏈,然后通過(guò)一個(gè)未授權(quán)的網(wǎng)絡(luò)連接將該ROP 鏈發(fā)送到TORQUE,并利用TORQUE 中的棧緩沖區(qū)溢出漏洞(CVE-2014-0749)使攻擊得到執(zhí)行.
測(cè)試前,首先分別處理各目標(biāo)程序(植入監(jiān)控代碼),然后通過(guò)將處理后的程序在不同輸入和操作條件下分別運(yùn)行20 次、40 次、60 次和80 次(每次運(yùn)行30min)來(lái)構(gòu)造程序運(yùn)行特征庫(kù).然后,在關(guān)閉和開(kāi)啟RCMon 特征監(jiān)控兩種情況下,分別使用上述4 個(gè)ROP 攻擊對(duì)目標(biāo)程序進(jìn)行攻擊.根據(jù)攻擊是否成功,驗(yàn)證RCMon 防御代碼復(fù)用攻擊的有效性.需要注意的是,由于植入監(jiān)控代碼的影響,原有的4 個(gè)攻擊在構(gòu)造ROP 鏈時(shí)所使用的地址都需要更新為代碼植入后的新地址.最后,再在開(kāi)啟RCMon 特征監(jiān)控的情況下運(yùn)行各目標(biāo)程序20 次(每次仍然運(yùn)行30min),以測(cè)試是否存在誤報(bào).最終的測(cè)試結(jié)果見(jiàn)表4.
Table 4Results of real applications tests表4 真實(shí)應(yīng)用測(cè)試結(jié)果
由表4 可知,RCMon 能夠有效防御針對(duì)nginx 等應(yīng)用程序的4 種ROP 攻擊,無(wú)漏報(bào);但RCMon 存在誤報(bào),尤其是nginx 誤報(bào)情況較為明顯.主要原因在于,該類(lèi)程序運(yùn)行特征的影響因素較多,不同服務(wù)狀態(tài)和客戶鏈接數(shù)量都會(huì)對(duì)服務(wù)器的執(zhí)行過(guò)程產(chǎn)生影響.另外,從測(cè)試結(jié)果可以發(fā)現(xiàn),在訓(xùn)練階段的訓(xùn)練越充分,RCMon 產(chǎn)生誤報(bào)的可能性就越小.
另外,本文總結(jié)了當(dāng)前已知的各類(lèi)代碼復(fù)用攻擊技術(shù),并根據(jù)其實(shí)現(xiàn)機(jī)制判斷RCMon 是否能夠有效阻止這些攻擊.分析過(guò)程中均假設(shè)這些攻擊中含有對(duì)某些關(guān)鍵系統(tǒng)調(diào)用的執(zhí)行過(guò)程或者這些攻擊的實(shí)施改變了程序原有的關(guān)鍵系統(tǒng)調(diào)用執(zhí)行情況,而這個(gè)假設(shè)對(duì)大多數(shù)攻擊都是適用的[13,38].對(duì)于函數(shù)級(jí)復(fù)用攻擊來(lái)說(shuō),不含任何關(guān)鍵系統(tǒng)調(diào)用的情況極少,另外,即使對(duì)于本身不含任何關(guān)鍵系統(tǒng)調(diào)用的指令片段復(fù)用攻擊,在gadget 跳轉(zhuǎn)串聯(lián)過(guò)程中也極有可能會(huì)干預(yù)原有的系統(tǒng)調(diào)用執(zhí)行過(guò)程,如跳過(guò)某些執(zhí)行關(guān)鍵系統(tǒng)調(diào)用的指令等.最終的分析結(jié)果見(jiàn)表5.通過(guò)上述測(cè)試和分析可知,RCMon 可實(shí)現(xiàn)對(duì)已知各類(lèi)代碼復(fù)用攻擊的有效防御.同時(shí),還在表5 中將RCMon 與其他相關(guān)防御方法進(jìn)行了防御能力的對(duì)比,對(duì)比結(jié)果進(jìn)一步表明了RCMon 的有效性.
Table 5 Analysis of RCMon’s defensive ability表5 RCMond 的防御能力分析
為了測(cè)試RCMon 對(duì)整個(gè)系統(tǒng)性能的影響,本文采用SPEC CPU 2006 的CFP 2006 基準(zhǔn)測(cè)試集中的部分測(cè)試程序?qū)ο到y(tǒng)開(kāi)銷(xiāo)進(jìn)行了測(cè)試.鑒于RCMon 基于Hypervisor 實(shí)現(xiàn),本文分別測(cè)試了裸機(jī)、Hypervisor、Hypervisor下開(kāi)啟關(guān)鍵系統(tǒng)調(diào)用監(jiān)控、測(cè)試程序部署未優(yōu)化的RCMon 以及部署優(yōu)化后的RCMon 這5 種條件下的性能開(kāi)銷(xiāo),測(cè)試結(jié)果如圖9 所示.
Fig.9 Results of performance overhead measurement圖9 性能開(kāi)銷(xiāo)測(cè)試結(jié)果
由測(cè)試結(jié)果可知,本文所設(shè)計(jì)實(shí)現(xiàn)的Hypervisor 由于采用了硬件輔助虛擬化技術(shù)Intel VT,并且盡可能地減少不必要的監(jiān)控,使得該監(jiān)控器在不監(jiān)控內(nèi)核函數(shù)時(shí)開(kāi)銷(xiāo)很小.當(dāng)增加對(duì)關(guān)鍵系統(tǒng)調(diào)用的監(jiān)控后,由于所有對(duì)關(guān)鍵系統(tǒng)調(diào)用的執(zhí)行都會(huì)產(chǎn)生陷入,并在陷入后執(zhí)行對(duì)當(dāng)前關(guān)鍵系統(tǒng)調(diào)用執(zhí)行狀態(tài)的更新和對(duì)函數(shù)入口原有的兩條指令的模擬,因此開(kāi)銷(xiāo)略有增加.在對(duì)測(cè)試程序部署RCMon 之后,由于不僅要監(jiān)控系統(tǒng)中的所有關(guān)鍵系統(tǒng)調(diào)用,還要監(jiān)控程序執(zhí)行到每個(gè)關(guān)鍵節(jié)點(diǎn)處的陷入,并在陷入后根據(jù)當(dāng)前節(jié)點(diǎn)信息到運(yùn)行特征庫(kù)中查找是否存在匹配項(xiàng),當(dāng)存在匹配項(xiàng)時(shí),還要根據(jù)運(yùn)行特征設(shè)置WDC 對(duì)關(guān)鍵系統(tǒng)調(diào)用進(jìn)行實(shí)時(shí)監(jiān)控,因此,RCMon 引入后,測(cè)試程序的運(yùn)行開(kāi)銷(xiāo)增加較多.與裸機(jī)(Linux 純凈系統(tǒng))相比,當(dāng)采用未優(yōu)化的RCMon 時(shí),平均開(kāi)銷(xiāo)約為31%(其中,434.zeusmp 開(kāi)銷(xiāo)最小,為6%;而465.tonto 開(kāi)銷(xiāo)最大,為58%);當(dāng)采用優(yōu)化后的RCMon 時(shí),平均開(kāi)銷(xiāo)降至22%,這也進(jìn)一步驗(yàn)證了第2.3 節(jié)中優(yōu)化方法的有效性.
RCMon 的開(kāi)銷(xiāo)小于傳統(tǒng)的內(nèi)存安全保護(hù)方法(例如,SoftBound[24]的平均開(kāi)銷(xiāo)為 67%,Baggy Bounds Checking[25]的平均開(kāi)銷(xiāo)為60%)、數(shù)據(jù)流完整性保護(hù)方法DFI[30](平均開(kāi)銷(xiāo)高達(dá)104%)以及控制流完整性方法CCFI[15](平均開(kāi)銷(xiāo)52%)等多類(lèi)防御方法,略高于CFI[14](平均開(kāi)銷(xiāo)16%)以及ASLR[6](的平均開(kāi)銷(xiāo)為10%)等方法,但RCMon 除了能夠有效防御代碼復(fù)用攻擊以外,對(duì)所有含有系統(tǒng)調(diào)用惡意執(zhí)行的攻擊都具有一定的防御能力,防御的攻擊類(lèi)型更廣,能夠比這些防御方法提供更高的安全性.
由于RCMon 不針對(duì)某個(gè)或某些具有特定特征的代碼復(fù)用攻擊類(lèi)型進(jìn)行防御,而是基于程序的系統(tǒng)調(diào)用運(yùn)行特征防御代碼復(fù)用攻擊,是基于攻擊的某種共性(即攻擊者在實(shí)施惡意操作時(shí)難免要通過(guò)關(guān)鍵系統(tǒng)調(diào)用和操作系統(tǒng)進(jìn)行交互)實(shí)施的檢測(cè)和防御,因此無(wú)論是已知的還是未知的代碼復(fù)用攻擊,只要其實(shí)現(xiàn)過(guò)程包含對(duì)關(guān)鍵系統(tǒng)調(diào)用的使用或者其實(shí)現(xiàn)過(guò)程對(duì)原程序的關(guān)鍵系統(tǒng)調(diào)用執(zhí)行過(guò)程造成了影響(即破壞了原程序的運(yùn)行特征),RCMon 就能檢測(cè)和防御.但RCMon 仍然存在一些局限性.
(1)如果一個(gè)代碼復(fù)用攻擊不使用任何關(guān)鍵系統(tǒng)調(diào)用且攻擊實(shí)施過(guò)程不對(duì)原程序的關(guān)鍵系統(tǒng)調(diào)用執(zhí)行過(guò)程產(chǎn)生任何影響,則可以繞過(guò)RCMon 的檢測(cè),從而產(chǎn)生漏報(bào).但這種情況下,代碼復(fù)用攻擊的發(fā)揮空間是非常有限的.首先,不借助任何關(guān)鍵系統(tǒng)調(diào)用的攻擊所能實(shí)施的操作非常有限;另外,代碼復(fù)用攻擊的核心仍是對(duì)程序控制流的改變,而控制流改變的情況下要保證原程序關(guān)鍵系統(tǒng)調(diào)用執(zhí)行過(guò)程不發(fā)生任何改變,這也使攻擊變得更加難以實(shí)現(xiàn).可見(jiàn),雖然RCMon 存在漏報(bào)某些攻擊的可能,但該類(lèi)攻擊的危害性和實(shí)現(xiàn)的可能性都非常小,對(duì)RCMon 的整體安全性的影響很小.而在第3.1 節(jié)的測(cè)試中未發(fā)現(xiàn)任何漏報(bào),這也在一定層度上驗(yàn)證了上述分析.
(2)當(dāng)在訓(xùn)練階段構(gòu)造的目標(biāo)程序運(yùn)行特征不夠完備時(shí),RCMon 可能會(huì)產(chǎn)生誤報(bào).由表4 的測(cè)試結(jié)果可知,通過(guò)不斷加大訓(xùn)練階段的訓(xùn)練量,能夠在較大程度上降低RCMon 誤報(bào)的可能.但這種方法效率低,而且存在很多不確定性.要在最大程度上消除誤報(bào),必須保證在訓(xùn)練階段能夠遍歷目標(biāo)程序所有的執(zhí)行路徑來(lái)構(gòu)造完備的程序運(yùn)行特征.擬在下一步工作中,利用動(dòng)態(tài)符號(hào)執(zhí)行技術(shù)來(lái)解決這一問(wèn)題.動(dòng)態(tài)符號(hào)執(zhí)行能實(shí)現(xiàn)對(duì)程序的高路徑覆蓋,它以某個(gè)具體的輸入來(lái)執(zhí)行目標(biāo)程序,并獲取當(dāng)前路徑中的所有路徑約束條件;然后通過(guò)對(duì)這些約束條件的修改,生成一條新的路徑的約束條件,并用約束求解器獲得一個(gè)新的輸入;然后再以該輸入執(zhí)行目標(biāo)程序.通過(guò)反復(fù)執(zhí)行上述過(guò)程,即可實(shí)現(xiàn)對(duì)被測(cè)試對(duì)象所有路徑的動(dòng)態(tài)遍歷.隨著訓(xùn)練過(guò)程中的路徑覆蓋率的提高,就可構(gòu)建更加完備的程序運(yùn)行特征,從而消除誤報(bào).
針對(duì)當(dāng)前代碼復(fù)用攻擊防御方法中存在的防御類(lèi)型單一等問(wèn)題,本文提出一種基于程序運(yùn)行特征監(jiān)控的代碼復(fù)用攻擊防御方法RCMon.該方法首先定義并構(gòu)造了程序的運(yùn)行特征模型RCMod(該模型包含了在程序中的函數(shù)調(diào)用位置前后和函數(shù)出入口這4 類(lèi)關(guān)鍵節(jié)點(diǎn)處的關(guān)鍵系統(tǒng)調(diào)用的運(yùn)行特征信息),并基于該模型向目標(biāo)程序的關(guān)鍵節(jié)點(diǎn)處植入監(jiān)控代碼,以實(shí)現(xiàn)基于Hypervisor 的對(duì)目標(biāo)程序運(yùn)行過(guò)程的監(jiān)控;然后,通過(guò)訓(xùn)練過(guò)程得到目標(biāo)程序的運(yùn)行特征庫(kù);最后,在實(shí)際運(yùn)行過(guò)程中監(jiān)控程序運(yùn)行特征是否與事先得到的運(yùn)行特征庫(kù)中對(duì)應(yīng)特征一致,來(lái)判斷程序是否遭到代碼復(fù)用攻擊,從而實(shí)現(xiàn)對(duì)代碼復(fù)用攻擊的有效防御.
RCMon 的驗(yàn)證過(guò)程包含基于特征庫(kù)匹配的后向安全驗(yàn)證BSV 和基于WDC 的前向安全驗(yàn)證FSV,分別實(shí)現(xiàn)了階段性的安全驗(yàn)證和一個(gè)階段內(nèi)的實(shí)時(shí)安全驗(yàn)證,能有效防御函數(shù)級(jí)和指令級(jí)代碼復(fù)用攻擊,加強(qiáng)了目標(biāo)程序的安全性.測(cè)試結(jié)果表明,RCMon 能夠有效防御各類(lèi)含關(guān)鍵系統(tǒng)調(diào)用執(zhí)行過(guò)程的代碼復(fù)用攻擊,且實(shí)現(xiàn)過(guò)程不需要源碼,實(shí)用性較好.另外,方法的平均性能開(kāi)銷(xiāo)也在可接受的范圍內(nèi),約為22%.