蔣煦, 張慧翔, 慕德俊
(西北工業(yè)大學(xué) 自動(dòng)化學(xué)院, 陜西 西安 710072)
一種動(dòng)態(tài)監(jiān)測(cè)安卓應(yīng)用程序的方法
蔣煦, 張慧翔, 慕德俊
(西北工業(yè)大學(xué) 自動(dòng)化學(xué)院, 陜西 西安 710072)
針對(duì)安卓應(yīng)用程序在終端用戶(hù)未知的情況下獲取系統(tǒng)服務(wù)的問(wèn)題,提出了動(dòng)態(tài)監(jiān)測(cè)應(yīng)用程序獲取系統(tǒng)服務(wù)的方法。首先,檢查應(yīng)用程序是否存在第三方庫(kù),如存在,則檢查第三方庫(kù)中是否存在敏感函數(shù)。如果不存在敏感函數(shù),就將應(yīng)用程序安裝到監(jiān)測(cè)系統(tǒng),實(shí)施對(duì)應(yīng)用程序獲取系統(tǒng)服務(wù)的實(shí)時(shí)監(jiān)測(cè)。實(shí)驗(yàn)結(jié)果表明,該方法在能夠避免惡意應(yīng)用程序?qū)ΡO(jiān)測(cè)系統(tǒng)進(jìn)行破壞的前提下,可以實(shí)時(shí)監(jiān)測(cè)到應(yīng)用程序來(lái)自Java層或是本地層對(duì)系統(tǒng)服務(wù)的調(diào)用,而且該方法的實(shí)現(xiàn)對(duì)時(shí)間的開(kāi)銷(xiāo)也在可接受的范圍內(nèi)。
應(yīng)用程序編程接口;網(wǎng)絡(luò)安全;Java語(yǔ)言;實(shí)時(shí)系統(tǒng);數(shù)據(jù)安全;第三方庫(kù);掛鉤子;系統(tǒng)服務(wù)調(diào)用;Linux;安卓應(yīng)用程序;動(dòng)態(tài)監(jiān)測(cè)
隨著移動(dòng)互聯(lián)網(wǎng)的飛速發(fā)展,智能手機(jī)承載著越來(lái)越多的服務(wù)功能。Android系統(tǒng)由于其開(kāi)源的原因,市場(chǎng)占有率穩(wěn)居第一,因此成為了惡意應(yīng)用程序重要的滋生平臺(tái)[1]。
針對(duì)Android惡意應(yīng)用程序的檢測(cè)主要分為靜態(tài)檢測(cè)和動(dòng)態(tài)檢測(cè)。靜態(tài)檢測(cè)是指在不運(yùn)行應(yīng)用程序的情況下,通過(guò)掃描反編譯的應(yīng)用程序代碼,發(fā)現(xiàn)其惡意行為。Felt等[2]從應(yīng)用程序中提取出相關(guān)申請(qǐng)權(quán)限,通過(guò)分析應(yīng)用程序的權(quán)限判斷應(yīng)用程序是否為惡意應(yīng)用程序。CHEX[3]首先通過(guò)識(shí)別應(yīng)用程序中可能被調(diào)用的接口,然后對(duì)這些接口進(jìn)行數(shù)據(jù)流分析,判斷接口是否有可能被惡意應(yīng)用程序利用以達(dá)到提權(quán)的目的。靜態(tài)檢測(cè)方法的優(yōu)點(diǎn)是可以快速地判斷應(yīng)用程序是否存在惡意行為,但無(wú)法應(yīng)對(duì)代碼的混淆、加密、動(dòng)態(tài)加載等情況。
動(dòng)態(tài)檢測(cè)是在應(yīng)用程序執(zhí)行的過(guò)程中實(shí)時(shí)監(jiān)控應(yīng)用程序的行為,一旦發(fā)現(xiàn)惡意行為,立刻提示終端用戶(hù)。TaintDroid[4]對(duì)Android系統(tǒng)應(yīng)用程序框架層進(jìn)行修改,在應(yīng)用程序框架層敏感API的位置插入相應(yīng)的監(jiān)控代碼,起到實(shí)時(shí)監(jiān)控的目的。但這種方法不適合應(yīng)用于實(shí)際使用,因?yàn)閷?duì)相關(guān)的API進(jìn)行修改后需要重新編譯。Aurasium[5]對(duì)應(yīng)用程序的代碼進(jìn)行修改,在敏感API調(diào)用處添加監(jiān)控代碼,從而監(jiān)控應(yīng)用程序的執(zhí)行,雖然該方法無(wú)需對(duì)系統(tǒng)進(jìn)行修改重新編譯,但無(wú)法監(jiān)控應(yīng)用程序的動(dòng)態(tài)加載,需要對(duì)應(yīng)用程序進(jìn)行重新打包簽名,有可能影響應(yīng)用程序的正常執(zhí)行。
無(wú)論采取哪種檢測(cè)方式,都必須要面對(duì)應(yīng)用程序第三方庫(kù)。而目前絕大多數(shù)的檢測(cè)方案集中在Java層,導(dǎo)致惡意應(yīng)用程序的開(kāi)發(fā)者通過(guò)第三方庫(kù)實(shí)現(xiàn)其惡意行為,達(dá)到繞過(guò)Java層檢測(cè)的目的,甚至有可能破壞Java層的安全檢測(cè)系統(tǒng)[6]。所以,對(duì)于Android檢測(cè)系統(tǒng)的研究,應(yīng)用程序第三方庫(kù)的行為檢測(cè)應(yīng)該得到相應(yīng)的重視。
本文在充分研究Android系統(tǒng)Binder機(jī)制及其源碼后,提出了全新的Android系統(tǒng)動(dòng)態(tài)監(jiān)測(cè)方法。首先,檢測(cè)應(yīng)用程序的第三方庫(kù)中是否存在敏感函數(shù)破壞監(jiān)測(cè)系統(tǒng),其次,將應(yīng)用程序安裝到動(dòng)態(tài)鏈接文件libbinder.so中的ioctl函數(shù)被掛鉤子的系統(tǒng)中,監(jiān)測(cè)來(lái)自Java層和Native層對(duì)系統(tǒng)服務(wù)的調(diào)用,實(shí)現(xiàn)動(dòng)態(tài)監(jiān)測(cè)Android應(yīng)用程序。
1.1 Android系統(tǒng)架構(gòu)
Android系統(tǒng)架構(gòu)如圖1所示,分為應(yīng)用層、應(yīng)用程序框架層、本地庫(kù)和Android運(yùn)行時(shí)、Linux內(nèi)核,相關(guān)的定義如下[7]:

