• 
    

    
    

      99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看

      ?

      JavaScript混淆惡意代碼檢測方法

      2021-11-17 04:32:00牟永敏張志華崔展齊
      計算機仿真 2021年2期
      關鍵詞:函數(shù)調用調用代碼

      王 婷,牟永敏,張志華,崔展齊

      (北京信息科技大學網(wǎng)絡文化與數(shù)字傳播北京市重點實驗室,北京 100101)

      1 引言

      隨著互聯(lián)網(wǎng)規(guī)模的快速增長和用戶人數(shù)的迅速增加,互聯(lián)網(wǎng)公司在產(chǎn)品的用戶體驗上有著越來越高的追求。前端部分的重要性日益凸顯,導致大量的業(yè)務邏輯由服務端轉移到客戶端。Bichhawat等人[1]的研究結果表明超過95%的Web應用選用JavaScript語言進行前端開發(fā)。JavaScript語言所具有的跨平臺、可遠程嵌入、能動態(tài)執(zhí)行的特性在為用戶提供更好的交互體驗的同時,也給Web應用帶來了更多的安全上的風險和威脅[2]。大量的安全報告表明,惡意網(wǎng)頁已成為攻擊者針對 Web客戶端進行攻擊的主要途徑和平臺[3]。因此,惡意JavaScript代碼的檢測成為一項影響Web應用安全的重要研究課題。

      網(wǎng)頁中的攻擊代碼常常具有多樣化和隱蔽性的特點,其中17.1%的攻擊行為是通過混淆JavaScript代碼進行.代碼混淆是一種為了避免安全系統(tǒng)檢測而改變數(shù)據(jù)形態(tài)的技術[4]。另外,Web前端應用為減少代碼體積,加快網(wǎng)頁加載速度,通常會對代碼進行優(yōu)化與壓縮。壓縮后的代碼常常與混淆后的代碼一樣失去可讀性,同時也為惡意代碼的隱藏提供了便利。隨著JavaScript代碼壓縮與混淆技術的成熟,惡意代碼的檢測也變得越來越困難。

      研究表明,惡意代碼的行為常常具有某種規(guī)律[5]。如惡意代碼通常會更多地調用某幾種JavaScript語言的內(nèi)置函數(shù)以實現(xiàn)代碼惡意代碼的偽裝和隱藏,且為完成某種惡意功能,函數(shù)的調用順序以及函數(shù)之間的調用圖會具有某種一致性。而常用的代碼自動壓縮與混淆工具為保證代碼在混淆前后語義上的等價,通常會保持原有的函數(shù)調用信息不變[5]。因此,利用已知的惡意代碼中各函數(shù)的調用信息可以為新的惡意代碼檢測的提供參考。

      針對以上問題,本文提出了基于函數(shù)調用信息的JavaScript混淆惡意代碼檢測方法。通過提取JavaScript代碼中的函數(shù)調用序列和函數(shù)調用關系圖,比較混淆前后函數(shù)調用關系的序列相似度和圖相似度,得到混淆前后代碼中函數(shù)的對應關系,為JavaScript混淆代碼中惡意函數(shù)的檢測提供參考。

      2 國內(nèi)外研究現(xiàn)狀

      2.1 惡意代碼檢測技術

      網(wǎng)頁中惡意代碼檢測的研究已經(jīng)歷了十余年的發(fā)展。自2004年開始,基于瀏覽器的客戶端蜜罐(honeypot)系統(tǒng)已成為一類檢測客戶端惡意代碼攻擊的有力工具。這些工具通常采用將可以網(wǎng)頁加載到易受攻擊的瀏覽器中并觀察系統(tǒng)總文件、注冊表和進程的變化來檢測網(wǎng)頁中的惡意代碼[6]。

      2.1.1 靜態(tài)分析的方法

      Canali等[7]提出的Prophiler是一個利用靜態(tài)分析進行惡意代碼和良性代碼分類的系統(tǒng)。Prophiler利用HTML及其關聯(lián)的JavaScript代碼以及URL信息構建有監(jiān)督學習的監(jiān)測模型,對代碼進行初步分類。再對被判定為惡意的代碼利用更精細的工具進行分析。Prophiler的不足是無法應對混淆后的惡意代碼。

      Curtsinger等[8]提出的ZOZZLE是一個靜態(tài)的JavaScript惡意代碼檢測工具,其原理基于這樣的假設:惡意的JavaScript代碼一定會在最終執(zhí)行前被反混淆。ZOZZLE利用JavaScript語言或宿主環(huán)境提供的可實現(xiàn)從字符串到代碼的轉換的函數(shù)(如document.write, eval)對代碼進行反混淆,并將反混淆后的代碼轉換為抽象語法樹、然后將從抽象語法樹中提取的特征輸入到樸素貝葉斯分類器中。

      2.1.2 動態(tài)分析的方法

      Xu等[5]提出的JStill通過分析器方法調用信息捕捉混淆惡意代碼中的特征,結合靜態(tài)分析和輕量級的運行時檢查,檢測混淆后的代碼中的惡意代碼。JStill的設計思想基于如下假設:混淆后的惡意代碼在被執(zhí)行前需要進行一定程度的反混淆以完全實現(xiàn)其惡意功能,而反混淆的過程必然會調用特定的一組函數(shù),因此這組特定函數(shù)的調用情況可以作為判斷惡意代碼的一個依據(jù)。JStill將函數(shù)調用分為了原生函數(shù)(native function)、內(nèi)置函數(shù)(built-in function)、DOM方法以及用戶定義函數(shù)四類。JStill總結了惡意代碼在函數(shù)調用上與良性代碼的差別,包括:惡意代碼會從靜態(tài)的角度隱藏一些在反混淆中常用的函數(shù)的參數(shù),使得這些參數(shù)不會被靜態(tài)分析工具獲取或分析,因為參數(shù)通常會暴露代碼的惡意行為;惡意代碼會隱藏函數(shù)定義,使得從靜態(tài)分析的角度解析不到函數(shù)的定義等。JStill主要關注基于編碼/加密的混淆惡意代碼的檢測。

      Gorji等[6]提出了一個基于內(nèi)部函數(shù)調用序列檢測混淆惡意代碼的方法。該方法的檢測分為兩個階段。首先是行為收集階段,通過在瀏覽器中加載真實的惡意的網(wǎng)頁,利用瀏覽器的調試工具收集函數(shù)調用信息。然后基于正則化的編輯距離將具有相似函數(shù)調用序列的網(wǎng)頁聚集為等價類,并且為每個等價類生成相應的行為簽名(behavior signature)。完成行為收集后,進入檢測階段。一個網(wǎng)頁只有在它的函數(shù)調用序列至少和一個已知的行為簽名匹配時,才會被判定為惡意的。實驗表明,該方法生成的行為簽名可以有效檢測出混淆的惡意JavaScript代碼,并且具有較低的誤報率。

      AbdelKhlek等[9]提出了一個JavaScript代碼反混淆工具JSDES。JSDES利用自主構建的Mozilla的SpiderMonkey JavaScript解釋器作為JavaScript執(zhí)行環(huán)境的仿真器。JSDES在仿真器中實現(xiàn)了JavaScript惡意代碼中常用的函數(shù),并根據(jù)代碼的運行日志分析各類函數(shù)的執(zhí)行信息,對惡意代碼實現(xiàn)反混淆。

      2.2 代碼混淆技術

      2.2.1 數(shù)據(jù)混淆(Data Obfuscation)

      數(shù)據(jù)混淆通常在代碼中將字符串分割成多個變量或子串然后再拼接成原始字符串的策略來對原始字符串進行偽裝。拼接可通過調用document.write, eval等函數(shù)實現(xiàn)。攻擊者還可能通過改變變量的順序來給代碼分析帶來更多困難。

      2.2.2 編碼混淆(Encoding Obfuscation)

      編碼混淆的方法大體上有兩種。第一種是將字符轉換成對應的ASCII或Unicode編碼值,以便繞開靜態(tài)分析程序的檢測。第二種是利用自定義的加密函數(shù)來對原始代碼編碼。攻擊者編寫一對加密和解密的函數(shù),使用加密函數(shù)將原始代碼加密,并在代碼執(zhí)行時調用解密函數(shù)將代碼解密為原始代碼

      2.2.3 標識符重命名混淆(Variable and Function (Re-)Name Randomization Obfuscation)

      標識符重命名混淆指在不改變程序語義的條件下對標識符做局部或全局的替換,替換后的標識符通常為隨機生成的字符串,可讀性大大減弱。標識符重命名混淆通常用于加大手工代碼分析的難度[9]。

      2.2.4 邏輯結構混淆(Logical Structure Obfuscation)

      攻擊者可以通過改變代碼邏輯結構的方式來改變程序的控制流。一個典型的例子是在運行時插入一段永遠不會被執(zhí)行的代碼。

      2.2.5 動態(tài)生成和運行時計算混淆

      動態(tài)生成(D-Gen, Dynamic Generation)和運行時計算(R-Eval, Runtime Evaluation)是惡意JavaScript代碼混淆的常用手段[5]。D-Gen可以在運行時從文本中生成代碼,R-Eval可以將字符串表達式轉成代碼。而惡意代碼檢測工具通常會在檢測過程中忽略字符串常量,從而使得混惡意代碼繞過檢測。D-Gen和R-Eval這兩個JavaScript語言的特性提供了從字符串到代碼的轉換方法,因此常被用作惡意代碼的混淆的手段。

      然而,D-Gen和R-Eval特性也常在正常代碼中使用,如條件加載,即只在相應的條件滿足時加載對應的組件。如JavaScript代碼包含只能在運行時取得的信息時(如用戶輸入、客戶端與服務端的交互等),可以借助R-Eval實現(xiàn)條件加載。因此,正常代碼和惡意代碼因壓縮和混淆技術的廣泛使用而變得更加難以區(qū)分。

      3 相關定義

      本文將函數(shù)調用信息形式化為函數(shù)調用關系圖和函數(shù)調用序列。

      IBM Watson實驗室在其開發(fā)的的WALA靜態(tài)開源分析框架中實現(xiàn)了調用圖的構建,并針對JavaScript語言的特性,開發(fā)了將JavaScript代碼標準化的工具JS_WALA,在此基礎上實現(xiàn)了面向JavaScript語言的基于指針分析的調用圖構造分析以及基于域的調用圖構造分析[10]。

      劉星[11]等人提出了一種基于函數(shù)調用圖的惡意代碼相似性分析方法,通過函數(shù)調用圖的相似性距離來度量兩個惡意代碼函數(shù)調用圖的相似性,進而分析得到惡意代碼的相似性。

      定義 1:函數(shù)調用關系圖G=(V,E)

      函數(shù)調用關系圖G是一個二元組,其中V代表圖中的所有節(jié)點,E代表圖中的所有邊。每個節(jié)點v代表一個函數(shù),每條邊e:v->w代表一個函數(shù)調用關系,令v,w為兩個函數(shù),若在v的定義中出現(xiàn)了對w的調用,則稱v調用了w,v與w具有調用關系。

      函數(shù)調用關系圖反映了函數(shù)之間的調用關系,對于簡單的代碼混淆,函數(shù)名可能會被混淆器重構,但函數(shù)之間的調用關系保持具有某種不變性,因此可以利用函數(shù)調用關系圖檢測混淆前后的代碼。

      以代碼1為例,其函數(shù)調用關系圖如圖1所示。

      代碼1

      function f0() {

      f1();

      }

      function f1() {

      f2();

      f3();

      }

      f0();

      f1();

      圖1 函數(shù)調用關系圖示例

      定義 2:函數(shù)調用序列 Seq

      函數(shù)調用序列Seq是一個由函數(shù)組成的線性序列,其中相鄰的函數(shù)v, w在源代碼的語法樹中具有中序遍歷的順序關系。

      張志華[12]等人提出的函數(shù)調用路徑用于解決回歸測試中的路徑爆炸問題,將函數(shù)的業(yè)務流程抽象為函數(shù)調用路徑,簡化了對函數(shù)執(zhí)行過程的描述。

      函數(shù)調用序列表達了函數(shù)在統(tǒng)一代碼片段中的書寫順序,對于簡單的混淆的,函數(shù)調用序列具有不變性,因此可以用于匹配混淆前后的代碼。

      代碼1的函數(shù)調用序列如下圖所示:

      圖2 函數(shù)調用序列示例

      4 基于Closure Compiler的代碼混淆

      4.1 Closure Compiler的混淆方法

      Closure Compiler是Google開發(fā)的一個JavaScript代碼優(yōu)化和壓縮工具,經(jīng)優(yōu)化和壓縮后的JavaScript代碼可以被瀏覽器更快地加載和執(zhí)行。與一般的JavaScript代碼編譯器不同的是,Closure Compiler并不是將JavaScript編譯為機器碼,而是將它編譯為運行更快的JavaScript代碼。Closure Compiler通過解析JavaScript代碼,移除無用代碼(dead code)然后重寫并壓縮有用代碼,并且檢查語法、變量引用以及類型,對JavaScript代碼中常見的陷阱(pitfalls)給出警告。

      Closure Compiler提供了三個級別的編譯選項。分別是只移除空白符、簡單優(yōu)化和高級優(yōu)化。

      1) 只移除空白符(Whitespace-only)的編譯等級會將代碼中的所有注釋和換行符、不必要的空白符和無關的標點(如多余的括號或分號)等字符移除。此等級輸出的JavaScript代碼在功能上和原始代碼等價。

      2) 簡單優(yōu)化的編譯等級首先進行和只移除空白符的編譯等級相同的處理,然后在表達式和函數(shù)層級進行優(yōu)化,包括將局部變量和函數(shù)參數(shù)名重構為更短的標識符。這樣的重命名可以在一定程度上減小代碼的字節(jié)數(shù)。由于此等級只對函數(shù)內(nèi)部的局部變量和參數(shù)進行了重命名,因此不會影響到此代碼和其他JavaScript代碼的交互。

      3) 高級優(yōu)化的編譯等級首先進行前兩個等級的處理,然后加入一些更復雜的全局優(yōu)化,使得輸出的代碼的體積進一步壓縮。高級優(yōu)化會移除無用代碼(dead code),此功能在引入龐大的外部庫后打包代碼時非常有用,可以對沒有用到過的庫中的代碼進行刪除以精簡代碼。高級優(yōu)化還會對一些函數(shù)調用進行“內(nèi)聯(lián)”,也就是將函數(shù)體展開在函數(shù)調用的地方,用以替換函數(shù)調用語句。高級優(yōu)化也會對一些常量進行內(nèi)聯(lián)。

      4.2 函數(shù)調用信息的不變性

      通過觀察Google Closure Compiler的編譯方法,發(fā)現(xiàn)簡單優(yōu)化雖然改變了函數(shù)和變量的標識符,但函數(shù)之間的嵌套調用關系以及順序執(zhí)行關系具有某種不變性,由此可以通過提取并比較兩份代碼的函數(shù)調用信息來為代碼行為的相似性提供依據(jù)。另外,對于一些內(nèi)置函數(shù)的調用,混淆并不會改變函數(shù)名,因此JavaScript語言或宿主內(nèi)置的函數(shù)名在混淆前后的不變形也為函數(shù)調用序列一致性的檢測提供了線索。

      本文將函數(shù)調用信息形式化為函數(shù)調用關系圖和函數(shù)調用序列,將代碼相似性的檢測問題規(guī)約為圖相似度和序列相似度的計算問題。以函數(shù)調用關系圖和函數(shù)調用序列作為代碼結構信息的載體。

      5 基于函數(shù)調用信息的JavaScript代碼混淆惡意代碼檢測方法

      本文利用Antlr4構建JavaScript代碼解析器,首先進行詞法分析,得到token序列,再進行語法分析,得到抽象語法樹;然后遍歷抽象語法樹,并通過在遍歷器中設置提取函數(shù)調用信息的事件監(jiān)聽器,在遍歷的過程中收集函數(shù)調用關系圖和函數(shù)調用序列。最后采用基于圖和序列相似度的比較算法計算函數(shù)節(jié)點的相似度。函數(shù)調用信息的提取流程如圖3所示。

      圖3 函數(shù)調用信息提取流程

      5.1 函數(shù)調用關系圖的提取

      函數(shù)調用關系圖的提取是在遍歷到函數(shù)調用節(jié)點時記錄當前的被調函數(shù)和調用函數(shù),將相應的節(jié)點和邊納入函數(shù)調用關系圖。

      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)

      5.2 函數(shù)調用序列的提取

      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

      5.3 函數(shù)調用信息相似度的比較

      本文對函數(shù)調用序列的相似度采用混合的正則化編輯距離計算。對函數(shù)名、函數(shù)內(nèi)部特征及函數(shù)參數(shù)信息分別計算編輯距離,然后取平均值。

      6 實驗

      6.1 實驗數(shù)據(jù)集

      本實驗采用使用廣泛的開源JavaScript庫Underscore和jQuery,以及部分Alexa網(wǎng)站發(fā)布的網(wǎng)站的代碼作為良性的代碼數(shù)據(jù)集,并利用Google Closure Compiler對原始JavaScript代碼進行混淆,得到混淆后的對比數(shù)據(jù)集。

      實驗原始數(shù)據(jù)集及靜態(tài)分析得到的信息如表1所示,原始代碼數(shù)據(jù)來自cdnjs.com。

      表1 實驗數(shù)據(jù)集統(tǒng)計信息

      混淆前后的樣例代碼如下:

      ∥ 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級別混淆后的樣例代碼如下:

      _.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級別混淆后的樣例代碼如下:

      c.compact=function(a){return c.filter(a,Boolean)};c.flatten=function(a,b){return v(a,b,!1)};

      6.2 實驗方法與環(huán)境

      本文的方法首先分別對混淆前后的代碼進行詞法和語法分析,并以函數(shù)定義為單位將語法樹切分為函數(shù)子樹。然后提取每棵函數(shù)子樹的調用信息,包括函數(shù)調用關系圖和函數(shù)調用序列。再對混淆前后的函數(shù)集合各自攜帶的函數(shù)調用信息進行兩兩比較,取相似度高于一定閾值的函數(shù)對,得到混淆前后函數(shù)的對應關系列表。

      函數(shù)調用信息的相似度根據(jù)函數(shù)調用序列的三組正則化編輯距離值確定。具體如表2和表3所示。

      表2 函數(shù)的內(nèi)部的三組編輯距離

      表3 函數(shù)內(nèi)部metric列表

      函數(shù)內(nèi)部的metric向量對函數(shù)邏輯和結構的反應足夠充分,因此對metric向量設置了較高的閾值。而函數(shù)名會在混淆后發(fā)生改變,因此設置了較低的閾值。函數(shù)調用序列因函數(shù)名的改變而變得難以確定函數(shù)節(jié)點的對應關系,因此也設置了較低的閾值。

      實驗環(huán)境為一臺具有2.3 GHz Intel Core i5處理器的PC機,內(nèi)存為16G。實驗程序采用Java語言實現(xiàn)。

      6.3 實驗結果與分析

      對于得到的混淆前后函數(shù)的對應關系,采用人工評判的方式確認結果。結果統(tǒng)計如表4所示。

      表4 實驗結果

      觀察實驗結果,發(fā)現(xiàn)對于代碼規(guī)模較小的underscore數(shù)據(jù)集,找到的函數(shù)定義個數(shù)反而最多,究其原因,與函數(shù)調用信息提取所用的解析器的實現(xiàn)有關。本文在實現(xiàn)解析器時,以underscore數(shù)據(jù)集作為樣例,因此對其中出現(xiàn)最多的函數(shù)表達式形式定義的函數(shù)支持較好,而忽略了其他兩個數(shù)據(jù)集中函數(shù)定義常用的形式。

      三個數(shù)據(jù)集普遍準確率大大高于召回率,這主要由于為函數(shù)內(nèi)部metric設置了較高的閾值。假陽性數(shù)據(jù)則是因為兩個函數(shù)名相近(如later與b.after)。

      JSNice是一款JavaScript語言的重構與反混淆工具,可以根據(jù)代碼上下文推測出函數(shù)原本的具有語義的名字。本文將混淆后的實驗數(shù)據(jù)用JSNice進行反混淆,發(fā)現(xiàn)JSNice對部分混淆后的函數(shù)并不能準確推測出原有的函數(shù)名,如underscore數(shù)據(jù)集中的_.where函數(shù),在混淆后被換名為c.Xa,而JSNice給出的反混淆結果中此函數(shù)名為_.Xa。

      檢測用時與代碼規(guī)模成正比,與JSNice的反混淆過程用時基本相當。

      7 結論

      本文分析了常用的JavaScript代碼混淆器Google Closure Compiler的混淆手段,針對其中的換名策略,觀察到了函數(shù)調用關系圖和調用序列在結構上保持不變的特點,提出了基于函數(shù)調用信息的JavaScript混淆惡意代碼的自動檢測方法。實驗表明,此方法可檢測出混淆后的惡意代碼和混淆前代碼的對應關系,并且在檢測效果上優(yōu)于一般的JavaScript反混淆工具。

      猜你喜歡
      函數(shù)調用調用代碼
      核電項目物項調用管理的應用研究
      LabWindows/CVI下基于ActiveX技術的Excel調用
      測控技術(2018年5期)2018-12-09 09:04:46
      創(chuàng)世代碼
      動漫星空(2018年11期)2018-10-26 02:24:02
      創(chuàng)世代碼
      動漫星空(2018年2期)2018-10-26 02:11:00
      創(chuàng)世代碼
      動漫星空(2018年9期)2018-10-26 01:16:48
      創(chuàng)世代碼
      動漫星空(2018年5期)2018-10-26 01:15:02
      基于函數(shù)調用序列模式和函數(shù)調用圖的程序缺陷檢測方法*
      探討C++編程中避免代碼冗余的技巧
      Unity3D項目腳本優(yōu)化分析與研究
      中國新通信(2017年1期)2017-03-08 03:12:21
      基于系統(tǒng)調用的惡意軟件檢測技術研究
      铜陵市| 遂平县| 桦南县| 台江县| 苏尼特右旗| 兴国县| 黑水县| 阿坝县| 太白县| 宝山区| 凤山县| 化隆| 崇阳县| 新营市| 鄄城县| 望都县| 潞城市| 额尔古纳市| 金秀| 屯留县| 陵水| 淅川县| 菏泽市| 汉川市| 太仓市| 浠水县| 北碚区| 玉田县| 黄骅市| 延长县| 巴林左旗| 华池县| 和田市| 佳木斯市| 紫阳县| 息烽县| 松阳县| 东乡族自治县| 宁津县| 吕梁市| 大同县|