2021-4-9 | 冶金工業(yè)論文
一、相關(guān)防御方法
針對(duì)非控制數(shù)據(jù)攻擊,目前存在一些防御方式。其中大部分都是靜態(tài)方法,需要程序源代碼進(jìn)行重新編譯,無(wú)法應(yīng)用于商業(yè)軟件。也有一些動(dòng)態(tài)分析解決方案,但是存在較嚴(yán)重的誤報(bào)漏報(bào)。文獻(xiàn)[9]提出了C語(yǔ)言的一個(gè)擴(kuò)展語(yǔ)義——YARRA,通過(guò)將程序中的關(guān)鍵數(shù)據(jù)聲明為一種特殊類型,只有類型匹配的指針才能訪問(wèn)這類數(shù)據(jù)。實(shí)現(xiàn)了一個(gè)編譯器的原型,編譯后的程序可以有效地防御非控制數(shù)據(jù)攻擊。ValueGuard在程序數(shù)據(jù)前添加哨兵位,將原始數(shù)據(jù)和哨兵位數(shù)據(jù)包裝為結(jié)構(gòu)體,每次運(yùn)行時(shí)檢查該哨兵位。這種方式同樣需要對(duì)源程序進(jìn)行重新編譯。數(shù)據(jù)空間隨機(jī)化DSR[11][DataSpaceRandomization]將內(nèi)存中數(shù)據(jù)的存儲(chǔ)內(nèi)容隨機(jī)化,針對(duì)不同的變量使用不同的掩碼,和實(shí)際數(shù)值進(jìn)行異或操作,當(dāng)讀取的時(shí)候再使用該掩碼異或操作獲取實(shí)際數(shù)值。攻擊者通過(guò)覆寫(xiě)關(guān)鍵數(shù)據(jù)進(jìn)行攻擊時(shí),由于不同變量掩碼不同,因此實(shí)際寫(xiě)入的將會(huì)是垃圾數(shù)據(jù),無(wú)法實(shí)施攻擊。文獻(xiàn)[12]針對(duì)非控制數(shù)據(jù)攻擊多數(shù)都存在非法指針解引用的現(xiàn)象,設(shè)計(jì)了一種基于邊界檢查的防御方法,但是文獻(xiàn)[3][15]指出這存在很嚴(yán)重的誤報(bào)和漏報(bào)。文獻(xiàn)[13]通過(guò)在硬件層面給寄存器、內(nèi)存添加標(biāo)記位,這樣可以高效地進(jìn)行污點(diǎn)標(biāo)記,不過(guò)這需要全新的硬件支持,實(shí)用性不強(qiáng)。
二、防御原理
基礎(chǔ)的動(dòng)態(tài)污點(diǎn)分析(DTA)針對(duì)控制數(shù)據(jù)攻擊非常有效,但是無(wú)法防御非控制數(shù)據(jù)攻擊。研究發(fā)現(xiàn),控制數(shù)據(jù)攻擊和大部分非控制數(shù)據(jù)攻擊都具備相同的特征,向攻擊者構(gòu)造的地址寫(xiě)入數(shù)據(jù),或者讀取攻擊者構(gòu)造的地址的數(shù)據(jù)。概括地說(shuō),大部分攻擊都依賴于一個(gè)不安全的指針解引用[12][13],而這個(gè)不安全的指針通常是由攻擊者構(gòu)造的。例如格式化串攻擊中,常見(jiàn)的攻擊方式是攻擊者往自己精心構(gòu)造的地址寫(xiě)入一個(gè)數(shù)值,這就存在不安全指針的解引用。Chenet.al[2]提到的針對(duì)HTTPserver-GHTTPD和WU-FTPD的攻擊實(shí)例,也是通過(guò)覆寫(xiě)指針,指針解引用后實(shí)施攻擊。根據(jù)這一特征,我們提出了指針污點(diǎn)分析方法,它是DTA的一種擴(kuò)展,因此我們這一方法也分為三個(gè)步驟:taintsource(標(biāo)記污點(diǎn)來(lái)源);taintpropagation(傳遞污染屬性);taintsink(污點(diǎn)信息終點(diǎn))。污點(diǎn)來(lái)源source就是來(lái)自外部的數(shù)據(jù),可以是讀取自文件、網(wǎng)絡(luò)等;根據(jù)二進(jìn)制指令的實(shí)際含義定義不同的傳播規(guī)則(即propagation);sink是污點(diǎn)數(shù)據(jù)的到達(dá)處,通常會(huì)在此處設(shè)置安全規(guī)則檢查。下面我們定義兩個(gè)重要的概念。定義1污點(diǎn)標(biāo)記(tainttag,T-tag)是內(nèi)存數(shù)據(jù)的一個(gè)屬性,表示該數(shù)據(jù)是否是來(lái)自外部、受污染的。真值表示是受污染的,假值表示不是受污染的。定義2指針標(biāo)記(pointertag,P-tag)是內(nèi)存數(shù)據(jù)的一個(gè)屬性,表示該數(shù)據(jù)是否是合法指針,是否可以用作地址。真值表示是合法指針,假值表示是非法指針。我們的防御方法就是圍繞內(nèi)存數(shù)據(jù)的這兩個(gè)屬性的標(biāo)記、傳播和檢查。
1.標(biāo)記污點(diǎn)來(lái)源
針對(duì)T-tag,我們監(jiān)控程序讀取文件、網(wǎng)絡(luò)數(shù)據(jù)等行為,將獲取的數(shù)據(jù)初始化標(biāo)記為受污染的,其他數(shù)據(jù)標(biāo)記為非污染的。針對(duì)P-tag,我們需要識(shí)別出該內(nèi)存數(shù)據(jù)是否是合法的地址。有兩種方式產(chǎn)生的數(shù)據(jù)可以用作指針,分別是動(dòng)態(tài)分配空間的指針和靜態(tài)分配空間的指針。初始狀態(tài)下,只有通過(guò)這些方式產(chǎn)生的數(shù)據(jù),才認(rèn)為是合法的指針,其他數(shù)據(jù)默認(rèn)會(huì)標(biāo)記為非法指針。
2.傳遞污染屬性
數(shù)據(jù)作為不同指令類型操作數(shù)時(shí),其傳播規(guī)則也不同。表1概括了不同的傳播策略。我們將指令主要分為算術(shù)運(yùn)算指令、邏輯運(yùn)算指令、數(shù)據(jù)傳輸指令和特殊指令,下面針對(duì)T-tag和P-tag分別進(jìn)行詳細(xì)描述。
(1)T-tag傳播策略
算術(shù)運(yùn)算指令:add,sub,mul等Example:mulop1,op2Rule:T(op1)=T(op1)∨T(op2)解析:只要兩個(gè)操作數(shù)中任一個(gè)為受污染的,則污染屬性傳播到目標(biāo)操作數(shù)中。數(shù)據(jù)傳輸指令:mov型指令,包括mov、movsb等Example:movop1,op2Rule:T(op1)=T(op2)解析:源操作數(shù)的污染屬性直接傳播到目標(biāo)操作數(shù)中。邏輯運(yùn)算指令:and,or,shl等Example:andop1,op2Rule:T(op1)=T(op1)∨T(op2)解析:只要兩個(gè)操作數(shù)中任一個(gè)為受污染的,則污染屬性傳播到目標(biāo)操作數(shù)中。特殊指令:xor,test等Example:xorop1,op1Rule:T(op1)=0解析:該指令的目的是將相應(yīng)寄存器中的數(shù)據(jù)清空,因此污染屬性將會(huì)清除。
(2)P-tag傳播策略
算術(shù)指令(相加、相減):add,subExample:addop1,op2Rule:P(op1)=P(op1)⊕P(op2)解析:兩個(gè)操作數(shù)都是合法指針,或者都不是合法指針,則目標(biāo)操作數(shù)不是一個(gè)合法指針。這個(gè)很容易理解,兩個(gè)地址之間加減,其結(jié)果是兩者的相對(duì)偏移,所以不是一個(gè)合法的地址。如果兩個(gè)操作數(shù)只有一個(gè)是合法指針,則這是一次通過(guò)基地址和偏移量計(jì)算地址的操作,其結(jié)果還是一個(gè)合法指針。算術(shù)指令(相乘等其他指令):mul,div等Example:mulop1,op2Rule:P(op1)=0解析:不是正常的地址計(jì)算操作,因此其結(jié)果都標(biāo)記為非法指針。邏輯運(yùn)算指令(取基地址的AND指令):andExample:andop1,0x11..00Rule:P(op1)=P(op1)解析:這是一條比較特殊的and指令,目的是獲取源操作數(shù)的基地址,因此其結(jié)果的P-tag屬性和源操作數(shù)的P-tag屬性相同。邏輯運(yùn)算指令(其他指令):or,not等Example:orop1,op2Rule:P(op1)=0解析:不是正常的地址計(jì)算操作,因此其結(jié)果都標(biāo)記為非法指針。數(shù)據(jù)傳輸指令:mov型指令,包括mov、movsb等Example:movop1,op2Rule:P(op1)=P(op2)解析:源操作數(shù)的污染屬性直接傳播到目標(biāo)操作數(shù)中。
3.攻擊判定
攻擊判定分為兩類,一類是常見(jiàn)的控制數(shù)據(jù)攻擊,監(jiān)控跳轉(zhuǎn)類指令(Jump、Call、Ret等),當(dāng)其操作數(shù)的T-tag屬性為真,即是來(lái)自外部的污點(diǎn)數(shù)據(jù),表明這是一次攻擊。第二類是監(jiān)控指針的解引用:如果T-tag屬性為假,即不是來(lái)自外部的污點(diǎn)數(shù)據(jù),則不管P-tag的屬性值,指針的解引用都是合法的;如果T-tag為真并且P-tag為假,即當(dāng)來(lái)自外部的污點(diǎn)數(shù)據(jù),并且不是一個(gè)合法指針,被解引用時(shí),則表明這是一次攻擊;如果T-tag為真并且P-tag也為真,雖然是來(lái)自外部的數(shù)據(jù)組成的地址,但是合法指針,所以可以解引用,這也很好地解決了之前防御方法存在的漏報(bào)誤報(bào)問(wèn)題[3][15]。表2定義了攻擊判定的規(guī)則。
三、系統(tǒng)具體實(shí)現(xiàn)
本系統(tǒng)是在UbuntuLinux下基于動(dòng)態(tài)二進(jìn)制分析框架Pin開(kāi)發(fā)的指針污點(diǎn)分析工具DynamicPointerTaintAnalysisTool,簡(jiǎn)稱DPTA。Pin可以在可執(zhí)行二進(jìn)制代碼中插入一些探測(cè)函數(shù),用于觀察、記錄、分析等。通過(guò)Pin提供的API可以編寫(xiě)各種分析工具,這樣程序運(yùn)行完以后,統(tǒng)計(jì)和分析結(jié)果也同時(shí)產(chǎn)生。DPTA除了具有基本的DTA功能以外,主要著眼于指針污點(diǎn)分析,因此具有防御控制數(shù)據(jù)攻擊和非控制數(shù)據(jù)攻擊的能力。圖2是DPTA的系統(tǒng)框架。系統(tǒng)會(huì)監(jiān)控系統(tǒng)調(diào)用,將來(lái)自外部的數(shù)據(jù)標(biāo)記T-tag和P-tag屬性,并存儲(chǔ)到Tagmap中。應(yīng)用程序的每條指令通過(guò)Pin進(jìn)行翻譯后執(zhí)行,同時(shí)DPTA會(huì)插入一些分析代碼,實(shí)時(shí)監(jiān)控程序運(yùn)行狀態(tài)。程序執(zhí)行過(guò)程中會(huì)動(dòng)態(tài)更新Tagmap,并在安全敏感處執(zhí)行檢查,發(fā)現(xiàn)攻擊時(shí)觸發(fā)警報(bào)。
Tagmap的設(shè)計(jì)Tagmap,又被稱為影子內(nèi)存,是在系統(tǒng)中開(kāi)辟的一塊新區(qū)域,用來(lái)存儲(chǔ)程序內(nèi)存數(shù)據(jù)的標(biāo)記信息。在本系統(tǒng)中,我們使用兩個(gè)bit位來(lái)標(biāo)識(shí)每一塊內(nèi)存的T-tag和P-tag屬性,分別為T(mén)-bit和P-bit。T-bit為0表明不是污點(diǎn)數(shù)據(jù),1表示是污點(diǎn)數(shù)據(jù)。P-bit為0表示不是一個(gè)合法指針,1表示是一個(gè)合法指針。Tagmap中標(biāo)記的地址和實(shí)際的數(shù)據(jù)存儲(chǔ)地址有一對(duì)映射關(guān)系,可以通過(guò)計(jì)算來(lái)獲取。程序初始運(yùn)行時(shí),Tagmap會(huì)根據(jù)實(shí)際情況初始化為不同的數(shù)值,默認(rèn)下這兩個(gè)bit位都是置為0。T-bit的初始化和傳統(tǒng)的DTA相同,將read、recv等函數(shù)獲取的數(shù)據(jù)標(biāo)識(shí)為1(污點(diǎn)數(shù)據(jù))。P-bit的初始化相對(duì)復(fù)雜性,主要是指針的產(chǎn)生可能會(huì)有很多種情況,因此指針識(shí)別是很重要的一環(huán),下文我們會(huì)對(duì)其進(jìn)行詳述。識(shí)別出的指針,其P-bit將會(huì)被標(biāo)識(shí)為1(合法指針)。
1.指針識(shí)別
指針識(shí)別是本系統(tǒng)中非常重要的一部分,但是二進(jìn)制中的指針識(shí)別向來(lái)是一件非常困難的事情。我們將指針區(qū)分為兩類,一類是指向動(dòng)態(tài)分配空間的指針,另一類是指向靜態(tài)分配空間的指針,例如全局變量的地址。圖3展示了內(nèi)存的布局,動(dòng)態(tài)區(qū)域主要是堆和棧,靜態(tài)區(qū)域包括靜態(tài)數(shù)據(jù)區(qū)、代碼區(qū)、動(dòng)態(tài)鏈接庫(kù)的靜態(tài)數(shù)據(jù)區(qū)和代碼區(qū)。下面分別對(duì)這兩類指針的識(shí)別進(jìn)行闡述。
(1)動(dòng)態(tài)分配的堆空間指針
動(dòng)態(tài)分配的空間一般需要調(diào)用一些系統(tǒng)調(diào)用,如mmap、brk、mmap2、mremap、shmat等。因此可以監(jiān)控這一類系統(tǒng)調(diào)用,其返回的指針就是合法的堆空間指針。例如增加對(duì)系統(tǒng)調(diào)用brk的監(jiān)視,根據(jù)Pin的api,我們給brk綁定一個(gè)監(jiān)控函數(shù)post_brk_hook:當(dāng)產(chǎn)生系統(tǒng)調(diào)用brk時(shí),監(jiān)控函數(shù)中會(huì)將返回的指針的P-bit設(shè)置為1,表明是合法的指針。同理也可以添加對(duì)其它系統(tǒng)調(diào)用的監(jiān)聽(tīng)。棧空間的指針都是來(lái)自于棧指針(StackPointer),因此我們將程序開(kāi)始時(shí)候的棧指針的P-bit設(shè)為1。
(2)靜態(tài)分配空間的指針
靜態(tài)分配空間的指針識(shí)別比較復(fù)雜。當(dāng)程序被編譯成重定向目標(biāo)文件時(shí),所有靜態(tài)分配空間的引用都會(huì)放置在重定向表中。如果應(yīng)用程序中有著完整的重定向表,我們可以精確地識(shí)別出所有靜態(tài)的指針初始化。然而大部分情況下都缺少這些信息,因此對(duì)于這種情況,我們需要其他方法來(lái)識(shí)別指針。DPTA是基于x86指令集下的Pin開(kāi)發(fā)的,通過(guò)反編譯程序可知,這類指針初始化具有一個(gè)特征,都是通過(guò)類似movl的指令,將一個(gè)32-bit的常數(shù)賦值給寄存器,據(jù)此我們可以保守地識(shí)別出x86下的靜態(tài)分配空間指針。我們首先獲得靜態(tài)空間的起始地址和終止地址,然后在DPTA插樁的時(shí)候檢查movl類的指令,如果其操作數(shù)是立即數(shù)和寄存器,并且立即數(shù)在靜態(tài)空間的地址范圍內(nèi),則認(rèn)為其是合法的指針初始化。這些操作雖然比較復(fù)雜,但是這是插樁代碼,因此其對(duì)效率影響有限。
2.污染屬性傳播和攻擊判定
污染屬性的傳播也就是在程序運(yùn)行中,每塊內(nèi)存數(shù)據(jù)所對(duì)應(yīng)的兩個(gè)bit位的變化。按照上文提到的傳播策略,當(dāng)程序運(yùn)行時(shí),Tagmap中的數(shù)據(jù)將按照表1中的策略進(jìn)行更新。攻擊判定,首先針對(duì)跳轉(zhuǎn)類指令(Jump、Call、Ret等),需要進(jìn)行判斷,這和傳統(tǒng)的DTA相同,此處不做詳述。針對(duì)指針解引用的判斷,根據(jù)指針解引用指令(如mov指令)的操作數(shù),如果源操作數(shù)是指針,T-bit為1并且其P-bit為0,表明要讀取一個(gè)非法指針指向的內(nèi)存區(qū)域數(shù)據(jù),判斷這是一次對(duì)非法指針的解引用,是一次攻擊。如果目的操作數(shù)是指針,T-bit為1并且其P-bit為0,表明將對(duì)一個(gè)非法指針指向的內(nèi)存區(qū)域?qū)懭霐?shù)據(jù),判斷其為攻擊。表3是一段攻擊判定的示例代碼。其中alert_mov方法將會(huì)按照我們定義的策略對(duì)該內(nèi)存地址的T-bit和P-bit進(jìn)行檢查,判斷是否是一次攻擊。
四、實(shí)驗(yàn)評(píng)估
在UbuntuLinux下對(duì)DPTA進(jìn)行實(shí)驗(yàn)評(píng)估,內(nèi)核版本是3.4,運(yùn)行的平臺(tái)為CPU2.67GHz,內(nèi)存4GB。實(shí)驗(yàn)一方面驗(yàn)證該工具是否能夠檢測(cè)出非控制數(shù)據(jù)攻擊和控制數(shù)據(jù)攻擊,另一方面測(cè)試工具對(duì)應(yīng)用程序效率的影響。
1.攻擊檢測(cè)驗(yàn)證
我們選取了具有代表性的四個(gè)控制數(shù)據(jù)攻擊和四個(gè)非控制數(shù)據(jù)攻擊,進(jìn)行了多次測(cè)試。表4的測(cè)試結(jié)果表明DPTA針對(duì)控制數(shù)據(jù)攻擊和大部分非控制數(shù)據(jù)攻擊都具有良好的防御能力,但是對(duì)于不通過(guò)指針修改關(guān)鍵數(shù)據(jù)的攻擊,我們還無(wú)法防御,這是我們系統(tǒng)的局限性。
2.性能測(cè)試
我們選取了5個(gè)程序來(lái)測(cè)試我們系統(tǒng)的性能損耗,同時(shí)我們使用了Kemerlis開(kāi)發(fā)的DTA工具Libdft[16]進(jìn)行參照,表5給出了最終的測(cè)試結(jié)果。總體而言,系統(tǒng)的損耗從1.5x到28.0x不等,平均性能損耗是12.5x,這與Memcheck的運(yùn)行負(fù)載相近。相比于Libdft,DPTA的系統(tǒng)負(fù)載比較高,這是因?yàn)槲覀儾扇×吮容^嚴(yán)格的監(jiān)測(cè)策略,除了監(jiān)控跳轉(zhuǎn)指令,還包括了非常常見(jiàn)的數(shù)據(jù)傳送指令(mov等),這會(huì)給系統(tǒng)增加非常大的運(yùn)行開(kāi)銷。但是我們系統(tǒng)可以防御大部分的非控制數(shù)據(jù)攻擊,而Libdft沒(méi)有這一能力。
五、結(jié)束語(yǔ)
本文在動(dòng)態(tài)污點(diǎn)分析的基礎(chǔ)上,針對(duì)非控制數(shù)據(jù)攻擊提出了一個(gè)改進(jìn)的指針污點(diǎn)分析方法,通過(guò)跟蹤內(nèi)存數(shù)據(jù)的污點(diǎn)標(biāo)記和指針標(biāo)記,監(jiān)控是否存在非法的指針解引用。實(shí)現(xiàn)了原型工具DPTA,實(shí)驗(yàn)評(píng)估表明,該工具可以防御控制數(shù)據(jù)攻擊和大部分非控制數(shù)據(jù)攻擊。雖然DPTA實(shí)現(xiàn)了我們的防御模型,但是還存在一些問(wèn)題需要我們進(jìn)一步研究:(1)實(shí)驗(yàn)表明我們的原型系統(tǒng)運(yùn)行效率并不是很理想,距離商業(yè)化應(yīng)用還有距離。我們計(jì)劃通過(guò)兩方面進(jìn)行優(yōu)化:一方面優(yōu)化Tagmap的數(shù)據(jù)結(jié)構(gòu),更新Tagmap信息是系統(tǒng)中常見(jiàn)的操作,因此快速獲取Tagmap中的信息會(huì)對(duì)效率產(chǎn)生很大影響;另一方面手動(dòng)分析程序調(diào)用的常用函數(shù)的語(yǔ)義信息,獲取其是否涉及污點(diǎn)傳播,對(duì)于不涉及污點(diǎn)傳播的函數(shù)不進(jìn)行插樁分析。(2)目前采取的指針識(shí)別方法并不是很準(zhǔn)確,尤其是靜態(tài)分配空間的指針,下一步計(jì)劃分析識(shí)別失敗的指針,歸納其特征,提高指針識(shí)別的準(zhǔn)確率。(3)本系統(tǒng)無(wú)法檢測(cè)出不通過(guò)覆寫(xiě)指針實(shí)施的非控制數(shù)據(jù)攻擊,可以通過(guò)結(jié)合靜態(tài)分析的方法防御,但是這不是我們下一步的主要方向。(本文圖、表略)
本文作者:劉小龍 鄭滔 單位:計(jì)算機(jī)軟件新技術(shù)國(guó)家重點(diǎn)實(shí)驗(yàn)室(南京大學(xué)) 南京大學(xué)軟件學(xué)院