崔艷鵬 顏 波 胡建偉
(西安電子科技大學網絡與信息安全學院 陜西 西安 710071)
Android平臺是目前世界上使用最多的智能平臺,占據了全球85%的市場份額。迄今為止,Google市場有超過650億次的下載量,比App Store高出2倍[1]。同時,Android平臺的流行也吸引了許多惡意攻擊者們的興趣,他們開發的惡意軟件可以進行各種惡意甚至非法操作,比如:竊取用戶隱私及敏感數據、遠程執行代碼、消耗用戶資費等行為。這些惡意軟件不僅危及用戶數據安全,也威脅到Android系統安全。
根據獨立安全機構AV-Test在2018年1月發表的報告[2],使用AhnLab、Alibaba、McAfee、Tencent、Kaspersky Lab等19個手機殺毒軟件對2 766個己知Android惡意應用進行檢測發現各大手機殺毒軟件對于已知的惡意應用檢測效果并不理想。
同時,由于當前主流的Android惡意軟件檢測方法都嚴重依賴API版本和惡意家族樣例,隨著時間推移,Android API版本的不斷變化和軟件保護措施的不斷加強,這些檢測方法變得越來越低效。
針對上述技術存在的問題,本文提出了一種基于抽象API調用序列的Android惡意軟件檢測方法。該方法采用靜態行為特征提取方法,提取Android應用軟件的API調用序列。然后,通過基于API包名、混淆名和自定義名的方法來抽象API調用序列。該方法能有效地識別Android系統原生API、Google API、混淆后的API以及開發者自定義的API,且不會對API版本產生依賴。最后,將抽象后的API調用序列作為分類特征來訓練RandomForest分類器。實驗結果表明,與一般使用API調用序列作為特征的判別方法相比,本文方法能更有效地檢測未知應用軟件的惡意性,且能適應API版本的變化,具有更好的容錯性。
目前,關于Android惡意軟件檢測的方法比較多,主要有基于動態檢測和靜態檢測方法。但基于動態檢測的方法在實驗資源成本上會耗費過大,且代碼覆蓋率不全,導致相應特征提取不全,檢測有效性降低,所以國內外學者們主要是研究靜態檢測方法。當前,基于靜態檢測的方法主要是從簽名、權限和API這三大方面進行展開的。
基于簽名的靜態檢測方法[3]是采用了模式匹配的思想。該方法極度依賴已知的惡意軟件簽名庫,無法對未知的惡意軟件進行檢測。
基于權限的靜態檢測方法[4-5]主要是從Android系統的權限安全機制著手,因為Android系統中組件間重要敏感的行為受權限限制。該方法通過從應用程序的Android Manifest文件中提取權限字段,建立了正常數據和惡意軟件數據的所有權限數據庫,最后利用機器學習算法對Android應用中的惡意軟件進行分類和識別。該方法優點是簡單并且很容易實現,缺點是容易出現誤差,比如由于缺乏經驗的開發者可能事先申請了某些權限,但其在編程中卻沒有用到被該權限作用的函數,因此準確率較低,且遺漏問題嚴重。
基于API調用的靜態檢測方法[6-7]主要是將Android應用程序的信息接口(API)作為突破口。Android應用軟件中API的調用序列存在著大量的行為信息,通過分析API調用特征所得到的特征向量,再結合多種分類算法,可以對Android惡意軟件進行檢測。文獻[8]提出了一種DroidAPIMiner分類器,該分類器從應用軟件的字節碼中提取API和其他參數,并且對API的使用頻率進行統計,最后使用了不同的機器學習的方法處理了這些特征。文獻[9]提出了權限和API特征結合的檢測方法,主要通過將權限和高危的20種API結合起來作為一個特征集合。實驗驗證了該方法的準確率比將單一的權限或者API作為特征的準確率要高。但是文獻中指出的20種高危API可能會被混淆后的名字代替,從而該方法會漏掉這一關鍵特征,檢測效率也將有偏差。文獻[10]提出了一種改進的多級簽名檢測方法,將簽名和API結合起來,對方法和類的簽名進行多級匹配。但是該方法依賴已知惡意軟件家族,實驗訓練樣本是已知的惡意軟件,測試樣本則是訓練樣本進行變種后,按照比例挑選出來的。同時,該方法檢測精度也只有88%。文獻[11]提取了多項特征數據,包括通過靜態檢測方法獲取的權限、API調用信息和通過動態檢測方法獲取的日志文件作為總體特征。雖然他們的實驗檢測效率達到94%,且在準確性方面優于其他反病毒系統,但是檢測模型的質量取決于良性樣本集合和惡意樣本集合。文獻[12]提出了一種基于上下文信息的檢測方法,該方法提取敏感API編程接口,并分析其行為的激活事件和條件因子,生成語境特征,該方法精確度達92.86%,但是文獻中實驗數據集太少,只有266個,實驗數據具有特殊性。
基于靜態檢測的方法方便、快速、代碼覆蓋率高,但是必須考慮到兩個問題:一方面,隨著Android安全技術的不斷提高,很多應用軟件均被使用了混淆等保護技術,獲取混淆后APK所包含的相關特征信息變得困難;另一方面,目前現有的Android惡意軟件靜態檢測方法都無法適應API版本的更替,隨著API版本的更改,檢測效率會降低。因此,本文提出的檢測方法是采用API包名、混淆名和自定義名來抽象API調用序列,使得抽象出來的序列不依賴API版本,同時又包含了混淆代碼特征,具有更好的容錯性。
基于抽象的API調用序列的Android惡意軟件檢測方法通過對提取出的API調用序列進行多層次的抽象描述,然后計算抽象API調用序列之間的轉移概率作為分類特征,最后通過RandomForest算法來達到區分惡意軟件的效果。實驗的整體設計框架如圖1所示。

