唐成華,高慶澤,杜 征,強(qiáng)保華
1(桂林電子科技大學(xué) 廣西可信軟件重點(diǎn)實(shí)驗(yàn)室,廣西 桂林 541004) 2(廣西密碼學(xué)與信息安全重點(diǎn)實(shí)驗(yàn)室,廣西 桂林 541004) 3(廣西云計(jì)算與大數(shù)據(jù)協(xié)同創(chuàng)新中心,廣西 桂林 541004)
Web應(yīng)用程序在給我們帶來便利的同時(shí),其暴露出漏洞的數(shù)量呈線性增長趨勢,已成為網(wǎng)絡(luò)攻擊的主要目標(biāo),而導(dǎo)致安全風(fēng)險(xiǎn)的產(chǎn)生也正是因?yàn)槁┒春屯{的存在[1].盡管更廣泛的Web應(yīng)用程序風(fēng)險(xiǎn)Top10很有意義,但在如今由應(yīng)用程序驅(qū)動(dòng)的信息化世界中,作為研發(fā)創(chuàng)新的基本要素,應(yīng)用程序編程接口(API)是Web應(yīng)用程序、SaaS和移動(dòng)服務(wù)的關(guān)鍵,由于涉及代碼邏輯和敏感數(shù)據(jù),快速創(chuàng)新的過程必須有安全API的保證,所以重點(diǎn)關(guān)注常見的API安全問題是非常重要的[2].作為一種資源交換方式,API越來越成為攻擊者的目標(biāo),對敏感數(shù)據(jù)的惡意訪問以及對代碼行為的邏輯混淆也正是許多惡意代碼的基本特征.
行為依賴分析對提取惡意代碼的特征具有極大的作用,通過對指令層污點(diǎn)傳播與行為層語義進(jìn)行分析,獲得系統(tǒng)調(diào)用和指令信息,并構(gòu)建行為依賴關(guān)系圖,從而提取惡意代碼的行為特征,是識別惡意代碼及其變種的有效方法[3].目前,污點(diǎn)分析是軟件安全分析與推理中的重要研究課題,亦是可信軟件研究的熱點(diǎn)和難點(diǎn).盡管在污點(diǎn)分析領(lǐng)域已有多方向的探索,但普遍的問題是,靜態(tài)污點(diǎn)分析具有路徑覆蓋率高的優(yōu)勢但資源消耗過大,誤報(bào)率較高,尤其是對分析惡意代碼時(shí)會遇到代碼混淆技術(shù)的阻礙,所以主要用于重點(diǎn)代碼靜態(tài)屬性的輔助性評估和驗(yàn)證[4];動(dòng)態(tài)污點(diǎn)分析則是實(shí)時(shí)監(jiān)控污點(diǎn)數(shù)據(jù)的流動(dòng),檢測數(shù)據(jù)能否從污點(diǎn)源傳播到污點(diǎn)匯聚點(diǎn),執(zhí)行效率高但每次只能遍歷一條路徑,覆蓋率較低.因此,往往采用靜態(tài)分析與動(dòng)態(tài)驗(yàn)證相結(jié)合的方法,形式化定義污點(diǎn)傳播操作語義,以有效跟蹤跨文件和跨頁面的污點(diǎn)傳播[5].
程序中的數(shù)據(jù)流、控制流,以及依賴關(guān)系等是軟件代碼的應(yīng)用特征,通過挖掘這些特征信息,獲取程序依賴、數(shù)據(jù)依賴、行為依賴、API調(diào)用關(guān)系及實(shí)例化等方面的特征和語義信息,從而得到軟件中惡意代碼的正確理解.
在程序依賴方面,依賴性分析是許多程序分析的基礎(chǔ),其中,程序依賴通常綜合安全敏感API、系統(tǒng)調(diào)用、控制流結(jié)構(gòu)和信息流等,為應(yīng)用程序的行為提供一個(gè)獨(dú)特的語義視圖,能夠在依賴關(guān)系圖(如每個(gè)基本塊、方法和類等)中量化它執(zhí)行惡意活動(dòng)的程度[6].當(dāng)然,程序依賴分析要減少對程序執(zhí)行中的擾動(dòng).Crussell等人[7]生成軟件的程序依賴圖,在不考慮代碼混淆的情況下,基于語義信息檢測相似APP的克隆性及惡意代碼的注入性.
在數(shù)據(jù)依賴方面,基于依賴圖的分析方法通常需要提取函數(shù)調(diào)用間的數(shù)據(jù)依賴,這種數(shù)據(jù)依賴關(guān)系能夠清晰地描述程序的行為邏輯.應(yīng)用于語義分析中的函數(shù)依賴發(fā)現(xiàn),其本質(zhì)體現(xiàn)的是數(shù)據(jù)屬性之間的關(guān)系[8].Li等人[9]提出了一種快速數(shù)據(jù)依賴分析技術(shù),允許跳過循環(huán)中重復(fù)執(zhí)行的內(nèi)存操作,可以降低部分時(shí)間開銷,但此方法構(gòu)建的數(shù)據(jù)依賴圖包含大量與脆弱性分析無關(guān)的變量,降低了變量回溯的效率.吳禮發(fā)等人[10]同時(shí)分析了Java層和原生代碼層的語義信息,通過提取原生方法函數(shù)調(diào)用路徑、數(shù)據(jù)操作和敏感字符串等,進(jìn)行數(shù)據(jù)流分析,判斷是否存在敏感數(shù)據(jù)依賴關(guān)系,從而理解軟件中的語義異常行為,以保護(hù)應(yīng)用的良性,不過如果將數(shù)據(jù)流與控制流結(jié)合分析,可以更精準(zhǔn)地理解Java層語義.Abbas[11]等人通過自適應(yīng)的方式生成數(shù)據(jù)依賴圖,為了避免由于代碼插樁方式導(dǎo)致運(yùn)行損失過高的問題,但這種自適應(yīng)方式會損失一部分精度.實(shí)際上,在分析數(shù)據(jù)依賴時(shí),由于語義可執(zhí)行路徑分支眾多,極易產(chǎn)生路徑空間的組合爆炸,使得代碼檢測的覆蓋率充滿挑戰(zhàn)性,往往需要從路徑分支選擇與搜索算法上考慮[12].Lindner[13]等人均引入符號執(zhí)行方法,對代碼指令形式化語義描述后,通過控制依賴關(guān)系追溯路徑的調(diào)用過程,針對存在敏感調(diào)用的路徑進(jìn)行約束求解路徑條件,從而緩解路徑爆炸問題.
在行為依賴方面,惡意代碼體現(xiàn)某些或某種行為意圖,通過對命令和行為的語義分析,提取關(guān)鍵行為并建立行為依賴或行為關(guān)聯(lián),這類基于行為特征的提取與檢測是有效識別惡意代碼的方法.行為序列可以看作一系列內(nèi)在關(guān)聯(lián)的函數(shù)調(diào)用,而惡意代碼的行為是為達(dá)到某種獲利目的的執(zhí)行邏輯,表現(xiàn)為一系列敏感函數(shù)調(diào)用或代碼段的執(zhí)行[14].通過建立惡意代碼行為依賴關(guān)系圖是近年來檢測惡意代碼的有益嘗試,不管是為惡意軟件家族建立一個(gè)共同的行為依賴圖[15],還是從惡意代碼家族行為依賴圖中挖掘出代表家族顯著共性特征的最大頻繁子圖[16],均是基于污點(diǎn)跟蹤的API系統(tǒng)調(diào)用行為間依賴關(guān)系的實(shí)現(xiàn),用行為依賴圖的匹配來判別惡意行為.當(dāng)然,這些方法有一定的局限性,比如只觀察可執(zhí)行文件的部分行為,如果惡意軟件在受監(jiān)視的環(huán)境中運(yùn)行時(shí)可以隱藏其惡意行為,則該方法無效.
在API方面,API被用來訪問內(nèi)、外部資源,其中惡意API調(diào)用頻繁序列可被模式挖掘技術(shù)用來識別惡意軟件行為的經(jīng)驗(yàn),從而建立惡意行為的基礎(chǔ).Jerbi等人[17]通過遺傳算法進(jìn)化出大量API調(diào)用序列,根據(jù)一組定義良好的進(jìn)化規(guī)則來發(fā)現(xiàn)新的惡意軟件行為,該檢測方法的性能取決于惡意軟件實(shí)例的基礎(chǔ)多樣化,因此需要人工加入一些惡意行為來豐富實(shí)例基礎(chǔ),以最大限度地提高檢測率.Eiter等人[18]引入IO依賴關(guān)系的語義信息優(yōu)化了API訪問檢查,直觀地將調(diào)用外部源的結(jié)果中出現(xiàn)的值與提供給該調(diào)用的輸入中出現(xiàn)的值聯(lián)系起來,能更精確地近似真實(shí)的依賴關(guān)系,雖然在檢查和優(yōu)化依賴關(guān)系的屬性時(shí)有一定的局限性,但在評估具有外部源訪問的程序惡意代碼時(shí)能顯著降低成本.
總之,代碼之間具有某種行為關(guān)聯(lián),即使是惡意代碼及其變種結(jié)合了混淆和代碼更改技術(shù)使其具有不同的語法結(jié)構(gòu),但在行為上仍具有相似性、序列性或某種依賴關(guān)系[19-21].在面對一些建模方法無法描述和分析的應(yīng)用程序行為(如遞歸),也往往結(jié)合屬性語法和數(shù)據(jù)流分析來捕獲程序的行為并構(gòu)建行為數(shù)據(jù)依賴圖[22].本文借鑒于此通過動(dòng)態(tài)污點(diǎn)傳播分析提取惡意代碼在進(jìn)行API函數(shù)調(diào)用時(shí)的行為依賴關(guān)系,并結(jié)合自定義污點(diǎn)傳播規(guī)則生成精確行為依賴圖(Precise Behavior Dependency Graph,簡稱PBDG),特別的,將基于依賴關(guān)系的語義行為過濾,以及對程序代碼的語義分析和動(dòng)態(tài)污點(diǎn)分析緊密結(jié)合,以達(dá)成軟件語義缺陷檢測精度的有效性,從而挖掘Web應(yīng)用程序中的潛在漏洞.通過污點(diǎn)分析技術(shù)深入研究程序的行為蹤跡與執(zhí)行路徑,根據(jù)語義的數(shù)據(jù)依賴關(guān)系和控制依賴關(guān)系實(shí)現(xiàn)精確行為依賴關(guān)系和靜動(dòng)態(tài)結(jié)合的污點(diǎn)分析.
定義1.函數(shù)調(diào)用可以用一個(gè)三元組sys_call={ret,arginput,argoutput}來描述.其中,ret表示函數(shù)調(diào)用的返回值,arginput表示函數(shù)調(diào)用的入口參數(shù),argoutput表示函數(shù)調(diào)用的出口參數(shù).
定義2.在污點(diǎn)傳播分析中每個(gè)污點(diǎn)的狀態(tài)可以用一個(gè)五元組Taint= {add,len,sta,type,p_info}表示.其中,add表示污點(diǎn)的起始地址,len表示污點(diǎn)長度,sta表示污點(diǎn)狀態(tài),type表示污點(diǎn)類型,p_info表示數(shù)據(jù)的上下文訪問路徑.
污點(diǎn)狀態(tài)sta包括untaint(清潔)、taint(被污染)和malicious(惡意代碼)3種,它們在受污染程度上滿足untaint 定義3.ChTaint(a,status)表示為對污點(diǎn)變量a變換污點(diǎn)的狀態(tài).如果a的原先污點(diǎn)狀態(tài)為untaint,則該操作稱為被污染過程,表示為: 定義4.?清潔變量a和上下文路徑p,a位于p上,且α?x.對于Tainta,存在a被標(biāo)記或誤報(bào)成疑似污點(diǎn),如果經(jīng)過算法1驗(yàn)證未被污染,則對起始地址為adda的污點(diǎn)數(shù)據(jù)進(jìn)行污點(diǎn)凈化,表示為: (ChTaint(α,taint))→(ChTaint(α,untaint)) 定義5.污點(diǎn)傳播是將污點(diǎn)變量右值Rv的污點(diǎn)信息傳遞給左值Lv,表示為:τ(Lv)=τ(Rv). 為了提取惡意代碼中的行為特征,本文通過污點(diǎn)文件,并結(jié)合惡意代碼執(zhí)行路徑的驗(yàn)證實(shí)現(xiàn)精確行為依賴圖的生成,應(yīng)用于惡意代碼的跟蹤檢測,其總體模型如圖1所示. 圖1 污點(diǎn)文件生成與驗(yàn)證模型Fig.1 Generation and verification of tainted file 首先,對惡意代碼源程序進(jìn)行動(dòng)態(tài)污點(diǎn)傳播分析,根據(jù)自定義的污點(diǎn)傳播規(guī)則獲取程序執(zhí)行的相關(guān)信息,包括系統(tǒng)調(diào)用、函數(shù)調(diào)用及其參數(shù)的數(shù)據(jù)依賴關(guān)系和控制依賴關(guān)系,使用操作序列文件tracer來記錄惡意代碼函數(shù)調(diào)用間的關(guān)鍵數(shù)據(jù).為了節(jié)省tracer文件占用的存儲資源,與傳統(tǒng)記錄的方式不同,采用僅對新增指令引用的值進(jìn)行記錄的增量式文件存儲方式.然后,對tracer文件進(jìn)行過濾,對Source集合進(jìn)行黑名單過濾,排除不屬于外部惡意輸入的Source,確保Source獲取的值是真實(shí)的外部惡意輸入,通過污點(diǎn)分析得到從Source到Sink的污點(diǎn)傳播路徑,對生成可配置的污點(diǎn)文件再利用活躍變量路徑驗(yàn)證算法進(jìn)行逆向的路徑遍歷來驗(yàn)證Sink→Source路徑的準(zhǔn)確性.經(jīng)過驗(yàn)證后,對source到sink的不可達(dá)路徑進(jìn)行剪枝處理,在降低路徑爆炸風(fēng)險(xiǎn)的同時(shí),能節(jié)省計(jì)算資源,并提高路徑驗(yàn)證的準(zhǔn)確率. 通過污點(diǎn)傳播分析可以分析相應(yīng)的攻擊行為,能夠提取攻擊信息.通過自定義的污點(diǎn)傳播分析規(guī)則對函數(shù)調(diào)用中的敏感數(shù)據(jù)進(jìn)行污點(diǎn)跟蹤,得到行為之間的依賴關(guān)系,用于活躍變量路徑驗(yàn)證. 首先定義一個(gè)taint集合用來動(dòng)態(tài)存儲污點(diǎn)變量信息,將經(jīng)過黑名單過濾的Source集合中的污點(diǎn)變量加入taint集合中.其次進(jìn)行污點(diǎn)傳播分析,對污點(diǎn)數(shù)據(jù)進(jìn)行跟蹤,根據(jù)自定義的污點(diǎn)傳播規(guī)則記錄污點(diǎn)的傳遞過程,對一些具有特殊功能的函數(shù)增加控制依賴性分析,例如拷貝函數(shù)strcpy、strcat,內(nèi)存分配函數(shù)mallco、calloc,以及調(diào)用過程會間接影響其它函數(shù)的調(diào)用從而導(dǎo)致隱式流產(chǎn)生的函數(shù)setjmp、longjmp等.基于定義5,設(shè)定污點(diǎn)對相應(yīng)變量進(jìn)行賦值與調(diào)用等操作的規(guī)則,這些規(guī)則針對形如“Lv=Rv”的變量表示,獲得污點(diǎn)變量左值Lv的狀態(tài). 規(guī)則1.賦值規(guī)則 ① 若右值Rv為常量,通過以下賦值可以消除Lv的污點(diǎn)狀態(tài). τ(Lv)=untaint ② 若右值Rv形如Lv= arr[i](數(shù)組元素),Rv的污點(diǎn)狀態(tài)為對所有數(shù)組元素污點(diǎn)狀態(tài)求并集. τ(Rv)=untaint τ(Rv)=τ(Rv)∪τ(i) τ(Lv)=τ(Rv) fori=1,…,n ③ 若右值Rv形如Lv=b.v(對象實(shí)例的成員變量)/Lv=class.v(全局靜態(tài)變量),Rv的污點(diǎn)狀態(tài)為對所有使用變量污點(diǎn)狀態(tài)求并集. τ(Rv)=untaint τ(Rv)=τ(Rv)∪τ(vi) τ(Lv)=τ(Rv) fori=1,…,n 規(guī)則2.方法調(diào)用規(guī)則 ① 對于形如x=invoke a.f(arg1,arg2)的方法調(diào)用首先判斷是否有參數(shù),若無參數(shù),則按下式直接返回對象屬性a.x的值. τ(Lv)=τ(a.x) ② 若有參數(shù),且實(shí)例對象a或任意參數(shù)污點(diǎn)狀態(tài)為taint或malicious,則對所有參數(shù)污點(diǎn)狀態(tài)求并集. τ(Rv)=τ(a) τ(Rv)=τ(Rv)∪τ(argi) τ(Lv)=τ(Rv) fori=1,…,n 在Java中存在許多后門(敏感)函數(shù),它們是針對不同的漏洞而存在.例如eval()、system()等代碼執(zhí)行函數(shù);又如ServletFileUpload()、FileItemStream()、MultipartFile()等文件上傳函數(shù); 還有g(shù)etRuntime()、exec()、cmd()、shell()等命令注入函數(shù); 以及Delete()、deleteFile()、fileName()、filePath()等任意文件刪除函數(shù);另有SAXBuilder()、DocumentBuilder()、XMLStreamReader()等XML注入函數(shù),這樣一些具有特殊功能的函數(shù)經(jīng)常被作為攻擊的調(diào)用.因此,對于這些危險(xiǎn)的或關(guān)鍵的函數(shù)類建立一個(gè)可配置的動(dòng)態(tài)黑名單文件寫入Source集合中.隨著新的惡意函數(shù)被發(fā)現(xiàn),黑名單信息量將不斷擴(kuò)充. 將外部惡意輸入的數(shù)據(jù)標(biāo)記為污點(diǎn)起源Source,而將可能破壞數(shù)據(jù)完整性、機(jī)密性的方法標(biāo)記為污點(diǎn)匯聚點(diǎn)Sink.在web應(yīng)用程序中,Source多數(shù)來自GET變量、表單POST、數(shù)據(jù)庫、會話變量等. 在檢查惡意代碼時(shí),本文首先通過動(dòng)態(tài)污點(diǎn)傳播分析,對其運(yùn)行一系列的自動(dòng)測試.測試會生成tracer序列,將tracer序列中的敏感函數(shù)引入到污點(diǎn)起源Source中,當(dāng)然,其中并非所有函數(shù)都具有惡意行為.例如,引入的Source信息可能是用于操作系統(tǒng)登錄過程的按鍵,也可能是Web表單中的用戶輸入.因此對污點(diǎn)起源Source進(jìn)行預(yù)處理來排除非惡意行為的輸入.通過在污點(diǎn)分析過程中添加Source黑名單,主要對黑名單中的方法進(jìn)行記錄,過濾黑名單以外的函數(shù),將不屬于惡意輸入的Source過濾掉,節(jié)約存儲空間的同時(shí)提高檢測效率.對Source過濾之后建立一個(gè)污點(diǎn)索引文件,由于被標(biāo)記污點(diǎn)的變量都包含add起始地址與len長度的標(biāo)記,應(yīng)用此索引文件可以快速定位到指定的指令,應(yīng)用于后文的活躍變量路徑驗(yàn)證算法中,提高驗(yàn)證效率. 對污點(diǎn)索引文件中生成的Source→Sink路徑進(jìn)行活躍變量路徑驗(yàn)證,使用活躍變量路徑驗(yàn)證算法逆向遍歷,對所生成的污點(diǎn)路徑進(jìn)行驗(yàn)證.經(jīng)驗(yàn)證后對不真實(shí)存在污點(diǎn)傳播的路徑進(jìn)行污點(diǎn)凈化,以進(jìn)一步降低路徑空間. 定義6.活躍變量分析計(jì)算:?α,ξ,t(α表示變量,ξ表示程序點(diǎn),t表示ξ的執(zhí)行路徑),若在t中發(fā)現(xiàn)α(記為〈α∝t〉)則說明α在程序點(diǎn)ξ是活躍的.其中,Input表示入口處活躍變量的集合,經(jīng)過逆向數(shù)據(jù)流求解后,將α之后的活躍變量集合作為Output.存在下式: Input[a]=ηs(Output[a]) (1) 其中,ηs為傳遞函數(shù),描述代碼執(zhí)行前后的數(shù)據(jù)流值在輸入輸出后變化的語義約束. 定義7.genB表示變量在基本塊Bi中被定義的活躍敏感參數(shù)定值集合(從Sink集合中選出),killB表示在基本塊Bi中不活躍的變量集合,succ(B)表示基本塊B的所有后繼基本塊的集合.存在下式: Input[B]=genB∪(Output[B]-killB) (2) (3) 根據(jù)定義6,計(jì)算分析得到基本塊中活躍變量的Input與Output集合,通過路徑敏感的上下文分析以及對Input進(jìn)行跟蹤可以得到從程序控制流圖終止點(diǎn)end到起始點(diǎn)start的逆向執(zhí)行路徑(即Sink→Source路徑),便可以驗(yàn)證路徑的準(zhǔn)確性,從而提高分析的準(zhǔn)確率. 活躍變量的OutputgenB上下文可以用{Funcall,SensiveP,Blockid,Valuecon,pathtrav}的形式表示,其中Funcall表示所調(diào)用的函數(shù),SensiveP表示敏感參數(shù)(Sink集合),Blockid表示所在的基本塊號碼,Valuecon表示定值信息,pathtrav表示路徑遍歷信息.一段存在驗(yàn)證漏洞的java代碼如圖2所示,通過上述的表示形式可以很好地對路徑進(jìn)行驗(yàn)證. 圖2 含有漏洞的java代碼Fig.2 Section of java code with vulnerability 根據(jù)圖2,分析后可以得到相應(yīng)的控制依賴關(guān)系,如圖3所示.此段代碼中存在兩個(gè)注入點(diǎn)name和pwd(記為Source點(diǎn)),但是最終賦值給了變量login(記為Sink點(diǎn)),所以將login標(biāo)記為敏感參數(shù),并將login加入genB集合中. 圖3 代碼的控制依賴圖Fig.3 Control dependency graph of a piece of code 圖3中顯示的是將敏感參數(shù)login作為活躍變量來進(jìn)行路徑驗(yàn)證.根據(jù)公式(2),顯然可以得出Input[B]={logingen}∪(Output[B]-loginkill).利用控制依賴關(guān)系可以得出InputB1={02,03,04,05}.繼續(xù)迭代循環(huán)基本塊B2,B3,B4,B5.得到InputB5={05,07,09,10,11}.經(jīng)過分析得到B5的輸出流來源于定值05,通過查找定值表(如表1所示),定值05所在的變量得知,05定值來自變量name.所以name在Source點(diǎn)是活躍的,即Sink→Source路徑驗(yàn)證真實(shí)可達(dá).Outputlogin={print,login,B5,11,(11→10→09→07→05→04→02)}.其中print是所調(diào)用的函數(shù)Funcall,login為敏感參數(shù)SensiveP,逆向追蹤遍歷路徑pathtrav為(11→10→09→07→05→04→02).路徑驗(yàn)證算法用于逆向遍歷從敏感參數(shù)到程序開始的路徑(即從sink到source).圖3控制依賴圖中的變量名與定值對應(yīng)關(guān)系如表1所示. 表1 變量名與定值關(guān)系表Table 1 Relationship between variable name and value 算法1.活躍變量路徑驗(yàn)證算法. Input:控制流圖CFG中已求出的每個(gè)基本塊的活躍敏感參數(shù)定值集合genB、不活躍變量集合killB; Output:驗(yàn)證后的逆向遍歷路徑信息pathtrav. Begin { 1.Input[end]=φ; /*end節(jié)點(diǎn)為程序的出口*/ 2.for eachBin CFG do /*遍歷控制流圖*/ 3. Input[B]=φ; /*對基本塊初始化*/ 4.end for 5.change=true; /*用change記錄Input變化*/ 6.while(change) do 7. change=false; 8. for eachBin CFG do 10. old=Input[B]; 11. Input[B]=genB∪(Output[B]-killB); /*過濾掉即將重新賦值的killB*/ 12. if(old!=Input[B]) then change=true; 13. end for 14.end while 15.for eachBendin CFG do 16. pathtrav=Output[Bend]; /*遍歷最后基本塊并取Output首元素*/ 17. print pathtrav; /*輸出逆向遍歷路徑*/ 18.end for }End 算法1采用活躍變量計(jì)算分析逆向傳播定值,直到此定值被過濾掉,算法才停止.因?yàn)閷τ诿總€(gè)基本塊B,Input[B]被初始化為φ,迭代過程中Input[B]不會減小,所以當(dāng)有定值加入到Input中不會存在丟失的情況.如果一個(gè)定值能夠到達(dá)程序點(diǎn),則它必須經(jīng)過一條路徑.使用迭代的方法求解,在while的每次迭代過程中,每個(gè)定值至少沿著相應(yīng)的路徑前進(jìn)一個(gè)點(diǎn).由于定值的集合是有限的,所以算法終止的標(biāo)志為while循環(huán)執(zhí)行后沒有再向Input中添加內(nèi)容,算法結(jié)束時(shí)輸出此時(shí)的遍歷路徑. 基于污點(diǎn)文件生成精確行為依賴圖,考慮了路徑敏感的污點(diǎn)分析方法.為了避免控制依賴干擾數(shù)據(jù)依賴的情況發(fā)生,所分析的依賴關(guān)系既包括數(shù)據(jù)依賴關(guān)系也包括控制依賴關(guān)系. 定義8.精確行為依賴圖可以用一個(gè)四元組G=(Entry,P,DE,CE)來表示.其中,Entry表示圖的入口節(jié)點(diǎn),P表示節(jié)點(diǎn),DE(滿足DE∈P×P)表示數(shù)據(jù)依賴邊,CE(滿足CE∈P×P)表示控制依賴邊. 數(shù)據(jù)依賴邊DE的添加要通過活躍變量路徑驗(yàn)證算法反向驗(yàn)證產(chǎn)生污點(diǎn)的函數(shù)調(diào)用與其相關(guān)聯(lián)的節(jié)點(diǎn),并在兩個(gè)節(jié)點(diǎn)之間添加一條數(shù)據(jù)依賴邊.控制依賴邊CE的添加則是分析具有污點(diǎn)屬性的數(shù)據(jù)是否對標(biāo)志寄存器EFlages改變,可以通過檢查污點(diǎn)信息中的type字段是否為0來判斷.若標(biāo)志寄存器作為污點(diǎn)分析控制流轉(zhuǎn)移的判別條件,計(jì)算新的函數(shù)調(diào)用在其后必經(jīng)節(jié)點(diǎn)所在的范圍內(nèi),則在兩個(gè)頂點(diǎn)之間添加一條控制依賴邊.若在某個(gè)函數(shù)調(diào)用中,既存在數(shù)據(jù)依賴又存在控制依賴,則在兩個(gè)節(jié)點(diǎn)間添加兩條依賴邊. 定義9.通過對污點(diǎn)文件的分析,查看函數(shù)調(diào)用中的污點(diǎn)傳播路徑,給定兩個(gè)已知的節(jié)點(diǎn)P1和P2,當(dāng)且僅當(dāng)P1和P2之間存在數(shù)據(jù)關(guān)聯(lián)關(guān)系并且P1調(diào)用了P2,則在精確行為依賴圖中記錄P1與P2的數(shù)據(jù)依賴關(guān)系,記為DE(P1|→P2). 定義10.程序在運(yùn)行的時(shí)候,會出現(xiàn)新的頂點(diǎn)P3被調(diào)用,這時(shí)需要考慮程序的跳轉(zhuǎn)問題.通過分析帶有污點(diǎn)屬性的數(shù)據(jù)是否有通過控制轉(zhuǎn)移指令進(jìn)行直接或者間接的跳轉(zhuǎn).若路徑t處于P3、P4兩個(gè)節(jié)點(diǎn)之間,當(dāng)僅存在一條執(zhí)行路徑從節(jié)點(diǎn)P3到程序結(jié)束且經(jīng)過P4,則P4控制依賴于P3,記為:CE(P3|→P4). 算法2.精確行為依賴圖構(gòu)建算法. Input:污點(diǎn)文件(TF); Output:精確行為依賴圖PBDG. Begin { 1.for each funcalin TF do /*遍歷TF中的函數(shù)調(diào)用*/ 2. add funcal(pi); /*添加節(jié)點(diǎn)p*/ 3. for each controlrel in TF do /*遍歷TF中的控制依賴*/ 4. add controlrel(Bi); /*添加基本塊B*/ 5. end for 6.end for 7.for each Biin funcaldo 8. if(p1|→p2) then 9. PBDG.add-DE(p1,p2); /*添加數(shù)據(jù)依賴邊*/ 10. end if 11. if(p3|→p4) then 12. PBDG.add-CE(p3,p4); /*添加控制依賴邊*/ 13. end if 14.end for }End 算法2首先對TF文件進(jìn)行分析,其中的函數(shù)調(diào)用關(guān)系用funcal表示,controlrel表示控制依賴,通過對污點(diǎn)文件中的控制流圖進(jìn)行遍歷,若符合定義中的DE(P1|→P2),則在節(jié)點(diǎn)p間添加數(shù)據(jù)依賴邊.若出現(xiàn)CE(P3|→P4),則在節(jié)點(diǎn)間添加控制依賴邊.當(dāng)對污點(diǎn)文件分析結(jié)束時(shí),算法生成最終的PBDG. 精確行為依賴圖PBDG提供了精準(zhǔn)的行為依賴關(guān)系分析,能有效提高惡意代碼的識別率.當(dāng)前,出現(xiàn)溢出漏洞的主要原因是由于不安全函數(shù)的調(diào)用所引起,可以使用PBDG對溢出漏洞進(jìn)行驗(yàn)證.以CVE-2017-13089棧溢出漏洞為例,2017年11月12日NVD公布了關(guān)于wget的漏洞情報(bào),對wget緩沖區(qū)溢出漏洞進(jìn)行分析.該漏洞主要是由于wget組件在處理401狀態(tài)碼的數(shù)據(jù)響應(yīng)包時(shí),沒有對讀取的包做正負(fù)檢查,導(dǎo)致的整數(shù)棧溢出.wget在處理重定向時(shí),會調(diào)用skip_short_body()函數(shù),解析器在解析塊時(shí)會使用strtol() 函數(shù)讀取每個(gè)塊的長度,但并沒有去檢查塊長度是否為負(fù)數(shù).解析器試圖通過使用MIN()函數(shù)跳過塊的前512個(gè)字節(jié),最終傳遞參數(shù)到函數(shù)fd_read()中.由于fd_read()僅會接受一個(gè)int參數(shù),當(dāng)攻擊者試圖將一個(gè)負(fù)數(shù)作為參數(shù)時(shí),塊長度的高32位將會被丟棄,攻擊者從而可以控制fd_read()中的長度參數(shù),引發(fā)整形緩沖區(qū)溢出漏洞. 可以把skip_short_body()看做Source點(diǎn),fd_read()看做Sink點(diǎn),對skip_short_body()函數(shù)進(jìn)行分析.首先該函數(shù)對于傳入的第一個(gè)參數(shù)sock獲取到http響應(yīng)包的響應(yīng)體指針line;然后調(diào)用strtol函數(shù),將line變量指的值轉(zhuǎn)為整型;接著通過MIN(remaining_chunk_size,SKIP_SIZE)得到響應(yīng)體的長度contlen;之后調(diào)用fd_read函數(shù),將響應(yīng)體內(nèi)容復(fù)制到棧中;fd_read函數(shù)封裝了sock_read函數(shù),sock_read函數(shù)調(diào)用了read函數(shù),從這里出現(xiàn)了棧溢出漏洞.通過對相關(guān)函數(shù)的調(diào)用分析,生成精確行為依賴圖,如圖4所示,描述了多個(gè)函數(shù)相互作用而構(gòu)成的數(shù)據(jù)依賴關(guān)系與控制依賴關(guān)系.基于PBDG對代碼進(jìn)行分析,與傳統(tǒng)的PDG方法等相比,能獲得更加清晰的數(shù)據(jù)流,檢測的路徑更加精確. 圖4 相關(guān)函數(shù)的精確行為依賴圖Fig.4 Precise behavior dependence graph of correlation function 實(shí)驗(yàn)所用的機(jī)器配置為Intel i5-8500CPU系統(tǒng)為windows10操作系統(tǒng),開發(fā)環(huán)境基于JDK 7,Soot-2.5.0,工具為Eclipse,編程語言為java.惡意代碼行為依賴圖的構(gòu)建是基于模擬器SOOT平臺實(shí)現(xiàn)的,通過在虛擬系統(tǒng)中對代碼進(jìn)行動(dòng)態(tài)分析,對執(zhí)行的代碼進(jìn)行審計(jì).實(shí)驗(yàn)數(shù)據(jù)集選取的是兩個(gè)Web漏洞網(wǎng)站W(wǎng)ebGoat和BodgeIt以及另外兩款用作對比參照的惡意軟件Alina和Mirai. 4.2.1 實(shí)驗(yàn)過程 首先結(jié)合使用Selenium自動(dòng)化測試工具分別對上述4種數(shù)據(jù)集構(gòu)建惡意代碼行為依賴圖,作為對照,選取傳統(tǒng)的行為依賴圖PDG[3]和公共行為依賴圖CDG[15]的構(gòu)建方法,與所提出的精確行為依賴圖PBDG在構(gòu)建規(guī)模和時(shí)間上的情況,如表2所示.然后在依賴圖的生成質(zhì)量和對敏感路徑的處理上進(jìn)行比較驗(yàn)證. 表2 依賴圖的構(gòu)建時(shí)間與規(guī)模Table 2 Construction time and scale of dependency graph 從表2可以看出,由于PBDG方法過程通過上文提出的Source黑名單構(gòu)建和過濾機(jī)制,以及受到自定義的污點(diǎn)傳播規(guī)則的限制,所以檢測到的函數(shù)調(diào)用數(shù)量遠(yuǎn)少于傳統(tǒng)PDG方法,略優(yōu)于CDG方法,構(gòu)造出的依賴圖邊數(shù)與節(jié)點(diǎn)數(shù)有了明顯的減少,避免路徑爆炸,有效節(jié)約了空間開銷.由于CDG采用從依賴圖中提取行為圖的方法,所以在依賴圖的構(gòu)建方面比傳統(tǒng)依賴圖PDG和PBDG方法要消耗更多的時(shí)間. 4.2.2 依賴圖生成質(zhì)量對比分析 通過對3種構(gòu)建方法生成的行為依賴圖進(jìn)行Source→Sink靜態(tài)分析,驗(yàn)證污點(diǎn)路徑的準(zhǔn)確性,進(jìn)而降低漏洞的誤報(bào)率.在對依賴圖分析后獲得的漏洞報(bào)告情況如表3所示. 表3 依賴圖生成質(zhì)量的表現(xiàn)(個(gè))Table 3 Generation quality of dependency graph BodgeIt中實(shí)際共有15個(gè)漏洞,根據(jù)表3可以看出,通過算法2構(gòu)建的精確行為依賴圖分析,報(bào)告出共13個(gè)漏洞,對其進(jìn)行活躍變量路徑驗(yàn)證分析后,驗(yàn)證出其中12個(gè)漏洞報(bào)告準(zhǔn)確,誤報(bào)1個(gè)漏洞.WebGoat中實(shí)有30個(gè)潛在漏洞,報(bào)告出27個(gè)漏洞,經(jīng)過驗(yàn)證其中有2個(gè)漏洞為誤報(bào).Alina中實(shí)有35個(gè)漏洞,分析出26個(gè),其中有5個(gè)漏洞被驗(yàn)證為誤報(bào).Mirai中實(shí)有42個(gè)漏洞,經(jīng)算法2分析出30個(gè)漏洞,其中有7個(gè)漏洞誤報(bào).由于本文方法主要應(yīng)用于對Web應(yīng)用中的漏洞分析,所以在BodgeIt和WebGoat中發(fā)現(xiàn)漏洞以及漏洞誤報(bào)明顯優(yōu)于傳統(tǒng)的PDG方法和CDG方法.但是在對惡意軟件Alina和Mirai中發(fā)現(xiàn)的漏洞與漏洞誤報(bào)比PDG方法略好,而CDG由于采用了基于最大權(quán)子圖的圖匹配算法用加權(quán)圖來描述惡意軟件家族的常見行為,通過犧牲時(shí)間來換取一定的惡意軟件漏洞檢測率. 測試網(wǎng)站W(wǎng)ebGoat中有SQL注入漏洞代碼如下: final String kid=(String) header.get("kid"); try(var connection=dataSource.getConnection()){ ResultSetrs=connection.createStatement().executeQuery ("SELECT key FROM jwt_keys WHERE id=′" + kid + "′"); while(rs.next()){ return TextCodec.BASE64.decode(rs.getString(1));} } 實(shí)驗(yàn)采用PDG傳統(tǒng)方法構(gòu)建行為依賴圖未能發(fā)現(xiàn)該漏洞.由于WebGoat使用了預(yù)編譯方法PrepareStatement調(diào)用函數(shù),將數(shù)據(jù)代碼分離,且通過BASE64.decode()函數(shù)進(jìn)行BASE64解碼,使得傳統(tǒng)方法無法識別;而采用PBDG方法通過黑名單構(gòu)建和過濾機(jī)制成功檢測出預(yù)編譯PrepareStatement調(diào)用函數(shù),以及BASE64.decode()函數(shù),再通過路徑驗(yàn)證算法遍歷路徑,可以成功建立路徑Sink(key)→Source(kid),最終發(fā)現(xiàn)SQL注入點(diǎn)kid. 更直觀的,給定準(zhǔn)確率用?表示,按下式計(jì)算: ?=n/N (4) 其中,n表示確定為漏洞的數(shù)量,即發(fā)現(xiàn)漏洞的數(shù)量減去誤報(bào)的數(shù)量,N表示實(shí)際存在的漏洞個(gè)數(shù). 誤報(bào)率用μ表示,按下式計(jì)算: μ=e/E (5) 其中,e表示漏洞誤報(bào)的數(shù)量,E表示實(shí)際存在的漏洞個(gè)數(shù). 不同方法對目標(biāo)漏洞檢測的準(zhǔn)確率和誤報(bào)率如圖5和圖6所示. 圖5 對數(shù)據(jù)集的檢測準(zhǔn)確率Fig.5 Detection accuracy of four data sets 由圖5和圖6可以看出,本文方法在發(fā)現(xiàn)漏洞的準(zhǔn)確率與誤報(bào)率均好于傳統(tǒng)方法PDG,但是由于本文方法主要面向Web應(yīng)用漏洞,所以在針對后兩款惡意軟件檢測時(shí),采用了共性行為依賴預(yù)處理的CDG方法的準(zhǔn)確率與誤報(bào)率優(yōu)于其他兩種,但此時(shí)PBDG與PDG相比仍有較好的表現(xiàn). 4.2.3 路徑驗(yàn)證對比分析 經(jīng)過活躍變量路徑驗(yàn)證算法驗(yàn)證后,能夠有效地對Source→Sink的不可達(dá)路徑進(jìn)行剪枝.通過與其他兩種方法對比檢查Source→Sink的路徑數(shù)量如表4所示,通過本文活躍變量路徑驗(yàn)證后需要遍歷的路徑有明顯的減少,最高減少了91.2%,最低減少了8.7%.由于Source的黑名單后門函數(shù)是針對Web應(yīng)用的,所以對于兩款惡意軟件的Source沒有進(jìn)行有效的過濾,在后兩款惡意軟件中需要驗(yàn)證的路徑數(shù)與其他兩種相比沒有得到明顯的減少. 表4 路徑檢驗(yàn)條數(shù)Table 4 Number of check paths 總體來說,本文提出的PBDG構(gòu)建方法,可以有效提高漏洞發(fā)現(xiàn)的準(zhǔn)確率,降低誤報(bào)率.經(jīng)過分析后,需要驗(yàn)證的路徑明顯少于其他兩種方法,但在圖構(gòu)建時(shí)間方面還有待提高. 4.2.4ACCmin對依賴圖生成質(zhì)量的影響 ACCmin為最小精確值,定義如式(6)所示. (6) 隨著PBDG依賴圖的構(gòu)建的擴(kuò)大,活躍變量路徑驗(yàn)證算法中定值Valuecon和InputBend(其中下標(biāo)Bend表示最后一個(gè)基本塊)也不斷變化,準(zhǔn)確率?和誤報(bào)率μ也會隨著發(fā)生變化.在Web應(yīng)用中,通過調(diào)整ACCmin的值,發(fā)現(xiàn)準(zhǔn)確率?和誤報(bào)率μ發(fā)生如圖7變化. 圖7 準(zhǔn)確率與誤報(bào)率隨ACCmin的變化情況Fig.7 Changes of accuracy and false rate with ACCmin 從圖7準(zhǔn)確率與誤報(bào)率隨ACCmin的變化情況中可以看出,當(dāng)ACCmin=0.4時(shí),準(zhǔn)確率達(dá)到最高83%;當(dāng)ACCmin> 0.4時(shí),準(zhǔn)確率開始出現(xiàn)明顯下降趨勢.當(dāng)0.4≤ACCmin≤0.5時(shí),誤報(bào)率最低為7%;ACCmin> 0.5時(shí),誤報(bào)率出現(xiàn)了小幅的上漲.因此,綜合分析準(zhǔn)確率?和誤報(bào)率μ的情況,將最小精確值A(chǔ)CCmin設(shè)置為0.45,誤報(bào)率與準(zhǔn)確率效果達(dá)到最佳. 提出了精確行為依賴圖PBDG的構(gòu)建方法,并基于該方法實(shí)現(xiàn)了惡意代碼行為依賴圖的構(gòu)建,與傳統(tǒng)的行為依賴圖構(gòu)建相比,其相關(guān)數(shù)據(jù)的控制依賴關(guān)系與數(shù)據(jù)依賴關(guān)系更加清晰,活躍變量路徑的引入,優(yōu)化了路徑分析過程.實(shí)驗(yàn)結(jié)果表明該方法在多種實(shí)驗(yàn)數(shù)據(jù)集中的有效性,尤其在對Web應(yīng)用程序進(jìn)行檢測時(shí)效果更好,能有效地提高漏洞發(fā)現(xiàn)的準(zhǔn)確率,降低了漏洞的誤報(bào)率.由于本文使用污點(diǎn)分析與活躍變量路徑驗(yàn)證,所以要分析更多的指令,在指令分析的優(yōu)化方面需得到有效提高.下一步工作將符號化污點(diǎn)分析與代碼混淆技術(shù)結(jié)合進(jìn)來,對包括Web漏洞和惡意軟件等具有變種的惡意代碼進(jìn)行更好的檢測.在不影響準(zhǔn)確率的情況下,進(jìn)一步縮短依賴圖構(gòu)建時(shí)間和遍歷時(shí)間.3 基于污點(diǎn)文件的依賴圖生成與驗(yàn)證
3.1 自定義污點(diǎn)傳播規(guī)則
3.2 Source黑名單構(gòu)建
3.3 Source黑名單過濾
3.4 活躍變量路徑驗(yàn)證算法
3.5 生成惡意代碼精確行為依賴圖
3.6 應(yīng)用PBDG分析漏洞
4 實(shí)驗(yàn)過程與分析
4.1 實(shí)驗(yàn)環(huán)境與數(shù)據(jù)
4.2 實(shí)驗(yàn)結(jié)果及分析
5 結(jié) 論