王 婷,牟永敏,張志華,崔展齊
(北京信息科技大學(xué)網(wǎng)絡(luò)文化與數(shù)字傳播北京市重點(diǎn)實(shí)驗(yàn)室,北京 100101)
隨著互聯(lián)網(wǎng)規(guī)模的快速增長和用戶人數(shù)的迅速增加,互聯(lián)網(wǎng)公司在產(chǎn)品的用戶體驗(yàn)上有著越來越高的追求。前端部分的重要性日益凸顯,導(dǎo)致大量的業(yè)務(wù)邏輯由服務(wù)端轉(zhuǎn)移到客戶端。Bichhawat等人[1]的研究結(jié)果表明超過95%的Web應(yīng)用選用JavaScript語言進(jìn)行前端開發(fā)。JavaScript語言所具有的跨平臺(tái)、可遠(yuǎn)程嵌入、能動(dòng)態(tài)執(zhí)行的特性在為用戶提供更好的交互體驗(yàn)的同時(shí),也給Web應(yīng)用帶來了更多的安全上的風(fēng)險(xiǎn)和威脅[2]。大量的安全報(bào)告表明,惡意網(wǎng)頁已成為攻擊者針對(duì) Web客戶端進(jìn)行攻擊的主要途徑和平臺(tái)[3]。因此,惡意JavaScript代碼的檢測成為一項(xiàng)影響Web應(yīng)用安全的重要研究課題。
網(wǎng)頁中的攻擊代碼常常具有多樣化和隱蔽性的特點(diǎn),其中17.1%的攻擊行為是通過混淆JavaScript代碼進(jìn)行.代碼混淆是一種為了避免安全系統(tǒng)檢測而改變數(shù)據(jù)形態(tài)的技術(shù)[4]。另外,Web前端應(yīng)用為減少代碼體積,加快網(wǎng)頁加載速度,通常會(huì)對(duì)代碼進(jìn)行優(yōu)化與壓縮。壓縮后的代碼常常與混淆后的代碼一樣失去可讀性,同時(shí)也為惡意代碼的隱藏提供了便利。隨著JavaScript代碼壓縮與混淆技術(shù)的成熟,惡意代碼的檢測也變得越來越困難。
研究表明,惡意代碼的行為常常具有某種規(guī)律[5]。如惡意代碼通常會(huì)更多地調(diào)用某幾種JavaScript語言的內(nèi)置函數(shù)以實(shí)現(xiàn)代碼惡意代碼的偽裝和隱藏,且為完成某種惡意功能,函數(shù)的調(diào)用順序以及函數(shù)之間的調(diào)用圖會(huì)具有某種一致性。而常用的代碼自動(dòng)壓縮與混淆工具為保證代碼在混淆前后語義上的等價(jià),通常會(huì)保持原有的函數(shù)調(diào)用信息不變[5]。因此,利用已知的惡意代碼中各函數(shù)的調(diào)用信息可以為新的惡意代碼檢測的提供參考。
針對(duì)以上問題,本文提出了基于函數(shù)調(diào)用信息的JavaScript混淆惡意代碼檢測方法。通過提取JavaScript代碼中的函數(shù)調(diào)用序列和函數(shù)調(diào)用關(guān)系圖,比較混淆前后函數(shù)調(diào)用關(guān)系的序列相似度和圖相似度,得到混淆前后代碼中函數(shù)的對(duì)應(yīng)關(guān)系,為JavaScript混淆代碼中惡意函數(shù)的檢測提供參考。
網(wǎng)頁中惡意代碼檢測的研究已經(jīng)歷了十余年的發(fā)展。自2004年開始,基于瀏覽器的客戶端蜜罐(honeypot)系統(tǒng)已成為一類檢測客戶端惡意代碼攻擊的有力工具。這些工具通常采用將可以網(wǎng)頁加載到易受攻擊的瀏覽器中并觀察系統(tǒng)總文件、注冊(cè)表和進(jìn)程的變化來檢測網(wǎng)頁中的惡意代碼[6]。
2.1.1 靜態(tài)分析的方法
Canali等[7]提出的Prophiler是一個(gè)利用靜態(tài)分析進(jìn)行惡意代碼和良性代碼分類的系統(tǒng)。Prophiler利用HTML及其關(guān)聯(lián)的JavaScript代碼以及URL信息構(gòu)建有監(jiān)督學(xué)習(xí)的監(jiān)測模型,對(duì)代碼進(jìn)行初步分類。再對(duì)被判定為惡意的代碼利用更精細(xì)的工具進(jìn)行分析。Prophiler的不足是無法應(yīng)對(duì)混淆后的惡意代碼。
Curtsinger等[8]提出的ZOZZLE是一個(gè)靜態(tài)的JavaScript惡意代碼檢測工具,其原理基于這樣的假設(shè):惡意的JavaScript代碼一定會(huì)在最終執(zhí)行前被反混淆。ZOZZLE利用JavaScript語言或宿主環(huán)境提供的可實(shí)現(xiàn)從字符串到代碼的轉(zhuǎn)換的函數(shù)(如document.write, eval)對(duì)代碼進(jìn)行反混淆,并將反混淆后的代碼轉(zhuǎn)換為抽象語法樹、然后將從抽象語法樹中提取的特征輸入到樸素貝葉斯分類器中。
2.1.2 動(dòng)態(tài)分析的方法
Xu等[5]提出的JStill通過分析器方法調(diào)用信息捕捉混淆惡意代碼中的特征,結(jié)合靜態(tài)分析和輕量級(jí)的運(yùn)行時(shí)檢查,檢測混淆后的代碼中的惡意代碼。JStill的設(shè)計(jì)思想基于如下假設(shè):混淆后的惡意代碼在被執(zhí)行前需要進(jìn)行一定程度的反混淆以完全實(shí)現(xiàn)其惡意功能,而反混淆的過程必然會(huì)調(diào)用特定的一組函數(shù),因此這組特定函數(shù)的調(diào)用情況可以作為判斷惡意代碼的一個(gè)依據(jù)。JStill將函數(shù)調(diào)用分為了原生函數(shù)(native function)、內(nèi)置函數(shù)(built-in function)、DOM方法以及用戶定義函數(shù)四類。JStill總結(jié)了惡意代碼在函數(shù)調(diào)用上與良性代碼的差別,包括:惡意代碼會(huì)從靜態(tài)的角度隱藏一些在反混淆中常用的函數(shù)的參數(shù),使得這些參數(shù)不會(huì)被靜態(tài)分析工具獲取或分析,因?yàn)閰?shù)通常會(huì)暴露代碼的惡意行為;惡意代碼會(huì)隱藏函數(shù)定義,使得從靜態(tài)分析的角度解析不到函數(shù)的定義等。JStill主要關(guān)注基于編碼/加密的混淆惡意代碼的檢測。
Gorji等[6]提出了一個(gè)基于內(nèi)部函數(shù)調(diào)用序列檢測混淆惡意代碼的方法。該方法的檢測分為兩個(gè)階段。首先是行為收集階段,通過在瀏覽器中加載真實(shí)的惡意的網(wǎng)頁,利用瀏覽器的調(diào)試工具收集函數(shù)調(diào)用信息。然后基于正則化的編輯距離將具有相似函數(shù)調(diào)用序列的網(wǎng)頁聚集為等價(jià)類,并且為每個(gè)等價(jià)類生成相應(yīng)的行為簽名(behavior signature)。完成行為收集后,進(jìn)入檢測階段。一個(gè)網(wǎng)頁只有在它的函數(shù)調(diào)用序列至少和一個(gè)已知的行為簽名匹配時(shí),才會(huì)被判定為惡意的。實(shí)驗(yàn)表明,該方法生成的行為簽名可以有效檢測出混淆的惡意JavaScript代碼,并且具有較低的誤報(bào)率。
AbdelKhlek等[9]提出了一個(gè)JavaScript代碼反混淆工具JSDES。JSDES利用自主構(gòu)建的Mozilla的SpiderMonkey JavaScript解釋器作為JavaScript執(zhí)行環(huán)境的仿真器。JSDES在仿真器中實(shí)現(xiàn)了JavaScript惡意代碼中常用的函數(shù),并根據(jù)代碼的運(yùn)行日志分析各類函數(shù)的執(zhí)行信息,對(duì)惡意代碼實(shí)現(xiàn)反混淆。
2.2.1 數(shù)據(jù)混淆(Data Obfuscation)
數(shù)據(jù)混淆通常在代碼中將字符串分割成多個(gè)變量或子串然后再拼接成原始字符串的策略來對(duì)原始字符串進(jìn)行偽裝。拼接可通過調(diào)用document.write, eval等函數(shù)實(shí)現(xiàn)。攻擊者還可能通過改變變量的順序來給代碼分析帶來更多困難。
2.2.2 編碼混淆(Encoding Obfuscation)
編碼混淆的方法大體上有兩種。第一種是將字符轉(zhuǎn)換成對(duì)應(yīng)的ASCII或Unicode編碼值,以便繞開靜態(tài)分析程序的檢測。第二種是利用自定義的加密函數(shù)來對(duì)原始代碼編碼。攻擊者編寫一對(duì)加密和解密的函數(shù),使用加密函數(shù)將原始代碼加密,并在代碼執(zhí)行時(shí)調(diào)用解密函數(shù)將代碼解密為原始代碼
2.2.3 標(biāo)識(shí)符重命名混淆(Variable and Function (Re-)Name Randomization Obfuscation)
標(biāo)識(shí)符重命名混淆指在不改變程序語義的條件下對(duì)標(biāo)識(shí)符做局部或全局的替換,替換后的標(biāo)識(shí)符通常為隨機(jī)生成的字符串,可讀性大大減弱。標(biāo)識(shí)符重命名混淆通常用于加大手工代碼分析的難度[9]。
2.2.4 邏輯結(jié)構(gòu)混淆(Logical Structure Obfuscation)
攻擊者可以通過改變代碼邏輯結(jié)構(gòu)的方式來改變程序的控制流。一個(gè)典型的例子是在運(yùn)行時(shí)插入一段永遠(yuǎn)不會(huì)被執(zhí)行的代碼。
2.2.5 動(dòng)態(tài)生成和運(yùn)行時(shí)計(jì)算混淆
動(dòng)態(tài)生成(D-Gen, Dynamic Generation)和運(yùn)行時(shí)計(jì)算(R-Eval, Runtime Evaluation)是惡意JavaScript代碼混淆的常用手段[5]。D-Gen可以在運(yùn)行時(shí)從文本中生成代碼,R-Eval可以將字符串表達(dá)式轉(zhuǎn)成代碼。而惡意代碼檢測工具通常會(huì)在檢測過程中忽略字符串常量,從而使得混惡意代碼繞過檢測。D-Gen和R-Eval這兩個(gè)JavaScript語言的特性提供了從字符串到代碼的轉(zhuǎn)換方法,因此常被用作惡意代碼的混淆的手段。
然而,D-Gen和R-Eval特性也常在正常代碼中使用,如條件加載,即只在相應(yīng)的條件滿足時(shí)加載對(duì)應(yīng)的組件。如JavaScript代碼包含只能在運(yùn)行時(shí)取得的信息時(shí)(如用戶輸入、客戶端與服務(wù)端的交互等),可以借助R-Eval實(shí)現(xiàn)條件加載。因此,正常代碼和惡意代碼因壓縮和混淆技術(shù)的廣泛使用而變得更加難以區(qū)分。
本文將函數(shù)調(diào)用信息形式化為函數(shù)調(diào)用關(guān)系圖和函數(shù)調(diào)用序列。
IBM Watson實(shí)驗(yàn)室在其開發(fā)的的WALA靜態(tài)開源分析框架中實(shí)現(xiàn)了調(diào)用圖的構(gòu)建,并針對(duì)JavaScript語言的特性,開發(fā)了將JavaScript代碼標(biāo)準(zhǔn)化的工具JS_WALA,在此基礎(chǔ)上實(shí)現(xiàn)了面向JavaScript語言的基于指針分析的調(diào)用圖構(gòu)造分析以及基于域的調(diào)用圖構(gòu)造分析[10]。
劉星[11]等人提出了一種基于函數(shù)調(diào)用圖的惡意代碼相似性分析方法,通過函數(shù)調(diào)用圖的相似性距離來度量兩個(gè)惡意代碼函數(shù)調(diào)用圖的相似性,進(jìn)而分析得到惡意代碼的相似性。
定義 1:函數(shù)調(diào)用關(guān)系圖G=(V,E)
函數(shù)調(diào)用關(guān)系圖G是一個(gè)二元組,其中V代表圖中的所有節(jié)點(diǎn),E代表圖中的所有邊。每個(gè)節(jié)點(diǎn)v代表一個(gè)函數(shù),每條邊e:v->w代表一個(gè)函數(shù)調(diào)用關(guān)系,令v,w為兩個(gè)函數(shù),若在v的定義中出現(xiàn)了對(duì)w的調(diào)用,則稱v調(diào)用了w,v與w具有調(diào)用關(guān)系。
函數(shù)調(diào)用關(guān)系圖反映了函數(shù)之間的調(diào)用關(guān)系,對(duì)于簡單的代碼混淆,函數(shù)名可能會(huì)被混淆器重構(gòu),但函數(shù)之間的調(diào)用關(guān)系保持具有某種不變性,因此可以利用函數(shù)調(diào)用關(guān)系圖檢測混淆前后的代碼。
以代碼1為例,其函數(shù)調(diào)用關(guān)系圖如圖1所示。
代碼1
function f0() {
f1();
}
function f1() {
f2();
f3();
}
f0();
f1();
圖1 函數(shù)調(diào)用關(guān)系圖示例
定義 2:函數(shù)調(diào)用序列 Seq
函數(shù)調(diào)用序列Seq是一個(gè)由函數(shù)組成的線性序列,其中相鄰的函數(shù)v, w在源代碼的語法樹中具有中序遍歷的順序關(guān)系。
張志華[12]等人提出的函數(shù)調(diào)用路徑用于解決回歸測試中的路徑爆炸問題,將函數(shù)的業(yè)務(wù)流程抽象為函數(shù)調(diào)用路徑,簡化了對(duì)函數(shù)執(zhí)行過程的描述。
函數(shù)調(diào)用序列表達(dá)了函數(shù)在統(tǒng)一代碼片段中的書寫順序,對(duì)于簡單的混淆的,函數(shù)調(diào)用序列具有不變性,因此可以用于匹配混淆前后的代碼。
代碼1的函數(shù)調(diào)用序列如下圖所示:
圖2 函數(shù)調(diào)用序列示例
Closure Compiler是Google開發(fā)的一個(gè)JavaScript代碼優(yōu)化和壓縮工具,經(jīng)優(yōu)化和壓縮后的JavaScript代碼可以被瀏覽器更快地加載和執(zhí)行。與一般的JavaScript代碼編譯器不同的是,Closure Compiler并不是將JavaScript編譯為機(jī)器碼,而是將它編譯為運(yùn)行更快的JavaScript代碼。Closure Compiler通過解析JavaScript代碼,移除無用代碼(dead code)然后重寫并壓縮有用代碼,并且檢查語法、變量引用以及類型,對(duì)JavaScript代碼中常見的陷阱(pitfalls)給出警告。
Closure Compiler提供了三個(gè)級(jí)別的編譯選項(xiàng)。分別是只移除空白符、簡單優(yōu)化和高級(jí)優(yōu)化。
1) 只移除空白符(Whitespace-only)的編譯等級(jí)會(huì)將代碼中的所有注釋和換行符、不必要的空白符和無關(guān)的標(biāo)點(diǎn)(如多余的括號(hào)或分號(hào))等字符移除。此等級(jí)輸出的JavaScript代碼在功能上和原始代碼等價(jià)。
2) 簡單優(yōu)化的編譯等級(jí)首先進(jìn)行和只移除空白符的編譯等級(jí)相同的處理,然后在表達(dá)式和函數(shù)層級(jí)進(jìn)行優(yōu)化,包括將局部變量和函數(shù)參數(shù)名重構(gòu)為更短的標(biāo)識(shí)符。這樣的重命名可以在一定程度上減小代碼的字節(jié)數(shù)。由于此等級(jí)只對(duì)函數(shù)內(nèi)部的局部變量和參數(shù)進(jìn)行了重命名,因此不會(huì)影響到此代碼和其他JavaScript代碼的交互。
3) 高級(jí)優(yōu)化的編譯等級(jí)首先進(jìn)行前兩個(gè)等級(jí)的處理,然后加入一些更復(fù)雜的全局優(yōu)化,使得輸出的代碼的體積進(jìn)一步壓縮。高級(jí)優(yōu)化會(huì)移除無用代碼(dead code),此功能在引入龐大的外部庫后打包代碼時(shí)非常有用,可以對(duì)沒有用到過的庫中的代碼進(jìn)行刪除以精簡代碼。高級(jí)優(yōu)化還會(huì)對(duì)一些函數(shù)調(diào)用進(jìn)行“內(nèi)聯(lián)”,也就是將函數(shù)體展開在函數(shù)調(diào)用的地方,用以替換函數(shù)調(diào)用語句。高級(jí)優(yōu)化也會(huì)對(duì)一些常量進(jìn)行內(nèi)聯(lián)。
通過觀察Google Closure Compiler的編譯方法,發(fā)現(xiàn)簡單優(yōu)化雖然改變了函數(shù)和變量的標(biāo)識(shí)符,但函數(shù)之間的嵌套調(diào)用關(guān)系以及順序執(zhí)行關(guān)系具有某種不變性,由此可以通過提取并比較兩份代碼的函數(shù)調(diào)用信息來為代碼行為的相似性提供依據(jù)。另外,對(duì)于一些內(nèi)置函數(shù)的調(diào)用,混淆并不會(huì)改變函數(shù)名,因此JavaScript語言或宿主內(nèi)置的函數(shù)名在混淆前后的不變形也為函數(shù)調(diào)用序列一致性的檢測提供了線索。
本文將函數(shù)調(diào)用信息形式化為函數(shù)調(diào)用關(guān)系圖和函數(shù)調(diào)用序列,將代碼相似性的檢測問題規(guī)約為圖相似度和序列相似度的計(jì)算問題。以函數(shù)調(diào)用關(guān)系圖和函數(shù)調(diào)用序列作為代碼結(jié)構(gòu)信息的載體。
本文利用Antlr4構(gòu)建JavaScript代碼解析器,首先進(jìn)行詞法分析,得到token序列,再進(jìn)行語法分析,得到抽象語法樹;然后遍歷抽象語法樹,并通過在遍歷器中設(shè)置提取函數(shù)調(diào)用信息的事件監(jiān)聽器,在遍歷的過程中收集函數(shù)調(diào)用關(guān)系圖和函數(shù)調(diào)用序列。最后采用基于圖和序列相似度的比較算法計(jì)算函數(shù)節(jié)點(diǎn)的相似度。函數(shù)調(diào)用信息的提取流程如圖3所示。
圖3 函數(shù)調(diào)用信息提取流程
函數(shù)調(diào)用關(guān)系圖的提取是在遍歷到函數(shù)調(diào)用節(jié)點(diǎn)時(shí)記錄當(dāng)前的被調(diào)函數(shù)和調(diào)用函數(shù),將相應(yīng)的節(jié)點(diǎn)和邊納入函數(shù)調(diào)用關(guān)系圖。
Algorithm Function Call Graph Extraction
Input:
file: JavaScript source file
Output:
graph: Function call graph
tokens=lexer.tokenize(file)
AST=parser.parse(tokens)
listener=FunctionCallGraphListener()
graph=walk(AST, listener)
return graph
FunctionCallGraphListener:
If enterMethodDefinition:
currentFunction=this.method
If enterMethodInvocation:
graph.addEdge(currentFunction, this.method)
Algorithm Function Call Graph Extraction
Input:
file: JavaScript source file
Output:
graph: Function call graph
tokens=lexer.tokenize(file)
AST=parser.parse(tokens)
listener=FunctionCallSequenceListener()
graph=walk(AST, listener)
return graph
FunctionCallSequenceListener:
If enterMethodInvocation:
sequence.add(this.method)
return sequence
本文對(duì)函數(shù)調(diào)用序列的相似度采用混合的正則化編輯距離計(jì)算。對(duì)函數(shù)名、函數(shù)內(nèi)部特征及函數(shù)參數(shù)信息分別計(jì)算編輯距離,然后取平均值。
本實(shí)驗(yàn)采用使用廣泛的開源JavaScript庫Underscore和jQuery,以及部分Alexa網(wǎng)站發(fā)布的網(wǎng)站的代碼作為良性的代碼數(shù)據(jù)集,并利用Google Closure Compiler對(duì)原始JavaScript代碼進(jìn)行混淆,得到混淆后的對(duì)比數(shù)據(jù)集。
實(shí)驗(yàn)原始數(shù)據(jù)集及靜態(tài)分析得到的信息如表1所示,原始代碼數(shù)據(jù)來自cdnjs.com。
表1 實(shí)驗(yàn)數(shù)據(jù)集統(tǒng)計(jì)信息
混淆前后的樣例代碼如下:
∥ Trim out all falsy values from an array.
_.compact=function(array) {
return _.filter(array, Boolean);
};
∥ Internal implementation of a recursive `flatten` function.
var flatten=function(input, shallow, strict, output) {
output=output || [];
var idx=output.length;
for (var i=0, length=getLength(input); i < length; i++) {
var value=input[i];
if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) {
∥ Flatten current level of array or arguments object.
if (shallow) {
var j=0, len=value.length;
while (j < len) output[idx++]=value[j++];
} else {
flatten(value, shallow, strict, output);
idx=output.length;
}
} else if (!strict) {
output[idx++]=value;
}
}
return output;
};
simple級(jí)別混淆后的樣例代碼如下:
_.compact=function(c){return _.filter(c,Boolean)};var flatten=function(c,f,g,a){a=a||[];for(var d=a.length,e=0,k=getLength(c);e advanced級(jí)別混淆后的樣例代碼如下: c.compact=function(a){return c.filter(a,Boolean)};c.flatten=function(a,b){return v(a,b,!1)}; 本文的方法首先分別對(duì)混淆前后的代碼進(jìn)行詞法和語法分析,并以函數(shù)定義為單位將語法樹切分為函數(shù)子樹。然后提取每棵函數(shù)子樹的調(diào)用信息,包括函數(shù)調(diào)用關(guān)系圖和函數(shù)調(diào)用序列。再對(duì)混淆前后的函數(shù)集合各自攜帶的函數(shù)調(diào)用信息進(jìn)行兩兩比較,取相似度高于一定閾值的函數(shù)對(duì),得到混淆前后函數(shù)的對(duì)應(yīng)關(guān)系列表。 函數(shù)調(diào)用信息的相似度根據(jù)函數(shù)調(diào)用序列的三組正則化編輯距離值確定。具體如表2和表3所示。 表2 函數(shù)的內(nèi)部的三組編輯距離 表3 函數(shù)內(nèi)部metric列表 函數(shù)內(nèi)部的metric向量對(duì)函數(shù)邏輯和結(jié)構(gòu)的反應(yīng)足夠充分,因此對(duì)metric向量設(shè)置了較高的閾值。而函數(shù)名會(huì)在混淆后發(fā)生改變,因此設(shè)置了較低的閾值。函數(shù)調(diào)用序列因函數(shù)名的改變而變得難以確定函數(shù)節(jié)點(diǎn)的對(duì)應(yīng)關(guān)系,因此也設(shè)置了較低的閾值。 實(shí)驗(yàn)環(huán)境為一臺(tái)具有2.3 GHz Intel Core i5處理器的PC機(jī),內(nèi)存為16G。實(shí)驗(yàn)程序采用Java語言實(shí)現(xiàn)。 對(duì)于得到的混淆前后函數(shù)的對(duì)應(yīng)關(guān)系,采用人工評(píng)判的方式確認(rèn)結(jié)果。結(jié)果統(tǒng)計(jì)如表4所示。 表4 實(shí)驗(yàn)結(jié)果 觀察實(shí)驗(yàn)結(jié)果,發(fā)現(xiàn)對(duì)于代碼規(guī)模較小的underscore數(shù)據(jù)集,找到的函數(shù)定義個(gè)數(shù)反而最多,究其原因,與函數(shù)調(diào)用信息提取所用的解析器的實(shí)現(xiàn)有關(guān)。本文在實(shí)現(xiàn)解析器時(shí),以u(píng)nderscore數(shù)據(jù)集作為樣例,因此對(duì)其中出現(xiàn)最多的函數(shù)表達(dá)式形式定義的函數(shù)支持較好,而忽略了其他兩個(gè)數(shù)據(jù)集中函數(shù)定義常用的形式。 三個(gè)數(shù)據(jù)集普遍準(zhǔn)確率大大高于召回率,這主要由于為函數(shù)內(nèi)部metric設(shè)置了較高的閾值。假陽性數(shù)據(jù)則是因?yàn)閮蓚€(gè)函數(shù)名相近(如later與b.after)。 JSNice是一款JavaScript語言的重構(gòu)與反混淆工具,可以根據(jù)代碼上下文推測出函數(shù)原本的具有語義的名字。本文將混淆后的實(shí)驗(yàn)數(shù)據(jù)用JSNice進(jìn)行反混淆,發(fā)現(xiàn)JSNice對(duì)部分混淆后的函數(shù)并不能準(zhǔn)確推測出原有的函數(shù)名,如underscore數(shù)據(jù)集中的_.where函數(shù),在混淆后被換名為c.Xa,而JSNice給出的反混淆結(jié)果中此函數(shù)名為_.Xa。 檢測用時(shí)與代碼規(guī)模成正比,與JSNice的反混淆過程用時(shí)基本相當(dāng)。 本文分析了常用的JavaScript代碼混淆器Google Closure Compiler的混淆手段,針對(duì)其中的換名策略,觀察到了函數(shù)調(diào)用關(guān)系圖和調(diào)用序列在結(jié)構(gòu)上保持不變的特點(diǎn),提出了基于函數(shù)調(diào)用信息的JavaScript混淆惡意代碼的自動(dòng)檢測方法。實(shí)驗(yàn)表明,此方法可檢測出混淆后的惡意代碼和混淆前代碼的對(duì)應(yīng)關(guān)系,并且在檢測效果上優(yōu)于一般的JavaScript反混淆工具。6.2 實(shí)驗(yàn)方法與環(huán)境
6.3 實(shí)驗(yàn)結(jié)果與分析
7 結(jié)論