圖1 安卓系統(tǒng)架構(gòu)
應(yīng)用層Android平臺(tái)運(yùn)行的應(yīng)用程序,如微信、日歷、地圖等,這些應(yīng)用程序通常使用Java語(yǔ)言編寫(xiě),可以使用Java與本地代碼接口(Java Native Interface, JNI)機(jī)制與本地已經(jīng)編譯的代碼進(jìn)行交互。
應(yīng)用程序框架層為應(yīng)用程序的開(kāi)發(fā)者提供訪問(wèn)核心功能的API框架,該層的應(yīng)用簡(jiǎn)化代碼的編寫(xiě),提高了程序的復(fù)用性。
本地庫(kù)和Android運(yùn)行時(shí)刻Android系統(tǒng)使用了大量的C/C++函數(shù)庫(kù),這些本地庫(kù)通過(guò)應(yīng)用程序框架層對(duì)應(yīng)用程序開(kāi)發(fā)者開(kāi)放。Android運(yùn)行時(shí)包含核心庫(kù)和Dalvik虛擬機(jī)兩部分,核心庫(kù)中提供了Java語(yǔ)言核心庫(kù)中包含的大部分功能和利用JNI封裝的C/C++函數(shù)庫(kù),Dalvik虛擬機(jī)是專(zhuān)門(mén)針對(duì)Android平臺(tái)解釋運(yùn)行Dalvik字節(jié)碼的虛擬機(jī)。
Linux內(nèi)核Android是基于Linux內(nèi)核開(kāi)發(fā)的,依賴(lài)于Linux的系統(tǒng)服務(wù),如內(nèi)存管理,進(jìn)程管理、安全機(jī)制等。Linux內(nèi)核為軟件提供了與硬件的交互。
1.2 Android的安全機(jī)制
Android應(yīng)用程序是作為L(zhǎng)inux進(jìn)程在系統(tǒng)中運(yùn)行,進(jìn)程間相互獨(dú)立不能互相訪問(wèn)資源,即使本地代碼也不能進(jìn)程間互相訪問(wèn),只有使用相同簽名的應(yīng)用程序才可以建立信任關(guān)系、實(shí)現(xiàn)數(shù)據(jù)共享。Android系統(tǒng)服務(wù)也是作為L(zhǎng)inux進(jìn)程在系統(tǒng)中運(yùn)行,如果應(yīng)用程序需要跨進(jìn)程訪問(wèn)系統(tǒng)服務(wù),在沒(méi)有root權(quán)限的前提下,必須獲得相應(yīng)的權(quán)限。Android系統(tǒng)的權(quán)限主要分為2類(lèi):①對(duì)設(shè)備的直接訪問(wèn),Android系統(tǒng)直接使用Linux內(nèi)核提供的用戶(hù)權(quán)限機(jī)制,采用Group IDs(GID)的形式管理該類(lèi)型的權(quán)限,Android系統(tǒng)會(huì)在platform.xml文件中記錄該應(yīng)用程序GID與權(quán)限字符串的對(duì)應(yīng)關(guān)系;②對(duì)設(shè)備或者服務(wù)的間接訪問(wèn)權(quán)限,Android系統(tǒng)采取Binder機(jī)制為應(yīng)用程序提供服務(wù),當(dāng)應(yīng)用程序向提供某服務(wù)的服務(wù)端發(fā)出請(qǐng)求時(shí),該服務(wù)端會(huì)檢查該應(yīng)用程序是否被授予該權(quán)限,如有則提供該服務(wù),反之亦然。
Android系統(tǒng)權(quán)限申請(qǐng)采取“all-or-nothing”的策略,所以應(yīng)用程序可能在用戶(hù)疏忽甚至是不同意的情況下竊取用戶(hù)的隱私信息[8]。
1.3 Binder機(jī)制
Linux內(nèi)核提供了管道、信號(hào)、消息隊(duì)列、共享內(nèi)存等進(jìn)程間通信機(jī)制。Android系統(tǒng)是基于Linux內(nèi)核開(kāi)發(fā)的,而Android系統(tǒng)卻開(kāi)發(fā)了一套新的進(jìn)程間通信機(jī)制Binder。Binder進(jìn)程間通信機(jī)制是在OpenBinder的基礎(chǔ)上實(shí)現(xiàn)的,采用CS通信方式,其中,提供服務(wù)的進(jìn)程成為Server進(jìn)程,訪問(wèn)服務(wù)的進(jìn)程稱(chēng)為Client進(jìn)程。Server進(jìn)程和Client進(jìn)程的通信都要依靠運(yùn)行在內(nèi)核空間的Binder驅(qū)動(dòng)程序來(lái)進(jìn)行,Binder驅(qū)動(dòng)程序向用戶(hù)控件提供一個(gè)設(shè)備文件/dev/binder,使得應(yīng)用程序進(jìn)程可以間接地通過(guò)它來(lái)建立通信通道。Service組件在啟動(dòng)時(shí),會(huì)將自己注冊(cè)到一個(gè)Service Manager組件中,為了讓Client組件可以通過(guò)Service Manager組件找到該服務(wù)。Binder驅(qū)動(dòng)程序、Service、client、Service-Manager的關(guān)系如圖2所示。Binder進(jìn)程間通信機(jī)制的代碼是由C/C++實(shí)現(xiàn)的,Android系統(tǒng)在應(yīng)用程序框架層中提供了Binder進(jìn)程間通信機(jī)制的Java接口,Java層通過(guò)使用JNI的方法來(lái)調(diào)用Binder庫(kù)的C/C++接口[9]。