圖1 實驗設計框架圖
為了使實驗樣本包含不同API版本,本文從各大應用市場下載各類別的不同版本的熱門軟件,良性應用軟件集總共3 000個。其中:前1 500個API版本均在24~27之間,這些版本是目前市場上多數使用的API版本;后1 500個API版本均在16~23之間,這些版本是比較老的API版本,但依舊占據小部分市場。同時,上述良性應用軟件集都是通過殺毒軟件的過濾篩除后得到的。實驗中的惡意應用軟件集來自于VirusShare.com[13]中提供的2 000個惡意軟件。
為了更好地訓練分類器和獲取更好的分類結果,本實驗中訓練樣本集合與測試樣本集合的比例為8∶2。表1給出了本實驗數據的具體劃分情況。

表1 實驗訓練集與測試集劃分
Android 系統中的API是可以提供給Android應用軟件開發者調用的系統接口。隨著Android版本的不斷更新,Android應用軟件開發者不僅使用Android系統原生API,還包括Google API。這些API包含豐富的功能函數,其為上層應用軟件提供框架支撐和行為實現。獲取API調用序列的一種方法就是獲取Android應用程序的函數調用關系圖,通過對函數關系圖的分析,獲取API 調用序列。
圖2為原始API的表達形式,其中包含的信息有:API所屬的包名(java.lang.String)、函數名(getBytes)、函數返回值類型(bytes)。

圖2 API示意圖
2.2.1函數調用關系圖的提取
對于Android應用軟件的函數調用關系圖的提取,本文使用了AndroidGuard工具。AndroidGuard可以進行程序流程圖的生成,還能通過圖形化的方式輸出,讓用戶對程序有直觀的了解。
為了更好地說明本文方法的不同之處,以一個真實的惡意軟件樣本作為運行實例。圖3列出惡意樣本malicious1.apk反編譯后提取出來的類。圖3中的代碼片段表示本地保存的短信內容、電話等信息會上傳到服務器。

圖3 Malicious1.apk中zjSevice類的代碼片段
這個惡意軟件偽裝成一個圖片查看器的應用軟件,但其中包含惡意行為:惡意記錄短信內容、電話號碼等敏感信息到本地并上傳到某服務器上,導致隱私數據泄露。為了清晰地描述API的調用關系,本文只分析圖3 uploadAllfiles函數,且忽略了對象初始化、返回類型和參數以及方法中隱式調用的調用關系。該函數的API調用關系如圖4所示。

圖4 uploadAllfiles函數的調用關系圖
2.2.2API調用序列的提取
本文從獲取到應用軟件的函數調用關系中提取API調用的序列。該階段的操作步驟為:標識函數調用關系圖中的入口節點(即沒有傳入邊的節點);枚舉出每個入口節點可到達的路徑。在此階段確定的所有路徑的集合L就是該函數的API調用序列。以圖3中的uploadAllfiles函數的調用關系圖為例,函數調用序列對如圖5所示。

