鄭曉梅 楊宇飛 程 碩 潘正東
1(南京中醫(yī)藥大學(xué)信息技術(shù)學(xué)院 江蘇 南京 210023)2(南京大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系 江蘇 南京 210023)3(南京大學(xué)計(jì)算機(jī)軟件新技術(shù)國(guó)家重點(diǎn)實(shí)驗(yàn)室 江蘇 南京 210023)
隨著移動(dòng)智能終端的普及,Android系統(tǒng)的市場(chǎng)范圍在不斷擴(kuò)大,Android應(yīng)用程序的規(guī)模也在逐年擴(kuò)大。數(shù)據(jù)顯示,目前僅在Google Play就有373萬(wàn)應(yīng)用,并且以每個(gè)月數(shù)萬(wàn)個(gè)的速度增加。然而,其中約13%為低品質(zhì)應(yīng)用,大部分包含惡意代碼,顯示出不同的惡意行為,例如盜取用戶短信內(nèi)容、盜取用戶通信錄信息、自動(dòng)訂購(gòu)付費(fèi)業(yè)務(wù)、泄漏用戶位置信息等行為,用戶往往很難鑒別[1]。此外,由于國(guó)內(nèi)第三方市場(chǎng)往往缺乏嚴(yán)格的審查制度,讓大量垃圾應(yīng)用擁入,用戶的隱私安全和正常使用都得不到保障[2],因此針對(duì)Android平臺(tái)的惡意軟件檢測(cè)技術(shù)顯得格外重要。
此外,Android新推出的動(dòng)態(tài)加載技術(shù)支持分離執(zhí)行體的方式實(shí)現(xiàn)運(yùn)行時(shí)的動(dòng)態(tài)程序加載,這雖然可以實(shí)現(xiàn)熱更新、快速修復(fù)bug等功能[3],但同時(shí)也給惡意行為檢測(cè)帶來(lái)了新的挑戰(zhàn)。開發(fā)者可以在執(zhí)行過程中通過動(dòng)態(tài)加載方式下載并運(yùn)行惡意行為程序[4],而傳統(tǒng)的靜態(tài)代碼分析技術(shù)無(wú)法有效檢測(cè)[5]。
針對(duì)該問題,提出了一種動(dòng)靜態(tài)相結(jié)合的Android程序惡意行為檢測(cè)技術(shù),先針對(duì)宿主App采用靜態(tài)分析技術(shù),提取程序的控制流圖,通過分析動(dòng)態(tài)加載點(diǎn)的位置進(jìn)行路徑制導(dǎo)的動(dòng)態(tài)執(zhí)行,以獲得動(dòng)態(tài)加載的APK。然后,再針對(duì)其進(jìn)行靜態(tài)分析獲得控制流圖[6],通過對(duì)宿主App和被加載APK的控制流組合,得到整個(gè)系統(tǒng)的完整控制流圖。針對(duì)該控制流圖進(jìn)行遍歷和惡意行為模式的匹配,就可以完成對(duì)完整App的檢測(cè)。本文基于所提出的惡意代碼檢測(cè)方法,開發(fā)了相應(yīng)的原型工具、構(gòu)造了實(shí)例,并且進(jìn)行了實(shí)例研究。
現(xiàn)有的惡意代碼檢測(cè)技術(shù)主要分為靜態(tài)分析和動(dòng)態(tài)分析。靜態(tài)分析是在獲取源碼或編譯體的情況下不運(yùn)行程序直接進(jìn)行程序分析;動(dòng)態(tài)分析主要是通過運(yùn)行程序,在運(yùn)行時(shí)收集相應(yīng)的上下文環(huán)境、虛擬機(jī)及操作系統(tǒng)等信息,進(jìn)而完成分析。
常用的靜態(tài)分析技術(shù)包括抽象語(yǔ)法樹分析、語(yǔ)義分析、控制流分析、數(shù)據(jù)流分析[7]、污點(diǎn)分析[8]、程序切片[9]等,目的是驗(yàn)證代碼是否規(guī)范、安全、可靠、便于維護(hù)。靜態(tài)分析能夠提供程序所有可能執(zhí)行的情況,其執(zhí)行速度快、效率高,但相對(duì)于動(dòng)態(tài)分析,靜態(tài)分析采用了很多推斷機(jī)制,因此誤報(bào)率也較高。同時(shí),靜態(tài)分析需要在進(jìn)行分析前獲得程序的所有源碼或編譯體,對(duì)于執(zhí)行體分離的運(yùn)行時(shí)加載程序難以實(shí)施靜態(tài)分析。相比之下,動(dòng)態(tài)分析因?yàn)槭窃趫?zhí)行過程中收集信息,因此準(zhǔn)確,誤報(bào)率較低。而且對(duì)于動(dòng)態(tài)加載的執(zhí)行體,也可以非常方便地在運(yùn)行時(shí)完成加載和執(zhí)行。但動(dòng)態(tài)分析的缺點(diǎn)也非常明顯,那就是環(huán)境配置和執(zhí)行過程的時(shí)間成本太高,而且難以保證覆蓋程序的所有路徑[13]。
目前主要的Android分析工具有Soot(Java字節(jié)碼分析工具)、IntelliDroid(該工具為動(dòng)態(tài)分析Android惡意軟件提供目標(biāo)輸入)、FlowDroid(基于污點(diǎn)分析的靜態(tài)分析工具)。Soot是加拿大麥吉爾大學(xué)的Sable課題組研發(fā)的Java字節(jié)碼分析工具,主要用于對(duì)字節(jié)碼的分析、插樁、優(yōu)化等,是Java和Android靜態(tài)分析方面應(yīng)用最廣泛的工具之一。Soot工具支持Call-graph 構(gòu)造、定義/調(diào)用鏈、模板驅(qū)動(dòng)的程序內(nèi)數(shù)據(jù)流分析、污點(diǎn)分析等。IntelliDroid是一個(gè)為動(dòng)態(tài)分析Android 惡意軟件提供目標(biāo)輸入的工具。由于Android應(yīng)用程序的入口點(diǎn)很多,包含很多的事件,僅僅觸發(fā)包含敏感API的Handler是不足的,有可能需要按照一定的順序觸發(fā)多個(gè)Handler,才會(huì)觸發(fā)真正的惡意行為,而IntelliDroid能做到觸發(fā)事件及其順序。利用IntelliDroid,可以有目的性地去觸發(fā)所期望的目標(biāo)函數(shù),而不是傳統(tǒng)的fuzzing方式。FlowDroid是Sable小組開發(fā)的,以Soot為基礎(chǔ),基于污點(diǎn)分析的靜態(tài)分析工具,目的是檢測(cè)Android 應(yīng)用程序中是否存在從source到sink的數(shù)據(jù)流[10],其中source是用戶的敏感數(shù)據(jù)(如短信、聯(lián)系人、數(shù)據(jù)庫(kù)等),sink是泄露方式(如短信發(fā)送、因特網(wǎng)等)。
靜態(tài)方法和動(dòng)態(tài)執(zhí)行方法單獨(dú)使用在檢測(cè)動(dòng)態(tài)加載的Android應(yīng)用上時(shí)往往不能取得充分的結(jié)果。惡意代碼的靜態(tài)分析方法容易被開發(fā)者繞過,開發(fā)者可以選擇先開發(fā)正常應(yīng)用通過靜態(tài)檢測(cè),后期加入惡意的動(dòng)態(tài)加載文件實(shí)現(xiàn)惡意行為。而單獨(dú)使用動(dòng)態(tài)方法難以覆蓋所有的執(zhí)行路徑,也無(wú)法充分檢測(cè)出惡意行為。
工作基于IntelliDroid將動(dòng)態(tài)加載API(DexClassLoader)作為目標(biāo)函數(shù),從而獲得加載的程序,用作進(jìn)一步分析和檢測(cè)。此外,采用source & sink的方式進(jìn)行污點(diǎn)分析檢測(cè)。使用FlowDroid以APK文件作為靜態(tài)污點(diǎn)分析的輸入,模擬了完整的Android應(yīng)用生命周期來(lái)處理回調(diào),source、sink的檢測(cè)通過解析從APK文件中抽取的manifest文件、Dalvik虛擬機(jī)字節(jié)碼文件和xml布局文件,生成一種dummy main函數(shù),模擬activity生命周期,建立函數(shù)調(diào)用控制流圖CFG。
在上述研究的基礎(chǔ)上,本文提出面向動(dòng)態(tài)加載的Android應(yīng)用惡意代碼檢測(cè)方法。
惡意代碼檢測(cè)方法整體框架如圖1所示,在整個(gè)框架中,分為三個(gè)模塊:宿主App檢測(cè)模塊、動(dòng)態(tài)加載文件分析模塊和完整惡意行為分析模塊。
圖1 惡意代碼檢測(cè)方法整體框架
該惡意代碼檢測(cè)方法大致的步驟如下:
(1) 對(duì)分析應(yīng)用程序進(jìn)行逆向工程。提取出APK(Android application package)中的dex字節(jié)碼文件、資源文件和配置文件,然后利用工具將Android的dex字節(jié)碼文件轉(zhuǎn)化為靜態(tài)分析工具能夠處理的Java的class字節(jié)碼文件(.class)。
(2) 進(jìn)行靜態(tài)分析。使用IntelliDroid工具,對(duì)逆向生成的Java字節(jié)碼文件進(jìn)行靜態(tài)分析,包括調(diào)用圖分析和控制流分析,檢測(cè)工程中是否使用了動(dòng)態(tài)加載技術(shù),生成到達(dá)動(dòng)態(tài)加載點(diǎn)的路徑,抽取構(gòu)成路徑的事件序列,生成路徑上的條件約束,作為后續(xù)動(dòng)態(tài)執(zhí)行過程中的依賴輸入。
(3) APK插樁。使用Soot工具對(duì)原始APK進(jìn)行插樁,在動(dòng)態(tài)加載點(diǎn)插入記錄信息的代碼,使得當(dāng)App觸發(fā)動(dòng)態(tài)加載時(shí),能夠記錄下動(dòng)態(tài)加載文件的存儲(chǔ)路徑、被加載的類信息、被調(diào)用的方法信息等,并輸出到文件中。
(4) 進(jìn)行約束求解和動(dòng)態(tài)執(zhí)行事件序列。利用z3求解器對(duì)路徑上的約束進(jìn)行求解,然后利用Android模擬器的adb調(diào)試工具,執(zhí)行路徑上的事件序列,觸發(fā)動(dòng)態(tài)加載,得到被動(dòng)態(tài)加載的文件。
(5) 分析檢測(cè)被動(dòng)態(tài)加載的文件。利用Soot工具,對(duì)被動(dòng)態(tài)加載的文件進(jìn)行控制流分析,生成相關(guān)類的包含方法signature的控制流圖,得到外部文件的相關(guān)調(diào)用序列。
最后將步驟2中得到的調(diào)用方法序列與步驟5中得到的動(dòng)態(tài)加載文件的調(diào)用序列拼接,形成完整的包含外部方法的序列。遍歷該序列,進(jìn)行惡意行為檢測(cè),不僅可以檢測(cè)出動(dòng)態(tài)加載文件中的惡意行為,還能檢測(cè)出宿主App和動(dòng)態(tài)加載文件兩者組合產(chǎn)生的惡意行為。
在此框架方法的基礎(chǔ)上,部署整個(gè)工程成Web項(xiàng)目,通過前后端交互的方式,實(shí)現(xiàn)用戶在前端簡(jiǎn)單操作上傳APK,等待后端分析檢測(cè)完成后,直接展示給用戶分析檢測(cè)報(bào)告。
宿主App檢測(cè)模塊主要對(duì)宿主App進(jìn)行分析,目的是生成宿主App內(nèi)部的控制流信息,提取出動(dòng)態(tài)加載文件、記錄下動(dòng)態(tài)加載的相關(guān)參數(shù)信息,用于后續(xù)模塊分析。主要步驟如下:
(1) APK逆向階段,結(jié)合使用Apktool和dex2jar工具,將APK解包,把Android 字節(jié)碼文件(.dex)逆向轉(zhuǎn)化為靜態(tài)分析工具能夠處理的Java字節(jié)碼文件(.class)。
(2) 靜態(tài)分析階段,判斷宿主App是否采用動(dòng)態(tài)加載技術(shù)和生成可以到達(dá)動(dòng)態(tài)加載點(diǎn)的路徑,以及該路徑上的語(yǔ)句和約束。使用IntelliDroid工具,對(duì)逆向生成的Java字節(jié)碼文件進(jìn)行靜態(tài)分析,包括調(diào)用圖分析和控制流分析,檢測(cè)工程中是否使用了動(dòng)態(tài)加載技術(shù),生成到達(dá)動(dòng)態(tài)加載點(diǎn)的路徑,抽取構(gòu)成路徑的事件序列,生成路徑上的條件約束,作為后續(xù)動(dòng)態(tài)執(zhí)行過程中的依賴輸入。
修改IntelliDroid的配置文件,將目標(biāo)方法設(shè)置為動(dòng)態(tài)加載相關(guān)的API。依據(jù)動(dòng)態(tài)加載技術(shù)的使用方法,創(chuàng)建DexClassLoader或PathClassLoader類加載器后,都需要調(diào)用類加載器的loadClass方法來(lái)將目標(biāo)類加載進(jìn)來(lái),因此將loadClass方法作為目標(biāo)方法,修改targeted-Methods.txt配置文件,填寫
靜態(tài)分析完成后,將在指定的輸出目錄生成一些結(jié)果文件,包括appInfo.json(App靜態(tài)分析的文件結(jié)果:mainActivity,到達(dá)目標(biāo)方法路徑的起點(diǎn)和終點(diǎn)等)、constrainsM_N.py(約束文件,表示要觸發(fā)第M條路徑上第N個(gè)受約束的事件需要滿足的約束)和instrPath.json(到達(dá)動(dòng)態(tài)加載點(diǎn)的所有路徑控制流文件,記錄了該路徑上的所有調(diào)用語(yǔ)句及其順序)。
(3) APK插樁階段,使用Soot工具對(duì)原始APK進(jìn)行插樁,在動(dòng)態(tài)加載點(diǎn)插入記錄信息的代碼,當(dāng)App觸發(fā)動(dòng)態(tài)加載時(shí),能夠記錄下動(dòng)態(tài)加載文件的存儲(chǔ)路徑、被加載的類信息、被調(diào)用的方法信息等,并輸出到文件中。DexClassLoader的構(gòu)造方法如下:
DexClassLoader (String dexPath,
String optimizedDirectory,
String librarySearchPath,
ClassLoader parent)
共有4個(gè)參數(shù),其中:dexPath表示外部文件的路徑,optimizedDirectory表示外部文件釋放的路徑,librarySearchPath表示包含native libraries的文件目錄列表(一般設(shè)置為null),parent表示父類加載器。主要關(guān)心參數(shù)dexPath,在DexClassLoader構(gòu)造完成后,只需將dexPath指向的文件拷貝到預(yù)先設(shè)定好的目錄下,就能得到被加載的文件而且不會(huì)被系統(tǒng)刪除,用于后續(xù)的外部文件分析。
此外,在應(yīng)用程序執(zhí)行l(wèi)oadClass和getMethod方法之后,插入代碼分別記錄下類的名稱和方法的名稱,并存儲(chǔ)在預(yù)先建立好的log文件中,用于后續(xù)的外部文件分析。插樁完成后,得到了經(jīng)過“改造”的APK文件,后續(xù)將該APK文件安裝在Android模擬器上,動(dòng)態(tài)執(zhí)行該App,來(lái)獲取外部文件和動(dòng)態(tài)加載調(diào)用的相關(guān)信息。
(4) 解析約束階段,使用z3求解器,對(duì)靜態(tài)分析生成的約束文件進(jìn)行求解,依次執(zhí)行時(shí)間序列,達(dá)到觸發(fā)動(dòng)態(tài)加載的目的,并且在這個(gè)過程中執(zhí)行插樁的代碼,記錄輸出相應(yīng)的信息。執(zhí)行完成之后,將動(dòng)態(tài)加載文件和記錄信息的log日志從Android 系統(tǒng)中提取到本地,作為后續(xù)動(dòng)態(tài)加載文件分析的依賴。
動(dòng)態(tài)加載文件分析模塊主要對(duì)動(dòng)態(tài)加載文件進(jìn)行分析,目的是依據(jù)記錄的動(dòng)態(tài)加載的相關(guān)參數(shù)信息,生成動(dòng)態(tài)加載文件中的控制流信息。主要步驟如下:
(1) 外部文件預(yù)處理階段,根據(jù)Android開發(fā)者文檔的說(shuō)明,動(dòng)態(tài)加載的文件可以是dex文件、apk文件和jar文件三種類型,并且apk文件和jar文件必須包含classes.dex文件。依據(jù)動(dòng)態(tài)加載的原理,無(wú)論被加載的文件是哪種格式,其本質(zhì)上都是先將包含的dex文件釋放到臨時(shí)目錄,然后再加載該dex文件。因此預(yù)處理的第一步是先將動(dòng)態(tài)加載文件解包,將其中包含的dex文件拷貝到指定目錄再進(jìn)行處理。
預(yù)處理包括兩個(gè)步驟:一是逆向處理,同樣使用dex2jar工具,將動(dòng)態(tài)加載的dex文件逆向轉(zhuǎn)化為Java字節(jié)碼文件,生成包含所有Java字節(jié)碼(.class)文件的文件夾,并且保證每層文件夾都以該層的包名稱來(lái)命名;二是對(duì)動(dòng)態(tài)加載文件進(jìn)行簡(jiǎn)單掃描,分析其中包含的類和方法,生成相應(yīng)文件的方法表,將classes.jar作為處理對(duì)象,使用"jar tf classes.jar grep.class"指令來(lái)獲取jar文件中的所有類信息,再使用"javap-cp classes.jar
(2) 外部方法靜態(tài)分析階段,使用Soot工具,對(duì)逆向后的Java字節(jié)碼文件進(jìn)行靜態(tài)分析,生成目標(biāo)類的控制流,并依據(jù)生成的方法表,對(duì)控制流在JDK和Android SDK層面進(jìn)行方法的展開,將控制流對(duì)象序列化,保存在文件中。
生成控制流圖相關(guān)的main方法位于soot.tools.CFGViewer類中,只需要指定要分析的類的完整信息(即包含PackageName和ClassName,以“.”來(lái)分隔)以及相關(guān)CLASSPATH(一般指android.jar和jre/lib/rt.jar),即可生成該類中所有方法的控制流信息。類信息從之前動(dòng)態(tài)執(zhí)行之后保存在本地的log文件中讀取。
Soot在控制流分析的過程中,對(duì)每條指令做了簡(jiǎn)化,僅包含調(diào)用方法的名稱而略去了所在類和返回值類型這兩個(gè)重要的信息,因此對(duì)Soot源碼進(jìn)行修改,使得生成的控制流中包含方法完整的signature,圖2是修改前后的比較。
圖2 Soot源碼修改前后生成的控制流語(yǔ)句對(duì)比
為了更好地記錄和利用控制流信息,定義了一個(gè)變量來(lái)在內(nèi)存中保存該控制流信息,其數(shù)據(jù)結(jié)構(gòu)為Map
由于Soot控制流分析的局限性,分析得到的某個(gè)方法的控制流不能夠做到對(duì)方法調(diào)用的進(jìn)一步展開,因此需要解決這一問題。為了保證工作的正確性以及處理效率,將方法展開的范圍限定為整個(gè)動(dòng)態(tài)加載文件的工程中,即只對(duì)預(yù)處理階段得到的方法表中的方法進(jìn)行展開,其余方法視為JDK級(jí)別、SDK級(jí)別以及第三方依賴方法不做展開處理。為了提高方法展開的效率,還定義了一個(gè)靜態(tài)變量AllControlFlow來(lái)存儲(chǔ)各個(gè)類的控制流信息,避免了對(duì)序列化后存儲(chǔ)的控制流文件的重復(fù)讀取,AllControlFlow是Map對(duì)象,以類名作為key鍵,以相對(duì)應(yīng)的控制流(即上文中提到的Map)作為value值。具體解決方案的偽代碼如算法1所示。
算法1控制流中的方法展開過程
輸入:原始、未做展開的方法控制流
過程:methodExpand
1.for 控制流中的每條路徑path do
2. for 每條路徑中的調(diào)用語(yǔ)句call do
3. if call調(diào)用的方法在方法表methodTable中then
4. if call調(diào)用的方法在AllContolFlow中能找到then
5. 直接從AllControlFlow中得到相應(yīng)的控制流controlFlow
6. 用controlFlow替換該調(diào)用語(yǔ)句
7. else
8. 利用Soot生成調(diào)用的方法所在類的控制流controlFlow
9. 將controlFlow更新到AllControlFlow
10.用controlFlow替換該調(diào)用語(yǔ)句
11.end if
12. end if
13. end for
14.end for
15.更新展開后的控制流到AllControlFlow中
16.更新序列化文件
在展開的過程中,為了兼顧效率和準(zhǔn)確性,設(shè)定了最大展開深度,避免出現(xiàn)因?yàn)檫f歸層數(shù)較深造成的長(zhǎng)時(shí)間循環(huán)的現(xiàn)象。如果將最大展開深度設(shè)置為無(wú)窮大,那么最終得到的控制流可以認(rèn)為是僅包含Java和Android API調(diào)用的序列。至此,得到了動(dòng)態(tài)加載文件的控制流信息。
將宿主App的控制流與動(dòng)態(tài)加載文件的控制流進(jìn)行合并,得到完整的控制流,逐個(gè)路徑進(jìn)行掃描檢測(cè)敏感API,與預(yù)先設(shè)定的惡意行為模式進(jìn)行匹配,得到最終的分析檢測(cè)結(jié)果。
2.4.1控制流合并
經(jīng)過宿主App的檢測(cè)與分析以及動(dòng)態(tài)加載文件的檢測(cè)與分析,分別得到了APK內(nèi)部與外部的控制流信息。根據(jù)APK內(nèi)部的控制流中的動(dòng)態(tài)加載點(diǎn)的信息,在不同的動(dòng)態(tài)加載點(diǎn)插入相應(yīng)的外部方法的控制流,就得到了完整的控制流信息。在宿主App內(nèi)部的控制流中,對(duì)每一條控制流語(yǔ)句進(jìn)行了編號(hào),作為確定位動(dòng)態(tài)加載的依據(jù)。同時(shí),每條路徑還定義了名為invokePoints的變量,記錄下動(dòng)態(tài)加載方法調(diào)用語(yǔ)句相對(duì)應(yīng)的控制流語(yǔ)句的編號(hào),結(jié)合log文件中記錄的global Loading Method,即可得知?jiǎng)討B(tài)加載調(diào)用的方法和調(diào)用所在的位置,將外部的相應(yīng)方法的控制流插入該位置即可[11]。控制流合并的偽代碼如算法2所示。
算法2控制流合并
輸入:內(nèi)部控制流interCF、外部控制流outerCF
過程:controlFlowMerge
1.for interCF中的每條路徑path do
2. for 每條路徑path中的invokePoints do
3. for 每個(gè)invokePoints中的插入點(diǎn)point do
4. 讀取log文件中point對(duì)應(yīng)globalLoading Method信息
5. 根據(jù)global Loading Method信息,從outerCF中獲取相應(yīng)方法的控制流methodControlFlow
6. 根據(jù)point,定位到相應(yīng)的invoke調(diào)用語(yǔ)句
7. 用methodControlFlow替換該invoke語(yǔ)句
8. end for
9. end for
10.end for
輸出:合并后的控制流mergedCF。
2.4.2惡意代碼檢測(cè)階段
定義一些典型的惡意行為模式,如竊取短信內(nèi)容、竊取通訊錄信息、竊取用戶位置信息等。將有關(guān)惡意行為的API稱之為敏感API,敏感API可以分為兩類:獲取用戶隱私信息的API,稱之為source-API;泄露用戶隱私信息的API,稱之為sink-API。主要依據(jù)FlowDroid的污點(diǎn)分析的配置文件,搜集了一些Android開發(fā)中會(huì)使用到的敏感API,并同樣使用配置文件的形式,使得敏感API可配置,能自行添加刪除[12]。
對(duì)敏感API 進(jìn)行簡(jiǎn)單的語(yǔ)義分析,使得在執(zhí)行惡意代碼檢測(cè)之后,能夠給出較為準(zhǔn)確的檢測(cè)報(bào)告,反映出軟件的可能存在的具體惡意行為。例如,進(jìn)行控制流分析之后,其中一條路徑上調(diào)用了getLastKnownLocation()方法,可以分析出軟件獲取了用戶的定位信息;接著在該路徑上又調(diào)用了sendTextMessage()方法,可以分析出軟件將某些信息以SMS短信的形式發(fā)送出去,兩者結(jié)合可以判斷,軟件可能存在通過SMS短信泄露用戶位置信息的隱私泄露行為。類似地,對(duì)多種API組合進(jìn)行了惡意行為模式的定義,關(guān)鍵信息為隱私的種類和泄露的方式,即:該軟件可能存在獲取用戶XX隱私,并通過XX方式將其泄露的惡意行為。
根據(jù)提出的惡意代碼檢測(cè)方法,在現(xiàn)有工具的基礎(chǔ)上,實(shí)現(xiàn)了能夠完整執(zhí)行惡意代碼檢測(cè)流程的原型工具,其簡(jiǎn)要框架如圖3所示。
圖3 原型工具框架圖
主要依賴Soot和IntelliDroid工具,實(shí)現(xiàn)本文工作中的靜態(tài)分析和插樁工作,使用ApkTool工具對(duì)Android應(yīng)用進(jìn)行逆向工程,使用z3求解器求解約束實(shí)現(xiàn)動(dòng)態(tài)執(zhí)行。
通過實(shí)驗(yàn)對(duì)所提出的面向動(dòng)態(tài)加載的Android應(yīng)用惡意代碼檢測(cè)方法進(jìn)行評(píng)估。
(1) 本次實(shí)驗(yàn)采用的實(shí)例,是一款名為“閱讀神器”的App,來(lái)源于國(guó)內(nèi)知名移動(dòng)安全論壇——看雪論壇,由論壇用戶上傳提供,并稱該應(yīng)用可能存在木馬行為。該應(yīng)用申請(qǐng)了SMS即短信權(quán)限,通過查看APK中的AndroidManifest.xml文件,可以得知主要是SEND_SMS和READ_SMS權(quán)限,這與應(yīng)用本身作為閱讀軟件的用途不相符。通過將該App安裝在Android虛擬機(jī)上并測(cè)試,卻發(fā)現(xiàn)該App在表面上并沒有明顯惡意行為。
(2) 宿主App的檢測(cè)與分析階段,首先將APK文件進(jìn)行逆向處理,生成相應(yīng)的Java字節(jié)碼文件,以及解包APK中的資源文件;對(duì)逆向處理后的應(yīng)用進(jìn)行靜態(tài)分析,生成宿主App內(nèi)部的控制流信息和觸發(fā)動(dòng)態(tài)加載的事件序列及其約束。接著對(duì)原始APK read.apk進(jìn)行插樁,植入相關(guān)代碼,生成插樁完成之后的APK read-ins.apk;將read-ins.apk和靜態(tài)分析產(chǎn)生的事件序列及其約束作為輸入,進(jìn)行動(dòng)態(tài)執(zhí)行操作,插樁后的Apk被安裝在Android模擬器上,解析約束,執(zhí)行事件序列。最終得到被動(dòng)態(tài)加載的文件cao.apk和動(dòng)態(tài)執(zhí)行記錄文件log.txt。結(jié)果顯示經(jīng)過逆向的APK的資源文件中同樣存在一個(gè)名為cao.apk的文件,位于/res/raw目錄下,經(jīng)過文件的MD5值計(jì)算和對(duì)比,可以判定兩者為同一文件,代表著該應(yīng)用動(dòng)態(tài)加載的目標(biāo)文件位于工程內(nèi)部的資源文件中。
(3) 在動(dòng)態(tài)加載文件的檢測(cè)與分析階段,得到動(dòng)態(tài)加載文件cao.apk之后,對(duì)其進(jìn)行控制流分析,根據(jù)log.txt文件中的記錄,動(dòng)態(tài)加載調(diào)用的xcvwreoipurew.zxcbwqioewr.xcvzmbnwerqoi.zxcvbnm類中的faxinxi方法。該方法的控制流圖,如圖4所示。
圖4 faninxi方法的控制流圖
該方法調(diào)用了sendMultipartTextMessage這一API,屬于敏感API,在后續(xù)過程中觀察是否能檢測(cè)出可能存在的惡意行為。
(4) 經(jīng)過合并和檢測(cè),得出了檢測(cè)報(bào)告。根據(jù)檢測(cè)報(bào)告顯示,該應(yīng)用調(diào)用getMessageBody方法來(lái)讀取用戶短信內(nèi)容,獲取了用戶的隱私數(shù)據(jù),然后調(diào)用了sendMultipartTextMessage方法將隱私數(shù)據(jù)以短信的形式發(fā)送出去,不但會(huì)泄露用戶的隱私,還會(huì)造成額外的短信費(fèi)用,可以將其作為一種惡意行為。檢測(cè)結(jié)果與之前通過人工查看控制流的預(yù)測(cè)相吻合。
此外,通過逆向原始APK,閱讀反編譯后的源碼,結(jié)合靜態(tài)分析生成的事件序列后發(fā)現(xiàn),動(dòng)態(tài)加載的調(diào)用位于短信服務(wù)的onReceive方法中,因此猜想該應(yīng)用會(huì)在用戶收到短信的情況下,讀取短信內(nèi)容,并將其發(fā)送給預(yù)設(shè)的收件人,造成隱私泄露和不知情扣費(fèi)。后續(xù)利用telnet向Android模擬器模擬發(fā)短信,確實(shí)觸發(fā)了該應(yīng)用的動(dòng)態(tài)加載,進(jìn)一步證明了預(yù)測(cè)的正確性。
(1) 使用開源應(yīng)用Good Weather項(xiàng)目地址:https://github.com/qqq3/-good-weather。Good Weather作為一款天氣軟件,擁有獲取設(shè)備定位信息的權(quán)限,因此我們對(duì)其進(jìn)行改造,在原始代碼中獲取定位信息之后,插入執(zhí)行動(dòng)態(tài)加載的代碼,達(dá)到將定位信息發(fā)送至預(yù)設(shè)服務(wù)器的目的,來(lái)模擬隱私信息的泄露。
(2) 為了保證實(shí)驗(yàn)的公正,使用惡意軟件在線檢測(cè)網(wǎng)站VirusTotal對(duì)樣本進(jìn)行檢測(cè),并與結(jié)果進(jìn)行對(duì)比。先對(duì)未插入任何代碼的Good Weather應(yīng)用進(jìn)行檢測(cè)。63種不同公司的檢測(cè)方法均沒有檢測(cè)出Good Weather本身包含惡意代碼,因此認(rèn)為該樣本是純凈的。
接著對(duì)插入動(dòng)態(tài)加載代碼之后的Good Weather應(yīng)用進(jìn)行檢測(cè),63種不同公司的檢測(cè)方法中有62種沒有檢測(cè)出Good Weather本身包含惡意代碼,僅僅有一個(gè)公司給出了風(fēng)險(xiǎn)告警,因此可以大致認(rèn)為經(jīng)過改造之后的包含惡意的Good Weather應(yīng)用不能被絕大部分檢測(cè)方法發(fā)現(xiàn)惡意代碼。下面將展示對(duì)該應(yīng)用的檢測(cè)結(jié)果,由于上文已經(jīng)對(duì)具體實(shí)現(xiàn)方法進(jìn)行了詳細(xì)介紹,因此該實(shí)例僅介紹檢測(cè)結(jié)果和分析。
第一條路徑存在隱患,從獲取隱私到泄漏的路徑如圖5所示。
圖5 插入代碼后的Good Weather的本文工作檢測(cè)結(jié)果
可以看出,工作實(shí)現(xiàn)的工具成功地檢測(cè)出了該隱私泄露,準(zhǔn)確定位到了隱私信息和泄露相關(guān)的API調(diào)用,即通過getLatitude()獲取用戶的位置信息,使用okhttp框架的post請(qǐng)求,將該隱私信息發(fā)送到預(yù)先啟動(dòng)的服務(wù)器上。宿主App中本身就包含獲取定位信息的代碼,插入的僅有DexClassLoader的構(gòu)造和類加載、方法調(diào)用的簡(jiǎn)單代碼,而在動(dòng)態(tài)加載文件中實(shí)現(xiàn)了基于okhttp框架的post請(qǐng)求的發(fā)送的功能,兩者獨(dú)立的情況下不存在惡意行為,但兩者結(jié)合起來(lái)就是一種典型的通過post請(qǐng)求泄露用戶隱私的惡意行為。
通過以上的檢測(cè)、分析和對(duì)比,證明了利用動(dòng)態(tài)加載技術(shù)可以躲避當(dāng)前大部分的惡意代碼檢測(cè),實(shí)現(xiàn)對(duì)用戶隱私信息的盜取。而提出和實(shí)現(xiàn)的惡意代碼檢測(cè)方法,能夠有效針對(duì)這一情況,提高檢測(cè)的準(zhǔn)確率,減少惡意軟件的漏報(bào)。
提出的基于控制流的動(dòng)靜態(tài)結(jié)合檢測(cè)方法,針對(duì)Android動(dòng)態(tài)加載機(jī)制進(jìn)行惡意代碼檢測(cè),并開發(fā)出了相關(guān)工具,能有效地檢測(cè)出應(yīng)用中的惡意行為,可以作為Android第三方市場(chǎng)上架應(yīng)用前對(duì)應(yīng)用程序的檢測(cè)手段。
接下來(lái)的工作中,擬將從以下幾個(gè)方面來(lái)進(jìn)一步改善目前所提出檢測(cè)方法:(1) 通過更加準(zhǔn)確的靜態(tài)分析、更高效率的約束求解以及更加高效的控制流分析方法,大幅度提高整個(gè)工程的惡意代碼的檢測(cè)效率。(2) 對(duì)敏感API的調(diào)研仍需要繼續(xù)進(jìn)行,通過搜集更多的惡意應(yīng)用,了解更多的惡意行為。(3) 形成完整的工具平臺(tái)。