圖2 Binder機(jī)制
1.4 動(dòng)態(tài)鏈接加載機(jī)制
動(dòng)態(tài)鏈接是把程序按照模塊拆分成各個(gè)相對(duì)獨(dú)立的組成部分,在應(yīng)用程序運(yùn)行時(shí)才將各部分鏈接在一起,形成一個(gè)完整的應(yīng)用程序。程序在運(yùn)行時(shí)會(huì)檢查所依賴(lài)的目標(biāo)文件是否在內(nèi)存中,如果不在,則將目標(biāo)文件拷貝至內(nèi)存,隨后進(jìn)行鏈接工作,包括對(duì)符號(hào)的解析和地址重定位,所以動(dòng)態(tài)鏈接可以很好地解決空間浪費(fèi)和應(yīng)用程序更新的問(wèn)題[10]。動(dòng)態(tài)鏈接文件被稱(chēng)為動(dòng)態(tài)共享對(duì)象(Dynamic Shared Objects,DSO),簡(jiǎn)稱(chēng)共享對(duì)象,以".so"作為文件的擴(kuò)展名。
Android系統(tǒng)中,Bionic是Android系統(tǒng)C/ C++庫(kù),Bionic庫(kù)實(shí)現(xiàn)了對(duì)系統(tǒng)調(diào)用的封裝,庫(kù)中的API與系統(tǒng)調(diào)用相對(duì)應(yīng),其中有部分API需要多次調(diào)用系統(tǒng)調(diào)用實(shí)現(xiàn)API功能。Bionic庫(kù)的動(dòng)態(tài)鏈接文件保存在系統(tǒng)lib目錄下,文件名叫“l(fā)ibc.so”。整個(gè)And-roid系統(tǒng)只保留一份“l(fā)ibc.so”,當(dāng)應(yīng)用程序被裝載到系統(tǒng)時(shí),系統(tǒng)的動(dòng)態(tài)鏈接器會(huì)將應(yīng)用程序所需要的libc.so裝載到進(jìn)程的地址空間,并進(jìn)行重定位工作。
如圖2所示,ServiceManager是Android系統(tǒng)的服務(wù)管理器,遠(yuǎn)程服務(wù)對(duì)象都是以Binder的形式存在,而ServiceManager是遠(yuǎn)程服務(wù)對(duì)象的管理者。應(yīng)用程序在申請(qǐng)獲得系統(tǒng)服務(wù)時(shí),必須通過(guò)Servic-eManager獲取服務(wù)的索引號(hào),通過(guò)索引號(hào),應(yīng)用程序建立與該系統(tǒng)服務(wù)的通訊。
在應(yīng)用程序獲取系統(tǒng)服務(wù)的過(guò)程中,應(yīng)用程序需要先打開(kāi)設(shè)備文件/dev/binder,通過(guò)IO控制函數(shù)ioctl與Binder驅(qū)動(dòng)程序進(jìn)行交互,因此Binder驅(qū)動(dòng)文件提供了一系列的IO控制命令來(lái)和應(yīng)用程序進(jìn)程通信。在這些IO命令中,最重要的是BINDER-WRITE-READ命令,命令參數(shù)binder-write-read,它是用來(lái)描述進(jìn)程間通信過(guò)程中所傳輸?shù)臄?shù)據(jù),包括輸入、輸出數(shù)據(jù),它的結(jié)構(gòu)體如Code 1所示,其中write-buffer和read-buffer都是數(shù)組,數(shù)組中的每一個(gè)元素都是由通信協(xié)議代碼和通信數(shù)據(jù)組成。協(xié)議代碼在write-buffer中被稱(chēng)為命令協(xié)議代碼,在read-buffer中被稱(chēng)為返回協(xié)議代碼。在命令和返回的協(xié)議代碼中,最重要的協(xié)議代碼是BC-TRANS-ACTION和BC-REPLY。
在命令協(xié)議代碼中,當(dāng)一個(gè)進(jìn)程請(qǐng)求另一個(gè)進(jìn)程執(zhí)行某一操作時(shí),源進(jìn)程就使用命令協(xié)議代碼BC-TRANSACTION來(lái)請(qǐng)求Binder驅(qū)動(dòng)程序?qū)⑼ㄐ艛?shù)據(jù)傳遞到目標(biāo)進(jìn)程,當(dāng)目標(biāo)進(jìn)程處理完成源進(jìn)程所請(qǐng)求的操作之后,就使用命令協(xié)議代碼BC_REPLY來(lái)請(qǐng)求Binder驅(qū)動(dòng)程序?qū)⒔Y(jié)果數(shù)據(jù)傳遞給源進(jìn)程。Code 1
struct binder-write-read {
signed long write-size; /* bytes to write */
signed long write-consumed; /* bytes consumed by driver */
unsigned long write-buffer;
signed long read-size; /* bytes to read */
signed long read-consumed; /* bytes consumed by driver */
unsigned long read-buffer;
}
在返回協(xié)議代碼中,當(dāng)一個(gè)Client進(jìn)程向一個(gè)Server進(jìn)程發(fā)出進(jìn)程間通信請(qǐng)求時(shí),Binder驅(qū)動(dòng)程序會(huì)使用返回協(xié)議代碼BC-TRANSACTION通知該Server進(jìn)程來(lái)處理該進(jìn)程間通信請(qǐng)求,當(dāng)Server進(jìn)程處理完該Client進(jìn)程通信請(qǐng)求后,Binder驅(qū)動(dòng)程序會(huì)使用返回協(xié)議代碼BC-REPLY將進(jìn)程間通信請(qǐng)求結(jié)果數(shù)據(jù)返回給Client進(jìn)程[11]。
本文的監(jiān)測(cè)系統(tǒng)主要分為2部分,第一部分主要是檢查應(yīng)用程序的第三方庫(kù)中是否存在敏感函數(shù),第二部分是將通過(guò)第一部分檢測(cè)的應(yīng)用程序載入系統(tǒng)調(diào)用ioctl被hook的系統(tǒng)中,進(jìn)行動(dòng)態(tài)監(jiān)測(cè)。
3.1 針對(duì)第三方庫(kù)的檢測(cè)
用戶(hù)對(duì)Android應(yīng)用程序的使用體驗(yàn)要求越來(lái)越高,應(yīng)用程序的開(kāi)發(fā)者僅僅使用Android SDK編寫(xiě)應(yīng)用程序已經(jīng)不能滿足用戶(hù)的需求,比如3D游戲的呈現(xiàn),涉及到CPU的高性能運(yùn)算等。所以,應(yīng)用程序的開(kāi)發(fā)者越來(lái)越多地使用本地語(yǔ)言開(kāi)發(fā)工具(native development kit,NDK)來(lái)編寫(xiě)應(yīng)用程序native部分的代碼和移植C/C++語(yǔ)言開(kāi)發(fā)的程序來(lái)節(jié)省開(kāi)發(fā)的時(shí)間和成本。
第三方庫(kù)應(yīng)用的普及也帶來(lái)了潛在的安全風(fēng)險(xiǎn):①應(yīng)用程序一旦被授予申請(qǐng)的權(quán)限,那么應(yīng)用程序無(wú)論Java層還是native層都獲得了相同的權(quán)限,即意味著通過(guò)native代碼可以通過(guò)JNI機(jī)制調(diào)用應(yīng)用程序框架層API獲得系統(tǒng)資源,甚至可以直接調(diào)用系統(tǒng)服務(wù)的C/C++接口。flexdroid[12]指出在含有第三方庫(kù)的應(yīng)用程序中,50%的第三方庫(kù)與廣告有關(guān),其中不少第三方庫(kù)在執(zhí)行過(guò)程中設(shè)法獲取用戶(hù)的隱私信息。 ②應(yīng)用程序Java層和Native層共處于一個(gè)獨(dú)立的虛擬空間內(nèi),所以惡意應(yīng)用程序的第三方庫(kù)可以通過(guò)操縱native代碼修改進(jìn)程內(nèi)虛擬內(nèi)存的屬性,寫(xiě)入相應(yīng)的數(shù)據(jù),執(zhí)行惡意的行為。
Google[13]關(guān)于NDK的官方說(shuō)明指出native代碼應(yīng)該僅僅被用于執(zhí)行CPU-intensive的操作,所以如果應(yīng)用程序的開(kāi)發(fā)者通過(guò)native代碼去獲取系統(tǒng)資源,甚至修改內(nèi)存數(shù)據(jù),顯然都是違背Android系統(tǒng)NDK的初衷。許多研究者對(duì)應(yīng)用程序第三方庫(kù)進(jìn)行了深入的研究,Appcage[14]采取對(duì)應(yīng)用程序第三方庫(kù)進(jìn)行二次編寫(xiě)的方法,將Java層的代碼和Native層的代碼分開(kāi),分別在各自的沙箱中運(yùn)行。NativeGuard[6]采取Android接口定義語(yǔ)言(android interface definition language,AIDL)的方法將應(yīng)用程序的第三方庫(kù)運(yùn)行在另一個(gè)進(jìn)程,為了第三方庫(kù)獲得的權(quán)限從應(yīng)用程序的權(quán)限中脫離,使得第三方庫(kù)只能執(zhí)行CPU-intensive的操作。上述的研究成果都可以有效地限制應(yīng)用程序第三方庫(kù)的行為,但在時(shí)間開(kāi)銷(xiāo)、空間開(kāi)銷(xiāo)和有效性方面還有欠缺。
同時(shí),在文件映射的過(guò)程中,系統(tǒng)調(diào)用mmap指定不同內(nèi)存區(qū)域擁有不同的屬性,但應(yīng)用程序仍然可以通過(guò)native代碼執(zhí)行系統(tǒng)調(diào)用mprotect修改內(nèi)存區(qū)域的讀、寫(xiě)、執(zhí)行屬性[10]。例如,代碼區(qū)的默認(rèn)屬性是只讀,意味著任何代碼都不能修改該區(qū)域的數(shù)據(jù),但是惡意應(yīng)用程序的native代碼可以通過(guò)執(zhí)行系統(tǒng)調(diào)用mprotect來(lái)改變代碼區(qū)的屬性由只讀變?yōu)榭勺x寫(xiě),對(duì)代碼進(jìn)行修改,執(zhí)行惡意行為。本文監(jiān)測(cè)系統(tǒng)的目的是能夠?qū)崟r(shí)監(jiān)測(cè)到來(lái)自Java層和native層對(duì)系統(tǒng)服務(wù)的調(diào)用,所以本文的監(jiān)測(cè)系統(tǒng)并沒(méi)有限制第三方庫(kù)的權(quán)限,但是禁止應(yīng)用程序的native代碼執(zhí)行系統(tǒng)調(diào)用mprotect,如第三方庫(kù)中存在mprotect函數(shù),就直接將其判定為惡意應(yīng)用程序,不納入動(dòng)態(tài)監(jiān)測(cè)的范圍。
3.2 hook對(duì)象的選取
hook是一種消息處理機(jī)制,也是處理消息的程序段,通過(guò)系統(tǒng)調(diào)用將此程序段載入系統(tǒng),每當(dāng)有特定消息發(fā)出時(shí),在沒(méi)有到達(dá)目標(biāo)地址前,hook程序就已經(jīng)得到該消息,獲得了程序的控制權(quán),可以對(duì)消息進(jìn)行相應(yīng)處理[14]。
Binder進(jìn)程間通信機(jī)制是由C/C++代碼實(shí)現(xiàn)的,Android系統(tǒng)在應(yīng)用程序框架層中提供Binder進(jìn)程間通信機(jī)制的Java接口,所以應(yīng)用程序Java層的代碼可以通過(guò)JNI機(jī)制來(lái)調(diào)用Binder的C/C++接口,實(shí)現(xiàn)進(jìn)程間的通訊。部分惡意應(yīng)用程序直接通過(guò)與Binder的C/C++接口通訊來(lái)獲取系統(tǒng)服務(wù),繞過(guò)Java層對(duì)應(yīng)用程序框架層敏感API檢測(cè)。無(wú)論是來(lái)自Java層還是Native層對(duì)系統(tǒng)服務(wù)的調(diào)用,歸根結(jié)底是需要調(diào)用ioctl函數(shù),所以本文選取了“l(fā)ibbinder.so”中的ioctl函數(shù)進(jìn)行hook,既可以實(shí)時(shí)監(jiān)測(cè)到通過(guò)應(yīng)用程序架構(gòu)層API獲取系統(tǒng)服務(wù)的行為,也可以監(jiān)測(cè)到通過(guò)native代碼獲取系統(tǒng)服務(wù)的行為[15]。
無(wú)論在命令協(xié)議代碼還是在返回協(xié)議代碼中,BC-TRANSACTION和BC-REPLY的通訊數(shù)據(jù)是使用binder-transaction-data來(lái)描述,結(jié)構(gòu)體如Code 2所示,成員變量sender-pid和sender-euid表示發(fā)起進(jìn)程間通信請(qǐng)求進(jìn)程的PID和UID,目標(biāo)進(jìn)程通過(guò)這2個(gè)成員變量就可以識(shí)別出client進(jìn)程是否有權(quán)限訪問(wèn)。
Code 2
struct binder-transaction-data{
union{
size-t handle;
void *ptr
}target;
void *cookie;
unsigned int code;
unsigned int flags;
pid-t sender-pid;
uid-t sender-euid;
size-t data-size;
union{
struct{
const void *buffer;
const void *offsets;
}ptr;
uint8-t buf[8];
}data;};
而上述的命令都需要使用IO控制函數(shù)ioctl,所以本文將所需要實(shí)現(xiàn)的代碼注入libbinder.so中,新建一個(gè)ioctl來(lái)替換舊的ioctl,當(dāng)執(zhí)行完注入代碼后,再將指針交還給原ioctl,偽代碼如Code 3所示。
Code 3
int new-icotl (int-fd, unsigned long int-request, void *arg)
{
if(-request = =BINDER-WRITE-READ)
{
根據(jù)命令獲取傳輸方向、類(lèi)型、類(lèi)型命令、傳輸數(shù)據(jù)大小
if(write-size>0)
{將write-buffer中的數(shù)據(jù)寫(xiě)入到Binder}
while(already-got-size {循環(huán)處理buffer中的每一個(gè)命令} if(read-size>0) {從Binder中讀取數(shù)據(jù)寫(xiě)入到read-buffer} while(already-got-size {循環(huán)處理buffer中的每一個(gè)命令,獲取PID和申請(qǐng)的service的信息} int res=(*old-ioctl) (-fd,-request,arg); return res; } 3.3 IPC數(shù)據(jù)的解析 ServiceManager是Android系統(tǒng)的服務(wù)管理器,遠(yuǎn)程服務(wù)對(duì)象都是以Binder的形式存在,而它們的共同管理者是ServiceManager。應(yīng)用程序在申請(qǐng)獲得系統(tǒng)服務(wù)時(shí),必須通過(guò)ServiceManager獲取服務(wù)的索引號(hào)[16]。鄭勇鑫[17]通過(guò)對(duì)SerciceManager中涉及敏感權(quán)限的系統(tǒng)服務(wù)進(jìn)行掛鉤子,得到應(yīng)用程序獲取涉及敏感權(quán)限的系統(tǒng)服務(wù)信息。這種方法能監(jiān)控到應(yīng)用程序獲取被監(jiān)測(cè)系統(tǒng)掛鉤子的系統(tǒng)服務(wù),但不能獲知應(yīng)用程序調(diào)用的所有系統(tǒng)服務(wù)。 結(jié)構(gòu)體binder-transaction-data的ptr成員變量buffer指向一個(gè)數(shù)據(jù)緩沖區(qū),這個(gè)緩沖區(qū)是用來(lái)保存通信數(shù)據(jù)的,它的大小由成員變量data-size決定。本文通過(guò)對(duì)ioctl函數(shù)掛鉤子,將binder-transaction-data的ptr成員變量所指的data-size大小的數(shù)據(jù)緩沖區(qū)中的內(nèi)容轉(zhuǎn)化為16進(jìn)制表達(dá) ,系統(tǒng)服務(wù)的名稱(chēng)是由大小寫(xiě)字母和點(diǎn)號(hào)組成,通過(guò)增加判斷語(yǔ)句if(((*data >= 65) && (*data<=90))‖((*data >= 97)&&(*data<=122))‖(*data==46))可以獲知應(yīng)用程序意圖獲取的所有系統(tǒng)服務(wù)名稱(chēng)。 4.1 實(shí)驗(yàn)環(huán)境與實(shí)驗(yàn)樣本 本文所有實(shí)驗(yàn)在內(nèi)存為8G,處理器為Intel(R)Core(TM)i5-3337U 1.80GHzPC控制器和Android OS 4.3,內(nèi)存1G,處理器1.2GHz的酷派8720L型號(hào)手機(jī)終端完成。 4.2 實(shí)驗(yàn)組成 1) 本文從Google Play應(yīng)用市場(chǎng)下載了下載排名前10的應(yīng)用程序,動(dòng)態(tài)監(jiān)測(cè)應(yīng)用程序的運(yùn)行,檢查是否能夠監(jiān)測(cè)到與應(yīng)用程序申請(qǐng)權(quán)限相關(guān)的系統(tǒng)服務(wù)。 2) 本文自編native層系統(tǒng)服務(wù),使用應(yīng)用程序第三方庫(kù)利用native代碼獲取系統(tǒng)服務(wù),用來(lái)檢測(cè)hook的ioctl函數(shù)是否能夠監(jiān)測(cè)到應(yīng)用程序直接與Binder驅(qū)動(dòng)通訊獲取系統(tǒng)服務(wù)的行為。 3) 通過(guò)對(duì)比hook前后應(yīng)用程序啟動(dòng)、系統(tǒng)服務(wù)執(zhí)行的時(shí)間,證明對(duì)ioctl函數(shù)掛鉤子對(duì)時(shí)間開(kāi)銷(xiāo)的增加微乎其微。 4.3 實(shí)驗(yàn)評(píng)估 本文首先對(duì)待檢測(cè)應(yīng)用程序中存在的第三方庫(kù),使用Android NDK中readelf命令進(jìn)行反匯編,在反匯編出的文件中存在動(dòng)態(tài)鏈接重定位表,分別是“rel.dyn”和“rel.plt”,其中“rel.dyn”是對(duì)數(shù)據(jù)引用的地址重定位,所修正的位置位于.got段以及數(shù)據(jù)段;“rel.plt”是對(duì)函數(shù)引用的地址重定位,所修正的位置位于“.got.plt”段。如果在“.got.plt”段中發(fā)現(xiàn)第三方庫(kù)中存在調(diào)用系統(tǒng)函數(shù)mprotect時(shí),就判定該應(yīng)用程序存在惡意行為的可能,不將其列入動(dòng)態(tài)監(jiān)測(cè)的范圍。 4.3.1 可用性驗(yàn)證 本文的檢測(cè)系統(tǒng)是為了動(dòng)態(tài)地監(jiān)測(cè)應(yīng)用程序?qū)ndroid系統(tǒng)服務(wù)的調(diào)用,而調(diào)用這些系統(tǒng)服務(wù)需要向Android系統(tǒng)申請(qǐng)相應(yīng)的權(quán)限。 表1 監(jiān)測(cè)結(jié)果 Monkey工具是利用socket通訊的方式模擬用戶(hù)的按鍵輸入、觸摸屏輸入、手勢(shì)輸入等。本文監(jiān)測(cè)系統(tǒng)利用Monkey工具對(duì)從Google Play應(yīng)用市場(chǎng)下載的10個(gè)應(yīng)用程序進(jìn)行自動(dòng)化的隨機(jī)測(cè)試,能夠?qū)崟r(shí)監(jiān)測(cè)到與應(yīng)用程序申請(qǐng)權(quán)限相關(guān)的系統(tǒng)服務(wù)調(diào)用。以Wifi萬(wàn)能鑰匙和百度糯米為例,從表1可以看出,本文監(jiān)測(cè)系統(tǒng)能夠?qū)崟r(shí)監(jiān)測(cè)到應(yīng)用程序通過(guò)Binder機(jī)制調(diào)用系統(tǒng)服務(wù)的情況,但無(wú)法監(jiān)測(cè)到獲取訪問(wèn)設(shè)備權(quán)限后直接訪問(wèn)設(shè)備的情況,因?yàn)橹苯釉L問(wèn)設(shè)備是不需要通過(guò)Binder機(jī)制的,同時(shí)直接訪問(wèn)硬件設(shè)備的監(jiān)控可以通過(guò)對(duì)系統(tǒng)Java層敏感API的監(jiān)測(cè)實(shí)現(xiàn),這部分不是本文的重點(diǎn)。 4.3.2 功能測(cè)試 應(yīng)用程序獲得申請(qǐng)的權(quán)限后,其第三方庫(kù)也獲取了相應(yīng)的權(quán)限,意味著native代碼可以直接通過(guò)調(diào)用Binder的本地接口獲取到受保護(hù)的系統(tǒng)服務(wù)。雖然目前Google還未公開(kāi)Android系統(tǒng)系統(tǒng)服務(wù)的本地接口,但如果存在本地接口并被惡意應(yīng)用程序的開(kāi)發(fā)者掌握,那么在Java層對(duì)系統(tǒng)服務(wù)調(diào)用的監(jiān)測(cè)將全部失效。隨著Android系統(tǒng)需求越來(lái)越高,native service應(yīng)用也越來(lái)越多。 本文在充分研究Binder機(jī)制的基礎(chǔ)上,編寫(xiě)了native層的系統(tǒng)服務(wù)。應(yīng)用程序通過(guò)第三方庫(kù)去獲取本文自定義的系統(tǒng)服務(wù),該第三方庫(kù)未使用JNI機(jī)制從native層去調(diào)用應(yīng)用程序框架層的API獲取系統(tǒng)服務(wù),而是直接調(diào)用自定義的系統(tǒng)服務(wù)本地接口去獲取系統(tǒng)服務(wù)。同理,如果存在原生系統(tǒng)服務(wù)的本地接口,應(yīng)用程序也可以通過(guò)native代碼調(diào)用系統(tǒng)服務(wù)。 在終端運(yùn)行該應(yīng)用程序,本文監(jiān)測(cè)系統(tǒng)能夠成功地監(jiān)測(cè)到應(yīng)用程序使用第三方庫(kù)直接與Binder驅(qū)動(dòng)通訊調(diào)用系統(tǒng)服務(wù),說(shuō)明了應(yīng)用程序獲取相應(yīng)的權(quán)限后,通過(guò)native代碼直接與Binder驅(qū)動(dòng)本地接口進(jìn)行交互是可以獲得受保護(hù)的系統(tǒng)服務(wù)。同時(shí),也說(shuō)明針對(duì)Android的監(jiān)測(cè)系統(tǒng)如果將監(jiān)測(cè)點(diǎn)僅僅放在Java層進(jìn)行監(jiān)測(cè)應(yīng)用程序獲取的系統(tǒng)服務(wù)是存在潛在風(fēng)險(xiǎn)的,Java層的檢測(cè)完全可能被惡意應(yīng)用程序通過(guò)第三方庫(kù)與Binder驅(qū)動(dòng)本地接口直接交互而繞過(guò)。 4.3.3 性能評(píng)估 Android系統(tǒng)除了從界面上啟動(dòng)程序之外,還可以使用命令行工具啟動(dòng)應(yīng)用程序。本文使用am start-W package name/ activity name的命令啟動(dòng)應(yīng)用程序,對(duì)比hook前和hook后應(yīng)用程序啟動(dòng)的時(shí)間消耗,以Wifi萬(wàn)能鑰匙和百度糯米為例,結(jié)果如表2所示,hook前后啟動(dòng)時(shí)間的值是取進(jìn)行了50次實(shí)驗(yàn)的平均值。從表2可以看出,監(jiān)測(cè)系統(tǒng)ioctl函數(shù)hook后并未明顯增加應(yīng)用程序啟動(dòng)時(shí)間的開(kāi)銷(xiāo)。 表2 hook前后應(yīng)用程序的啟動(dòng)時(shí)間 最后,本文自編應(yīng)用程序,在應(yīng)用程序中調(diào)用應(yīng)用程序框架層API來(lái)獲取系統(tǒng)資源,通過(guò)在應(yīng)用程序框架層API代碼前后插入計(jì)時(shí)代碼(以getDeviceId為例,如Code 4所示),計(jì)算ioctl函數(shù)被hook前后獲取系統(tǒng)服務(wù)所需的時(shí)間,結(jié)果如表3所示,hook前后完成系統(tǒng)服務(wù)的用時(shí)也是取50次實(shí)驗(yàn)的平均值。 Code 4 Long start = System.currentTimeMillis(); TelephonyManager telephonemanage=(TelephonyManager) getSystemService(Context.TELEPHONY-SERVICE); System.out.println(“串號(hào):”+telephonemanage.getDeviceId()); long end=System.currentTimeMillis(); System.out.println(“運(yùn)行時(shí)間:”+(end-start)+“毫秒”); 從表3可以看出,hook前后對(duì)應(yīng)用程序跨進(jìn)程調(diào)用系統(tǒng)服務(wù)獲取系統(tǒng)資源所需時(shí)間影響不大。 表3 hook前后系統(tǒng)服務(wù)執(zhí)行的時(shí)間 本文動(dòng)態(tài)監(jiān)測(cè)系統(tǒng)通過(guò)對(duì)libbinder.so中ioctl函數(shù)掛鉤子的方法,能夠有效、實(shí)時(shí)地監(jiān)控應(yīng)用程序通過(guò)應(yīng)用程序框架層API或是通過(guò)native層直接與Binder驅(qū)動(dòng)本地接口進(jìn)行交互獲取系統(tǒng)服務(wù)的行為。同時(shí)該方法對(duì)應(yīng)用程序的啟動(dòng)時(shí)間、應(yīng)用框架層API調(diào)用的時(shí)間開(kāi)銷(xiāo)影響較小。應(yīng)用程序載入監(jiān)控系統(tǒng)前第三方庫(kù)的檢測(cè)確保了應(yīng)用程序第三方庫(kù)無(wú)法對(duì)本文監(jiān)測(cè)系統(tǒng)構(gòu)成威脅,具有實(shí)際應(yīng)用的價(jià)值。 下一步的研究重點(diǎn)是如何監(jiān)測(cè)應(yīng)用程序通過(guò)第三方庫(kù)打開(kāi)設(shè)備文件;其次對(duì)部分系統(tǒng)服務(wù)進(jìn)行更加細(xì)粒度的監(jiān)測(cè),力爭(zhēng)將動(dòng)態(tài)監(jiān)測(cè)系統(tǒng)做的更加完善。 [1] 許鋁才,張?jiān)?楊珉. SysTracker:一種采用系統(tǒng)調(diào)用監(jiān)測(cè)安卓應(yīng)用資源使用的方法[J]. 計(jì)算機(jī)應(yīng)用與軟件,2014,31(10): 244-250 Xu Lücai, Zhang Yuan, Yang Min. Systracker: A System Call-Based Re-Sourses Usage Monitoring Technique for Android Applications[J]. Computer Applications and Software, 2014, 31(10): 244-250 (in Chinese) [2] Felt A P, Chin E, Hanna S, et a1. Android Permissions Demystified[C]∥Proceedingsof the 18th ACM Conference on Computer and Communications Security, New York, ACM, 2011: 627-638 [3] Lu L, Li Z, Wu Z, et al. Chex: Statically Vetting Android Apps for Component Hijacking Vulnerabilities[C]∥Proceedings of ACM Conference on Computer and Communications Security, New York:ACM, 2012 [4] Enck W, Ongtang M, McDaniel. On Lightweight Mobile Phone Application Certication[C]∥Proceedings of the 2009 ACM Conterence on Computer and Communications Secutity, 2009: 24-41 [5] Xu R, Sa?di H, Anderson R. Aurasium: Practical Policy Enforcement for Android Applications[C]∥Proceedings of the 21st USENIX Conference on Security Symposium, 2012:27-27 [6] Sun M, Tan G. NativeGuard: Protecting Android Applications from Third-Party Native Libraries[C]∥Proceedings of the 2014 ACM Conference on Security and Privacy in Wireless & Mobile Networks, 2014:165-176 [7] 張玉清, 王凱, 楊歡,等. Android安全綜述[J]. 計(jì)算機(jī)研究與發(fā)展, 2014, 51(7):1385-1396 Zhang Yuqing, Wang Kai, Yang Huan, et al. Survey of Android OS Security[J]. Journal of Computer Research and Development, 2014, 51(7): 1385-1396 (in Chinese) [8] Yan L K, Yin H. DroidScope: Seamlessly Reconstructing the OS and Dalvik Semantic Views for Dynamic Android Malware Analysis[C]∥Proceedings of the 21st USENIX Conference on Security Symposium, 2012: 29-29 [9] Enck W, Octeau D, Mcdaniel P, et al. A Study of Android Application Security[C]∥Usenix Conference on Security, 2011:1175-1175 [10] 俞甲子,石凡,潘愛(ài)民. 程序員的自我修養(yǎng)[M]. 北京:電子工業(yè)出版社, 2009 Yu Jiazi, Shi Fan, Pan Aimin. Programmer′s Self-Improvement[M]. Beijing, Publishing House of Electronics Industry, 2009 (in Chinese) [11] 羅升陽(yáng). Android系統(tǒng)源代碼情景分析[M]. 北京:電子工業(yè)出版社, 2012 Luo Shengyang. Android Source Code Scenario Analysis[M]. Beijing, Publishing House of Electronics Industry, 2012 (in Chinese) [12] Seo J, Kim D, Cho D, et al. Flexdroid: Enforcing In-App Privilege Separation in Android[C]∥Proceedings of the 2016 Annual Network and Distributed System Security Symposium, CA, 2016 [13] Google. Android ndk[EB/OL]. (2012-09-02)http:// developer. android. com/ tools/sdk/ ndk/ index. html [14] 華保健, 周艾亭, 朱洪軍. Android內(nèi)核鉤子的混合檢測(cè)技術(shù)[J]. 計(jì)算機(jī)應(yīng)用, 2014, 34(11):3336-3339 Hua Baojian, Zhou Aiting, Zhu Hongjun. Hybrid Detection Technique for Android Kernel Hook[J]. Computer Applications, 2014, 34(11): 3336-3343 (in Chinese) [15] Zhou Y, Patel K, Wu L, et al. Hybrid User-Level Sandboxing of Third-Party Android Apps[C]∥Proceedings of the 10th ACM Symposium on Information, Computer and Communication Security, 2015: 19-30 [16] 金泰延,宋享周,樸知?jiǎng)?等. Android框架揭秘[M]. 北京:人民郵電出版社, 2012 Jin Taiyan, Song Xiangzhou, Piao Zhixun, et al. Inside the Android Framework[M]. Beijing, Post & Telecom Press, 2012 (in Chinese) [17] 鄭勇鑫. Android動(dòng)態(tài)監(jiān)控系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn)[D]. 南京:東南大學(xué), 2014 Zheng Yongxin. Design and Implementation of Dynamic Monitoring System for Android[D]. Nanjing, Southeast University, 2014 (in Chinese) A Method for Dynamically Monitoring Android Applications Jiang Xu, Zhang Huixiang, Mu Dejun School of Automation, Northwestern Polytechnical University, Xi′an 710072, China In order for Android application to acquire system service without knowing their terminal user, we proposed the dynamic monitoring method. First, we monitor whether the Android applications have the third libraries; if yes, we monitor whether the third libraries have sensitive function. If the sensitive function do not exist, the Android applications are installed into a certain Android system whose call function has been hooked, thus monitoring in real time the applications' acquisition of system services. The experimental results show that the dynamic monitoring method can monitor the applications' acquisition of their system services called by both the Java layer and the local layer under the precondition that the damage to the monitoring system by an ill-intentioned application can be avoided. Besides, the overhead of the dynamic monitoring method for Android applications is acceptable. application programming interface (API); network security; Java programming language; real time systems; security of data; third libraries; hook; system service call; Linux; Android application; dynamic monitoring 2016-08-26 國(guó)家自然科學(xué)基金(61672433)資助 蔣煦(1983—),西北工業(yè)大學(xué)博士研究生,主要從事Android系統(tǒng)安全及大數(shù)據(jù)挖掘研究。 TP309 A 1000-2758(2016)06-1074-084 實(shí)驗(yàn)與評(píng)估



5 結(jié) 論