圖5 uploadAllfiles函數的API調用序列對
2.2.3抽象API調用序列
不同的Android版本對應著不同的API版本,不同版本的Android API也存在不同,會根據新增的功能去增加或刪改一些應用程序接口。因此,如何讓提取API特征不依賴API版本成為一個亟待解決的問題。
本文方法通過抽象API的包名避免了檢測的特征對于API版本的依賴。具體包括:對API官方網站給出的API進行包名抽象、對應用程序自定義的包名統一抽象為insensitive-defined、對被混淆后的包名統一抽象為obfuscated。根據Android API和Google API官方統計,API以包名進行分類共有9個,分別包括android、com.google、java、javax、org.xml、org.apache、junit、org.json和org.w3c.dom。由于org.w3c.dom家族下的API都為文檔對象模型 (DOM)提供接口,junit類適用于開發者做單元測試的類,并且org.w3c.dom和junit都幾乎不曾在實驗樣本集中出現過,所以剔除這兩類。表2中給出了所有API抽象描述后的種類集合,總共8種。

表2 抽象API的集合
在Android軟件開發中,自定義包名的命名規則采用反域名命名規則,全部使用小寫字母。一級包名為com;二級包名為個人或公司名稱,可以簡寫,三級包名根據應用進行命名;四級包名為模塊名或層級名;根據實際情況也是可以用五級包名、六級包名。而在Android應用程序層中,混淆技術主要采用標識符混淆,它是對源程序中的包名、類名、方法名和變量名進行重命名,用無意義的標識符來替換,使得破解和分析更困難。通過標識符混淆后的包名多數以單一字符或定制的混淆字典中的字符串替換每級包名,這些單一字符和定制的混淆字典中的字符串的命名方式不會遵守反域名命名規則。因此根據上述特性,本文對應用程序自定義的包名和混淆后的包名識別算法步驟如下:
輸入:API調用信息Sorigin,API官網抽象出的集合[APIabstract]=[android, com.google, java, javax, org.xml, org.apache]。
輸出:抽象的API。
步驟一:以“.”切分Sorigin,得到一個包名組L。
步驟二:將包名組L中的元素與[APIabstract]逐個匹配,匹配成功,則輸出匹配的元素,即為抽象API。
步驟三:如果步驟二匹配不成功,計算L中每個元素的長度,統計元素長度不超過3的元素數量count。
步驟四:判斷count是否大于等于len(L)/2,是則輸出匹配元素obfuscated,表示為混淆的包名;否則輸出匹配元素insensitive-defined,表示為自定義包名。
繼續以圖5的API調用圖為例,API抽象后結果如圖6所示。

圖6 抽象后的API調用序列
為了更好體現API調用序列之間的關系,本文方法通過計算API兩兩之間的轉移概率,獲取轉移矩陣作為分類特征。
API兩兩之間的轉移概率P的計算公式如下:
(1)

