朱璋穎 , 史云凡 , 吳振宇, 燕錦華
(1.上海犇眾信息技術(shù)有限公司,上海 201199;2.上海電機(jī)學(xué)院,上海 200240;3.華東計(jì)算技術(shù)研究所,上海 201808)
智能手機(jī)、平板電腦和其他移動(dòng)設(shè)備的普及,使得專為這些設(shè)備設(shè)計(jì)的軟件應(yīng)用程序得到了蓬勃發(fā)展。應(yīng)用程序可以通過(guò)定制化的用戶界面和簡(jiǎn)單的程序邏輯展示W(wǎng)eb頁(yè)面,如社交來(lái)往、新聞娛樂(lè)、Web郵件等。就Android平臺(tái)而言,應(yīng)用開(kāi)發(fā)者可以通過(guò)WebView組件展示W(wǎng)eb頁(yè)面。WebView在Android平臺(tái)上是一個(gè)特殊的View,其基于webkit引擎來(lái)展現(xiàn)web頁(yè)面的控件,可作為移動(dòng)應(yīng)用內(nèi)置的一款內(nèi)核瀏覽器來(lái)加載和顯示web頁(yè)面。WebView內(nèi)部的實(shí)現(xiàn)是采用渲染引擎來(lái)展示內(nèi)容,提供網(wǎng)頁(yè)前進(jìn)、后退、放大、縮小、搜索等功能。目前,許多移動(dòng)應(yīng)用都采用HTML5和原生代碼混合的開(kāi)發(fā)方式,因?yàn)橥ㄟ^(guò)內(nèi)置WebView加載網(wǎng)頁(yè)比較靈活,只需要修改HTML頁(yè)面即可升級(jí)應(yīng)用。因此,WebView組件被廣泛應(yīng)用于移動(dòng)應(yīng)用,并為用戶提供界面展示。
WebView組件能提供與瀏覽器應(yīng)用類似的功能。不同的是,瀏覽器應(yīng)用對(duì)其敏感數(shù)據(jù)和關(guān)鍵資源如cookie等,都提供瀏覽器級(jí)別的保護(hù)。具體而言,瀏覽器應(yīng)用強(qiáng)制實(shí)施同源策略保護(hù),將同域名、端口和協(xié)議的頁(yè)面視為同一個(gè)域,一個(gè)域內(nèi)的腳本僅有該域內(nèi)的訪問(wèn)權(quán)限,不能訪問(wèn)其他域內(nèi)的資源。同源策略的目的是保護(hù)用戶的信息安全,防止被惡意的頁(yè)面竊取信息。目前,所有瀏覽器應(yīng)用都支持這個(gè)策略,WebView也不例外。但是,WebView同時(shí)也提供了一系列API,可以通過(guò)這些API定制化WebView組件配置,而不強(qiáng)制要求實(shí)施同源策略保護(hù)。開(kāi)發(fā)人員使用不安全的API設(shè)置,可開(kāi)啟部分跨域訪問(wèn)的支持。在這種情況下,惡意腳本可以訪問(wèn)應(yīng)用內(nèi)敏感數(shù)據(jù)。不同的敏感數(shù)據(jù)會(huì)給用戶造成不同的安全危害。典型的敏感數(shù)據(jù)如用戶登錄應(yīng)用時(shí)在應(yīng)用本地保存的身份憑證。攻擊者通過(guò)跨域訪問(wèn)并獲取身份憑證后,即可以受害者的身份登錄應(yīng)用并實(shí)現(xiàn)對(duì)移動(dòng)應(yīng)用用戶賬戶的完全控制,這種攻擊被稱為應(yīng)用克隆攻擊。2018年1月,騰訊玄武實(shí)驗(yàn)室利用該類漏洞對(duì)支付寶應(yīng)用進(jìn)行克隆攻擊,并“克隆”用戶賬戶[1]。因此,利用同源策略的設(shè)置漏洞可造成WebView跨域訪問(wèn)安全漏洞,導(dǎo)致用戶隱私數(shù)據(jù)泄露,產(chǎn)生嚴(yán)重的安全威脅[2]。
為檢測(cè)跨域攻擊漏洞,本文首先對(duì)由于WebView跨域訪問(wèn)[3]造成的應(yīng)用克隆攻擊進(jìn)行建模,然后針對(duì)應(yīng)用克隆攻擊的條件,提供了一種基于soot的抽象語(yǔ)法樹(shù)與數(shù)據(jù)流分析的靜態(tài)檢測(cè)方案,通過(guò)構(gòu)造調(diào)用圖(Call Graph)進(jìn)行可達(dá)性分析和過(guò)程內(nèi)數(shù)據(jù)流分析,最后將該檢測(cè)方案實(shí)現(xiàn)為相應(yīng)的檢測(cè)工具。通過(guò)對(duì)大量的Android應(yīng)用進(jìn)行檢測(cè)表明,該工具能夠有效檢測(cè)出Android應(yīng)用是否存在跨域訪問(wèn)漏洞。
安卓應(yīng)用中的WebView,提供一系列API來(lái)支持應(yīng)用開(kāi)發(fā)者進(jìn)行定制化開(kāi)發(fā)。某些API的設(shè)置會(huì)提供部分跨域訪問(wèn)支持。具體而言,WebView實(shí)現(xiàn)某些域的跨域訪問(wèn)涉及以下2個(gè)API設(shè)置:
(1)setAllowFileAccessFromFileURLs用 于 設(shè)置是否允許通過(guò)file url加載的JavaScript訪問(wèn)其他的file域本地文件。在Android 4.0及其以下默認(rèn)值為允許(true),在Android 4.1以及以上版本默認(rèn)值為禁止(false)。
(2)setAllowUniversalAccessFromFileURLs用于設(shè)置是否允許通過(guò)file URL加載的JavaScript訪問(wèn)其他域,默認(rèn)值為禁止(false)。
如果應(yīng)用開(kāi)發(fā)者錯(cuò)誤地將上述兩個(gè)API的參數(shù)設(shè)置為true,就可產(chǎn)生WebView跨域訪問(wèn)漏洞。典型的漏洞利用方式是通過(guò)WebView跨域訪問(wèn)漏洞實(shí)現(xiàn)應(yīng)用的克隆攻擊。
具體而言,成功應(yīng)用克隆攻擊需要滿足以下四個(gè)條件。
(1)WebView待加載的URL可被外部控制
受攻擊的應(yīng)用包含有可以被外部調(diào)用的WebView。該WebView能夠加載外部可控的url,url可通過(guò)以下方式被加載:
①存在Activity組件暴露[4],并可以通過(guò)瀏覽器打開(kāi),傳遞特定的URI信息并加載。
②通過(guò)即時(shí)消息、資訊等內(nèi)容中包含的鏈接信息點(diǎn)擊加載。
(2)可在file域中執(zhí)行任意js腳本
如果要在file域中執(zhí)行任意js腳本,需要滿足兩個(gè)條件,一是WebView能夠使用File協(xié)議,另一個(gè)是通過(guò)某種方式攻擊者能夠向受害者的本地環(huán)境寫入任意js腳本。為了使WebView能夠使用File協(xié)議,只需要將WebView相關(guān)API——setAllowFileAccess設(shè)置為true,默認(rèn)值是允許。為了實(shí)現(xiàn)向受害者的本地環(huán)境寫入js腳本,可通過(guò)瀏覽器實(shí)現(xiàn)自動(dòng)下載網(wǎng)頁(yè)到本地,并加載執(zhí)行或通過(guò)其他方式在file域直接執(zhí)行js語(yǔ)句。目前,公開(kāi)的自動(dòng)下載方式有兩種。第一種方式是通過(guò)在頁(yè)面中設(shè)置頭部為“header("Content-Type∶binary/octetstream")”,此時(shí)會(huì)自動(dòng)下載到sdcard/Download目錄中[5]。第二種方式是通過(guò)在頁(yè)面中設(shè)置頭部為“header("Content-Disposition∶attachment;filename=op endb.html")”,表示以附件形式下載,自動(dòng)下載到目錄sdcard/Download目錄中[6]。通過(guò)構(gòu)造惡意鏈接欺騙用戶點(diǎn)擊打開(kāi)時(shí),就能自動(dòng)下載包含有js腳本的惡意網(wǎng)頁(yè)到本地,隨后將該惡意網(wǎng)頁(yè)傳遞給被攻擊應(yīng)用進(jìn)行加載執(zhí)行。
(3)通過(guò)js腳本獲取本地文件內(nèi)容并傳輸?shù)竭h(yuǎn)程服務(wù)器
為了實(shí)現(xiàn)這一目標(biāo),WebView首先需要允許js腳本可以運(yùn)行,此時(shí)只需要將WebView相關(guān) API——setJavaScriptEnabled要求設(shè)置為 true,默認(rèn)值是不允許。隨后,需要滿足js腳本可以訪問(wèn)本地其他文件并傳輸?shù)竭h(yuǎn)程服務(wù)器,要求設(shè)置setAllowFileAccessFromFileURLs或者setAllowUniver salAccessFromFileURLs為true,就能讀取本地文件內(nèi)容并發(fā)送到遠(yuǎn)程服務(wù)器。
(4)通過(guò)分析確定關(guān)鍵目標(biāo)文件或數(shù)據(jù)實(shí)現(xiàn)應(yīng)用克隆
攻擊者可獲取相應(yīng)移動(dòng)應(yīng)用存儲(chǔ)在手機(jī)本地的信息,包括登陸憑證、照片、文檔等數(shù)據(jù)。利用這些數(shù)據(jù),攻擊者可以在自己手機(jī)中復(fù)制用戶應(yīng)用狀態(tài),以用戶的身份操作移動(dòng)應(yīng)用。
整個(gè)攻擊場(chǎng)景只需要構(gòu)造一條惡意鏈接欺騙用戶點(diǎn)擊,繼而遠(yuǎn)程實(shí)現(xiàn)惡意腳本自動(dòng)下載到本地,將腳本傳送給可被外部調(diào)用的WebView進(jìn)行執(zhí)行即可。惡意鏈接可以利用通信軟件、郵件等方式進(jìn)行傳播。由于這種漏洞是開(kāi)發(fā)者的安全意識(shí)不足導(dǎo)致的,因此Google官方并沒(méi)有修補(bǔ)漏洞的措施。用戶只能通過(guò)安裝更新后的移動(dòng)應(yīng)用來(lái)修復(fù)漏洞攻擊。
為了實(shí)現(xiàn)批量化自動(dòng)檢測(cè)Android應(yīng)用中的WebView跨域訪問(wèn)漏洞,緩解可能的應(yīng)用克隆攻擊,本文基于上述對(duì)應(yīng)用克隆攻擊的利用條件進(jìn)行分析,設(shè)計(jì)了一種靜態(tài)檢測(cè)方案。該方案結(jié)合過(guò)程間控制流分析和過(guò)程內(nèi)數(shù)據(jù)流分析技術(shù),快速且準(zhǔn)確地發(fā)現(xiàn)應(yīng)用是否可能遭受克隆攻擊的威脅。
整個(gè)檢測(cè)流程為:
(1)逆向分析獲取應(yīng)用代碼等文件;
(2)字符串搜索以定位API特征等,包括有可導(dǎo)出Activity列表、WebView對(duì)象、URL加載的API和可引起WebView跨域訪問(wèn)的2個(gè)API;
(3)過(guò)程內(nèi)數(shù)據(jù)流分析,以確定每個(gè)WebView對(duì)象的2個(gè)跨域訪問(wèn)API、1個(gè)File域訪問(wèn)API和1個(gè)js腳本運(yùn)行的參數(shù)值。如果這些API參數(shù)設(shè)置為true,則可能存在克隆攻擊,并記錄下這些WebView對(duì)象位置;否則,判斷該應(yīng)用不存在應(yīng)用克隆攻擊可能性,開(kāi)始檢測(cè)下一個(gè)應(yīng)用;
(4)基于語(yǔ)法樹(shù)構(gòu)造函數(shù)調(diào)用圖進(jìn)行控制流分析,分析(3)中記錄的每個(gè)WebView對(duì)象,根據(jù)WebView對(duì)象獲取其URL加載的API,分析從可導(dǎo)出Activity組件到該API的可達(dá)性,如果滿足可達(dá)性要求,則記錄該WebView對(duì)象URL加載的API并繼續(xù);反之,則選取下一個(gè)WebView對(duì)象;
(5)對(duì)(4)中記錄的WebView URL加載API進(jìn)行過(guò)程內(nèi)的數(shù)據(jù)流分析,如果API參數(shù)是一個(gè)定值,則認(rèn)為URL外部不可控;反之,則認(rèn)為URL可能外部可控。待所有應(yīng)用檢測(cè)結(jié)束,還需要進(jìn)一步人工審計(jì)。
由WebView跨域訪問(wèn)引起應(yīng)用克隆攻擊的檢測(cè)流程如圖1所示。
圖1 WebView跨域訪問(wèn)引起應(yīng)用克隆攻擊的檢測(cè)流程
檢測(cè)流程共包括四個(gè)子模塊,分別是逆向分析、特征定位、數(shù)據(jù)流分析和控制流分析。
(1)逆向分析
待檢測(cè)的Android應(yīng)用以APK的壓縮包形式存在,需要對(duì)其進(jìn)行逆向分析得到Smali代碼和AndroidMainfest.xml文件。目前,存在很多開(kāi)源且有效的逆向工具,如apktool[7]、baksmali[8]、jadx[9]等。利用這些工具可以對(duì)應(yīng)用進(jìn)行反編譯。因此,逆向分析模塊實(shí)現(xiàn)對(duì)逆向工具的集成,存儲(chǔ)反編譯結(jié)果并傳遞給特征定位模塊。
(2)特征定位
根據(jù)應(yīng)用克隆攻擊的利用條件,需要定位到三類特征。
第一,要實(shí)現(xiàn)WebView加載的URL外部可控,可導(dǎo)出Activity作為一個(gè)攻擊入口。安卓應(yīng)用組件是否可導(dǎo)出依賴于組件在應(yīng)用中的配置,其AndroidManifest.xml文件定義了組件的配置信息。位于該文件的android∶exported屬性定義了組件是否可導(dǎo)出,即暴露在安卓環(huán)境中可被外部調(diào)用,該屬性值默認(rèn)為true。如果一個(gè)組件添加了android∶exported=true屬性,則顯示說(shuō)明該組件是暴露的。另外,如果組件定義了intent-filter子元素且android∶exported沒(méi)有設(shè)置,則默認(rèn)表示該組件是暴露的,可以接收來(lái)自其他應(yīng)用程序的Intent[7]。正是基于上述判斷組件暴露的規(guī)則,通過(guò)腳本實(shí)現(xiàn)對(duì)AndroidManifest.xml文件掃描,從而快速定位可導(dǎo)出的Activity組件列表。
第二,定位引起WebView跨域訪問(wèn)的四個(gè)API,分 別 是 setAllowFileAccess、setJavaScriptEnabled、setAllowFileAccessFromFileURLs和setAllowUniversalAcc essFromFileURLs。由于前兩個(gè)API默認(rèn)為true,且出于業(yè)務(wù)需要,這兩個(gè)API也會(huì)設(shè)置為true;而后兩個(gè)API默認(rèn)為false。因此,必須通過(guò)顯示調(diào)用才能設(shè)置為true。實(shí)際操作時(shí),直接通過(guò)字符串搜索后兩個(gè)API的名字即可,記錄API所在的類與方法。
第三,定位WebView加載URL的API函數(shù)。WebView加載HTML代碼共提供了三個(gè)函數(shù):loadUrl、loadData和 loadDataWithBaseURL。前者會(huì)傳入一個(gè)Web頁(yè)面鏈接,后兩者傳入HTML代碼。本文只考慮API——loadUrl。實(shí)際操作時(shí),直接通過(guò)字符串搜索該API的字符串即可,記錄API所在的類、調(diào)用方法名和調(diào)用該API的WebView對(duì)象。
(3)數(shù)據(jù)流分析
數(shù)據(jù)流分析[10]是根據(jù)(2)中定位的API分析其參數(shù)賦值。數(shù)據(jù)流分析是在過(guò)程內(nèi)實(shí)施的。在整個(gè)檢測(cè)方案中,共有兩處需要應(yīng)用數(shù)據(jù)流分析。第一,定位到引起WebView跨域訪問(wèn)的四個(gè)API后,基于函數(shù)的Smali代碼構(gòu)造API參數(shù)變量的引用-定值鏈,從而確定API參數(shù)的值。如果對(duì)于同一個(gè)WebView對(duì)象,其四個(gè)API的參數(shù)值存在都為true的可能性,則繼續(xù)分析;反之,只要其中一個(gè)API確定為false,則重新分析其他WebView對(duì)象。第二,對(duì)滿足跨域訪問(wèn)的WebView對(duì)象定位其頁(yè)面加載API即loadUrl,分析該API參數(shù)變量的引用-定值鏈。如果參數(shù)確定是一個(gè)定值,則認(rèn)為該WebView雖然存在跨域訪問(wèn)漏洞,但是該漏洞不可利用,將其剔除;反之,則記錄下該WebView對(duì)象、跨域訪問(wèn)API和loadUrl API所在的類和函數(shù),以備人工審計(jì)。
(4)控制流分析
控制流分析即進(jìn)行過(guò)程間函數(shù)調(diào)用分析,目的是分析作為攻擊入口的可導(dǎo)出Activity是否存在以類中某個(gè)函數(shù)為起點(diǎn)到WebView對(duì)象loadUrl函數(shù)的調(diào)用路徑。為進(jìn)行可達(dá)性分析,使用反向搜索過(guò)程。在構(gòu)建應(yīng)用調(diào)用圖的基礎(chǔ)上,以API(loadUrl)為起點(diǎn)進(jìn)行深度遍歷。一旦遍歷到的函數(shù)屬于可導(dǎo)出Activity所在類,即停止掃描,且認(rèn)為滿足可達(dá)性要求,判斷通過(guò)該可導(dǎo)出組件存在一條可以執(zhí)行到WebView對(duì)象的loadUrl函數(shù)的路徑。
按照上述檢測(cè)方案,采用Java語(yǔ)言編寫實(shí)現(xiàn)檢測(cè)工具,使用soot[11]框架實(shí)現(xiàn)功能模塊。
在64位Windows系統(tǒng)、CPU為Intel core i7-4790以及內(nèi)存為16 GB的實(shí)驗(yàn)環(huán)境下,在Janus[12]平臺(tái)上選取下載量排行為前300個(gè)Android應(yīng)用進(jìn)行批量檢測(cè),共耗時(shí)約6 h。其中,逆向分析模塊耗時(shí)約為7 800 s,特征定位和數(shù)據(jù)流分析模塊共耗時(shí)約為4 510 s,控制流分析共耗時(shí)約為11 010 s,共檢測(cè)出20個(gè)可疑應(yīng)用。經(jīng)人工確認(rèn),有3個(gè)應(yīng)用滿足應(yīng)用克隆攻擊條件。
以某證券應(yīng)用為例,存在的可導(dǎo)出Activity:**.NewSplashActivity,如圖2所示。
圖2 NewSplashActivity在Android Manifest中的設(shè)置
經(jīng)控制流分析,該Activity會(huì)接收外部URL鏈接并將其傳入給**.WebViewActivity中的WebView組件的loadUrl函數(shù)進(jìn)行加載,且該WebView對(duì)象將 setAllowFileAccess、setJavaScriptEnabled和 setAl lowUniversalAccessFromFileURLs相關(guān)的三個(gè)參數(shù)值設(shè)置為true,說(shuō)明應(yīng)用存在跨域訪問(wèn)漏洞,相關(guān)代碼如圖3所示。
圖3 WebView相關(guān)API設(shè)置
綜合上述分析可判斷,該應(yīng)用存在應(yīng)用克隆攻擊的漏洞。通過(guò)編寫對(duì)應(yīng)的攻擊驗(yàn)證代碼,可進(jìn)一步驗(yàn)證該應(yīng)用可被克隆攻擊。
API設(shè)置不當(dāng)引起的WebView跨域訪問(wèn)漏洞,可能被攻擊者利用進(jìn)行應(yīng)用克隆攻擊。本文通過(guò)分析應(yīng)用克隆攻擊的利用條件,提出了一個(gè)基于抽象語(yǔ)法樹(shù)與數(shù)據(jù)流分析的靜態(tài)檢測(cè)方案,并且基于該方案實(shí)現(xiàn)了一個(gè)自動(dòng)檢測(cè)工具。經(jīng)實(shí)驗(yàn)測(cè)試,該工具能有效檢測(cè)出應(yīng)用是否可被克隆攻擊。但是,該檢測(cè)方案只進(jìn)行過(guò)程內(nèi)的數(shù)據(jù)流分析會(huì)造成一定的誤報(bào),因此后續(xù)將考慮引入過(guò)程間數(shù)據(jù)流分析,以盡可能減少誤報(bào),提高檢測(cè)效率。