接著,根據上述2.2節分析可知,抽象API集合LAPI_abstract=[android, com.google, java, javax, org.xml, org.apache, obfuscated, insensitive-defined],則LAPI_abstract中API兩兩之間轉換的狀態有64(8×8)種,設一個64列的特征向量Vtranslate_count=[API]1×64來代表64種轉化狀態。其中Vtranslate_count分別代表的是LAPI_abstract集合中抽象API兩兩之間的轉換概率矩陣。一個應用軟件中所有函數的抽象API調用序列中的API之間轉移概率的集合就組成了轉移概率矩陣。具體算法流程如下:
輸入:一個應用軟件中n個函數的抽象API調用序列集;特征維度t=64。
輸出:轉移概率矩陣Tn×t。
步驟一:創建轉移概率矩陣Tn×t,并將其元素都初始化為0。
步驟二:計算Ti×j的值。其中Ti×t(第i行向量)表示第i個函數的抽象API調用序列中API之間的轉移概率向量,因此Ti×j表示第i個函數在Vtranslate_count的第j個指定的兩個API之間轉換概率。該概率通過式(1)計算可得。
步驟三:輸出矩陣Tn×t。
本文采用的分類算法為隨機森林算法,主要是為了區分惡意軟件和良性軟件。
隨機森林[14]是建立在決策樹算法基礎上的改進算法,用于分類與回歸。該算法通過重復多次的有放回的方式從原始樣本中隨機抽取部分樣本產生新的樣本集合,每個樣本集合后續都可以構建成一棵決策樹,多棵決策樹組建成隨機森林。最終分類結果根據每棵分類子樹投票統計結果而定。該算法的執行步驟[13]如下:
輸入:n個訓練樣本集T[n],測試樣本x,樣本特征維度M。
輸出:x所屬的類別。
步驟一:對于原始訓練樣本集T[n],有放回的隨機抽取N個訓練樣本。
步驟二:隨機地從M個特征中選取m個特征子集(m< 步驟三:將經過步驟二生長后的多棵樹進行組建,構建成一個隨機森林分類器。 步驟四:將測試樣本x放入隨機森林分類器中進行分類判別。 分類結果的好壞需要通過不同的指標來表現。本文主要以TPR、FPR、Accuracy、Precision、Recall和F-measure作為分類方法的評價標準。具體說明如下: TPR:表示非惡意樣例被正確分類的比率。其公式如下: (2) 式中:TP表示非惡意樣例被正確分類的個數;P表示非惡意樣例的總個數。 FPR:表示惡意樣例被錯誤分類的比率。其公式如下: (3) 式中:FP表示惡意樣例被錯誤劃分為正常樣例的個數;N表示惡意樣例的總個數。 Accuracy:表示準確率,即所有樣本被正常分類的比率。其公式如下: (4) 式中:TN表示惡意樣例被正常分類的個數。 Precision:表示精度,即非惡意樣本正常分類的個數占所有被正常分類總樣本個數的比率。其公式如下: (5) Recall:表示查全率,即表示非惡意樣本被正常分類的個數占總正常樣本的個數的比率。其公式如下: (6) F-measure:表示綜合查全率,即平均上述的Precision和Recall指標后的綜合評測標準。其公式如下: (7) 本節包含了對不同特征的分類性能的驗證實驗,具體包括以下兩部分實驗:(1) 基于抽象API調用序列特征的分類實驗。(2) 本方法與市場已有的惡意軟件檢測方法的比較實驗。 3.2.1基于抽象API調用序列特征的分類實驗 實驗結果對不同API版本的數據集上的準確率、召回率表現進行了詳細地統計。從表3中可以看出,API版本在16~23的F-measure和API版本在24~27的F-measure都是93%。API版本在16~23和24~27的TPR、 FPR的差距都只控制在0.2%,表明本文方法能有效區分惡意樣本且不受API版本的影響。 表3 不同API版本中RandomForest算法的各項指標 % 3.2.2與其他方法的對比實驗 為了驗證本文提出的基于抽象API調用序列的特征方法對于Android惡意軟件的檢測效果。將本文提出的檢測方法與邵舒迪等[9]提出的基于權限和API特征結合方法,以及盧正軍等[10]提出的基于上下文信息的Android惡意行為檢測方法進行對比實驗。實驗結果如圖7所示。 圖7 本文方法與文獻[9]和文獻[11]方法對比結果 根據實驗結果可以看出,本文方法的檢測精度比文獻[9]方法高出了3.8%,比文獻[11]提出的方法檢測率高出了1%。因此,基于抽象API調用序列的Android惡意軟件檢測方法效果遠優于的文獻[9]和文獻[11]方法,且實驗結果更加具有說服力。 根據目前Android系統存在的安全問題,本文在對Android應用軟件的靜態特征進行分析后,提出了一種基于抽象API調用序列的Android應用軟件檢測方法,來判別某個軟件是否為惡意軟件。本文對3 000款正常軟件和2 000款惡意軟件進行了仿真實驗,結果驗證了本文提出的方法的準確性和高效性。 該方法依舊還有提升的空間,可以結合動態方法提取惡意軟件運行時的行為進行分析,同樣也可以從運行時API調用的角度出發考慮,將動態和靜態分析獲取到的API調用序列融合在一起,或許可以達到更好的檢測效果。3 實驗結果與分析
3.1 方法評測標準
3.2 實驗結果


4 結 語