陳純,周安民
(四川大學電子信息學院信安所,成都610065)
Android是一種基于Linux的、開放源代碼的操作系統(tǒng),主要適合移動設(shè)備,如智能手機和平板電腦等,Android操作系統(tǒng)最初由Andy Rubin開發(fā),主要支持手機,2005年8月由Google收購[1]。在網(wǎng)絡(luò)技術(shù)迅猛發(fā)展的今天,各種移動設(shè)備如春后竹筍般增長,現(xiàn)在移動設(shè)備的使用頻率已經(jīng)超過PC端。Android系統(tǒng)的快速發(fā)展,不同功能Android應(yīng)用也越來越多,形形色色的應(yīng)用豐富了人們的生活,也給人們的生活帶來了便捷的同時也產(chǎn)生了弊端,由于復(fù)雜的網(wǎng)絡(luò)環(huán)境,Android系統(tǒng)中產(chǎn)生了大量的安全漏洞,從而造成了各種信息泄露、惡意扣費、系統(tǒng)破壞等各種現(xiàn)象,而漏洞的產(chǎn)生,主要是由于開發(fā)人員的安全意識淡薄,在程序設(shè)計當中存在的缺陷,或者在開發(fā)過程中對沒有對輸入做校驗,因此設(shè)計一款檢測Android應(yīng)用漏洞是很有必要的。
Android整體構(gòu)架[2]主要包括應(yīng)用層、應(yīng)用程序框架、核心庫與運行環(huán)境層、Linux內(nèi)核層。
(1)應(yīng)用層
應(yīng)用層幾乎運行所有的應(yīng)用程序。應(yīng)用程序不僅包括Android系統(tǒng)自帶的應(yīng)用,例如主屏幕(Home)、聯(lián)系人(Contact)、電話(Phone)、瀏覽器(Browsers)等,還包括用戶自定義開發(fā)的應(yīng)用程序,應(yīng)用層的應(yīng)用程序是直接和用戶進行交互的,并最終運行在Dalvik虛擬機中。
(2)應(yīng)用框架層
應(yīng)用框架層主要為應(yīng)用層的開發(fā)者提供API,本層包含了UI程序中所需要的各種控件,包括:豐富而又可擴展的視圖、內(nèi)容提供器、資源管理器、通知管理器、活動管理器等。
(3)核心庫與運行環(huán)境層
本層次對應(yīng)一般嵌入式系統(tǒng),相當于中間件層次,分為各種庫和Android運行環(huán)境兩個部分,包括C庫、多媒體框架、SGL、SSL、OpenGL SE、界面管理工具、SQLite、WebKit、FreeType 等。
(4)Linux內(nèi)核層
該層位于最底層,作為硬件層和軟件層交互的層,提供了與Android設(shè)備相關(guān)的驅(qū)動程序,例如顯示驅(qū)動、Flash內(nèi)存驅(qū)動、照相機驅(qū)動、音頻驅(qū)動、Wi-Fi驅(qū)動、藍牙驅(qū)動等。
Android有四種不同類型與功能的組件[2],它們分別是活動(Activity)、服務(wù)(Service)、廣播接收器(Broadcast Receiver)、內(nèi)容提供者(Content Provider)。
(1)活動是android應(yīng)用程序的表現(xiàn)層,展現(xiàn)為一個可視化的用戶界面,是用戶與程序進行交互的組件,存在著活動、暫停、停止、銷毀四種狀態(tài)。
(2)服務(wù)是運行在操作系統(tǒng)后臺、無用戶界面的一種組件,Service通常被用來執(zhí)行不需要用戶干涉的操作。
(3)內(nèi)容提供器是Android系統(tǒng)提供的一種應(yīng)用程序數(shù)據(jù)共享機制,可以在多個應(yīng)用程序中實現(xiàn)存儲數(shù)據(jù)的共享。
(4)廣播接收器是Android系統(tǒng)提供的一種異步消息傳遞機制,用于在系統(tǒng)與應(yīng)用程序之間、應(yīng)用程序與應(yīng)用程序之間傳遞消息,Broadcast Receiver本質(zhì)上就是一種系統(tǒng)級別的時間監(jiān)聽器,用于監(jiān)聽系統(tǒng)全局的廣播消息。
同一應(yīng)用的組件之間的交流和不同應(yīng)用組件之間的交流是通過意圖(Intent)組件[2]來實現(xiàn)的,四大組件都需要使用意圖來激活,意圖主要有兩種類型:顯示Intent和隱式 Intent。
(1)顯示Intent
顯式Intent通常為應(yīng)用程序內(nèi)部組件之間的通信方式,通常這種方式需要在Intent中明確指定目標組件;
(2)隱式Intent
隱式Intent通常應(yīng)用于程序之間通信,由于隱式Intent沒有明確目標組件,所以必須包含足夠的屬性信息才能通過系統(tǒng)匹配到對應(yīng)的目標組件,相對而言,目標組件必須包含意圖的過濾器,過濾包含匹配意圖的相應(yīng)的屬性信息才能實現(xiàn)兩者的匹配,隱式意圖中攜帶的屬性有 action(動作)、data(數(shù)據(jù))、category(類別)。
Android系統(tǒng)的安全機制在內(nèi)核層面試繼承Linux內(nèi)核的安全機制,在內(nèi)核安全機制的基礎(chǔ)上發(fā)展了一套具有自身特點的安全機制,主要介紹Android系統(tǒng)提供的三大安全機制:沙箱隔離機制、權(quán)限授予和檢查機制以及簽名機制。
(1)沙箱隔離機制
Android在Linux內(nèi)核安全模型[3]基礎(chǔ)上,拓展了用戶與權(quán)限機制,將多個用戶操作系統(tǒng)中用戶隔離為應(yīng)用程序隔離,并且為其配置一個UID,用于區(qū)別每個應(yīng)用程序。Android系統(tǒng)根據(jù)UID為應(yīng)用程序創(chuàng)建沙箱,不同UID的應(yīng)用程序運行在各自的沙箱中,彼此隔離,互不干擾。默認情況下,兩個不同的Android應(yīng)用彼此無法互相訪問,如果要實現(xiàn)不同應(yīng)用程序之間的互相訪問需要為它們分配相同UID。Android系統(tǒng)提供了一種共享UID機制,通過在Manifest在文件中制定android:sharedUserId屬性實現(xiàn)不同的應(yīng)用程序具有相同UID的功能。
(2)權(quán)限授予和檢查機制
Android系統(tǒng)的沙箱隔離機制使應(yīng)用程序之間的分離開來,相互隔離的進程之間無法互相訪問彼此的資源,這樣導(dǎo)致應(yīng)用無法使用系統(tǒng)資源,為此Android系統(tǒng)提供了權(quán)限授予和檢查機制[4],使應(yīng)用程序可以通過較為安全的方式訪問系統(tǒng)資源,Android系統(tǒng)提供了多達一百多種權(quán)限。Android應(yīng)用程序通過在Manifest文件中使用
(3)簽名機制
開發(fā)人員在發(fā)布自己的Android應(yīng)用程序時必須對應(yīng)用程序設(shè)置數(shù)字簽名,Android系統(tǒng)會在應(yīng)用程序安裝時檢查應(yīng)用的簽名,如果沒有簽名或者簽名不正確則拒絕安裝。雖然Android應(yīng)用程序必須進行簽名才能發(fā)布和安裝運行,但其簽名可以有開發(fā)人員自己生成,Android SDK為開發(fā)人員提供了簽名工具singapk.jar[5],使用自己生成的公鑰、密鑰即可完成對應(yīng)用程序的簽名。簽名是應(yīng)用程序開發(fā)者的身份識別標識,可以通過簽名判斷應(yīng)用程序是否被篡改,這對應(yīng)用的安全起到了一定程度的保護作用。
能力泄露[6]漏洞是Android應(yīng)用軟件眾多安全問題之一的一類,其本質(zhì)是應(yīng)用軟件通過某種方式提升了相關(guān)系統(tǒng)權(quán)限,獲取了權(quán)限對應(yīng)的系統(tǒng)資源,最終執(zhí)行相應(yīng)的軟件行為,造成對用戶或者系統(tǒng)的危害。
Android應(yīng)用在運行時都運用于自身的進程中,該進程擁有獨立的虛擬機實例,不能隨便與其他應(yīng)用相互訪問資源。圖1給出了Android應(yīng)用程序級別的能力泄露漏洞原理。從圖中表示單個應(yīng)用運行在各自的虛擬機中,互不干擾,應(yīng)用1不擁有權(quán)限,應(yīng)用2擁有權(quán)限p1,應(yīng)用2并沒有任何權(quán)限保護它的組件1,任何其他應(yīng)用可以訪問應(yīng)用2的組件1,當然應(yīng)用1的任何組件可以訪問應(yīng)用2的組件1,又因為應(yīng)用2的組件1有可以訪問應(yīng)用3組件1的權(quán)限,因此,應(yīng)用1的組件1在沒有p1的權(quán)限情況下也可以通過應(yīng)用2的組件1訪問應(yīng)用3的組件1,應(yīng)用1的組件1通過應(yīng)用2的組件1權(quán)限得到了提升,這就是所謂的應(yīng)用2能力泄露。

圖1 能力泄露原理
下面將用具體代碼展示能力泄露漏洞產(chǎn)生的過程,如圖2所示,應(yīng)用1的配置文件代碼的作用是使應(yīng)用1具有獲取定位信息的權(quán)限,應(yīng)用1的代碼的作用是使組件能夠獲得用戶定位并且將定位信息綁定到隱式Intent對象上,最后啟動應(yīng)用2的一個活動,應(yīng)用2中的配置文件1是獲取發(fā)送短信的權(quán)限,配置文件2通過過濾器篩選出符合條件的Intent對象,應(yīng)用2的代碼的作用是獲得應(yīng)用1的Intent對象以及Intent中額外的位置信息,并將信息發(fā)送到其他設(shè)備上,這就導(dǎo)致雖然應(yīng)用2沒有獲取定位信息的權(quán)限,卻通過應(yīng)用1獲得了該權(quán)限,我們也稱這種現(xiàn)象叫做應(yīng)用2權(quán)限提升,應(yīng)用1能力泄露。


圖2 能力泄露代碼
污點分析技術(shù)[7]是信息流分析技術(shù)的一種,該技術(shù)通過對程序中敏感數(shù)據(jù)進行標記,之后跟蹤標記數(shù)據(jù)在程序中的傳播,最后檢測是否到達泄漏點來進行漏洞分析的,污點分析技術(shù)主要有三個重要技術(shù):中間表示層,Source和Sink,可達路徑。
(1)中間表示層
為了簡化分析的復(fù)雜性,一般不會在Dalvik字節(jié)碼和Java代碼上面直接分析,而是在中間代碼Jimple[8]上進行分析的,Jimple是Java中簡單類型化的三地址表示的中間語言,只有15條語句指令,這15條指令核心指令、函數(shù)內(nèi)控制指令、函數(shù)間控制指令、監(jiān)視器指令、退出指令和異常處理指令。
(2)Source和 Sink
Source[9]即污點源,代表直接引入不受信任的數(shù)據(jù),Sink[9]即泄漏點,代表直接產(chǎn)生安全敏感操作或者泄露隱私數(shù)據(jù)到外界,污點分析是通過信息流分析方法檢測出那些標記的Source(污點源)所操作的信息是否能流向并且達到所定義的Sink(泄漏點)位置。
(3)可達路徑
污點分析的整個過程屬于執(zhí)行順序相關(guān),其中前向的污點分析用于尋找被污染源污染的變量傳播到了何處,而后向的按需別名分析[9]用于查找在Source之前所有對同一個被污染源污染的堆內(nèi)存位置的別名,從而找出一條從Source到Sink之間的一種可能性路徑,如圖3所示[9],foo函數(shù)中的w變量被標記為污點變量,然后傳播到堆對象中的x.f變量,當有被污染了的變量傳播到堆對象的成員變量中時,使用后向分析找出相關(guān)變量或者對象的別名,x.f和z.g.f指向了同一內(nèi)存,而這兩個變量是由x賦值的,x又是參數(shù)z賦值而來的,然后繼續(xù)向前分析調(diào)用函數(shù)中a賦值給z,接著發(fā)現(xiàn)b也是別名,對b.f再繼續(xù)做前向分析,判斷出b.f即a.g.f,從而檢測到Source被傳遞到了Sink的位置。

圖3 可達路徑
第一節(jié)主要介紹了Android體系結(jié)構(gòu)、Android組件、Android安全機制、能力泄露原理、靜態(tài)污點分析技術(shù)的基礎(chǔ)知識,在本章中主要提出一種基于污點分析的Android能力泄露漏洞檢測框架,該框架的流程圖如圖4所示,該框架啟動時,首先會對apk文件進行逆向解析,得到Manifest文件和Dex文件。接著,將Dex文件用soot工具[10]轉(zhuǎn)換成可讀的中間語言表示形式,結(jié)合對Manifest文件進行分析得到模擬的Android生命周期,構(gòu)造初始偽入口函數(shù)dummymain[9],以偽造的dummymain函數(shù)為入口,對Jimple代碼進行控制流分析并構(gòu)造程序控制流圖ICFG[11],然后,在ICFG的基礎(chǔ)上進行檢測Android應(yīng)用中能力泄露數(shù)據(jù)在Android應(yīng)用內(nèi)的傳播情況。

圖4 系統(tǒng)框架流程圖
通過前面的能力泄露漏洞原理介紹,可以知道Android應(yīng)用能力通過權(quán)限以及敏感API泄露的,而Manifest文件記錄了應(yīng)用需要使用的權(quán)限,暴露的組件和實現(xiàn)的類、實現(xiàn)的位置,以及訪問某組件所需的權(quán)限。其中

圖5 解析Manifest文件
一般情況下,應(yīng)用程序值提供apk文件給用戶,并不會直接提供源代碼,這就需要將apk反編譯成Jimple可讀語言,可以通過調(diào)用開源靜態(tài)分析工具Soot完成。首先使用Soot內(nèi)嵌的Android分析插件Dexpler[12]讀取dex格式的文件,生成一種類似jasmin的偽代碼,再使用soot的Jimple組件對jasmin偽代碼進行轉(zhuǎn)換為Jimple中間語言,為后面的使用Jimple中間代碼來構(gòu)建控制流圖奠下基礎(chǔ)。
Android應(yīng)用不像Java程序一樣有統(tǒng)一的main函數(shù),它是事件驅(qū)動的系統(tǒng),由組件的周期函數(shù)以及回調(diào)函數(shù)來控制應(yīng)用程序的運行過程,包含多個Android分析入口點,因此我們需要生成一個虛擬main方法來模擬各個組件的生命周期[13]以及被重寫的回調(diào)函數(shù)之間的控制流轉(zhuǎn)移關(guān)系,以dummyMain函數(shù)為程序的控制流追蹤起點,在dummyMain中順序調(diào)用使控制流分析進入所有的子入口函數(shù),即可實現(xiàn)對Android程序多入口遍歷。如圖6所示[9],展示了通過dummyMain方法構(gòu)造為入口的Activity生命周期以及sendMessage回調(diào)的控制流圖。

圖6 dummyMain方法的流程圖
控制流[14]是在解析Manifest.xml文件的基礎(chǔ)上,結(jié)合敏感API函數(shù)和系統(tǒng)回調(diào)函數(shù)對apk文件進行構(gòu)造程序控制流圖,該階段采用Soot靜態(tài)分析框架來生成函數(shù)間控制流圖ICFG。函數(shù)間控制流圖ICFG是遍歷一個程序所有語句的地圖,通過一個接口InterproceduralCFG進行定義,Soot自帶的JimpleBasedInterproceduralCFG類對InterproceduralCFG進行了多層實現(xiàn),JimpleBasedInterproceduralCFG 中的CallGraph,Unit-Graph兩種數(shù)據(jù)結(jié)構(gòu)以及一些映射關(guān)系完成控制流ICFG的實現(xiàn),并保存在靜態(tài)的全局環(huán)境變量Scene中。
數(shù)據(jù)流分析[15]是建立在控制流分析之上的,根據(jù)控制流分析提供的語句執(zhí)行順序,數(shù)據(jù)流分析遍歷程序語句,提取并記錄語句中的數(shù)據(jù)依賴關(guān)系,形成數(shù)據(jù)路徑。在該框架中我們使用了以流函數(shù)flowfunction的形式提供服務(wù)的污染規(guī)則來提取程序語句中的數(shù)據(jù)流。步驟如下:
(1)normalFlowFunction():當分析到語句是一條沒有跳轉(zhuǎn)的順序執(zhí)行語句時進行處理,提取語句之間的復(fù)制關(guān)系。
(2)callFlowFunction():當分析到的語句是一條函數(shù)調(diào)用語句時進行處理,主要是對參數(shù)調(diào)用的映射。
(3)returnFlowFunction():當分析的語句是一條函數(shù)返回語句時進行處理,主要對返回值進行映射。
(4)callToReturnFlowFunction():當分析的語句是函數(shù)調(diào)用語句時進行處理,主要是對與函數(shù)無關(guān)的數(shù)據(jù)的提取依賴關(guān)系或者特殊函數(shù)處理。
靜態(tài)污點分析過程通過類InfoflowProblem來定義,該類實現(xiàn)了Heros的分析接口IFDSTabulationProblem,而IFDSTabulationProblem是IFDS的程序化描述,接口中按照IFDS理論定義了數(shù)據(jù)流分析的所有要素,接口中四個關(guān)鍵的函數(shù),其中flowFunction是流函數(shù);interprocedualCFG是控制流圖ICFG的接口;initial-Seeds是數(shù)據(jù)流分析在控制流中的起點,一般是source函數(shù)的位置,在數(shù)據(jù)流分析前,我們需要根據(jù)檢測不同類型的漏洞而配置不同的SourceAndSink.txt配置文件,下面表1和表2分別列出了與能力泄露相關(guān)的一些權(quán)限特征和行動特征;zeroValue用來標志污染值。

表1 權(quán)限特征

表2 行為特征
我們從國內(nèi)的五大Android應(yīng)用市場上面下載了105個應(yīng)用進行分析測試,囊括了金融理財、音樂視頻、社交通訊、旅游消費、氣象交通、購物支付、新聞閱讀等幾類。
系統(tǒng)配置及測試環(huán)境如表3所示。

表3 系統(tǒng)配置及測試環(huán)境
該框架通過靜態(tài)污點分析技術(shù)分析完這105個應(yīng)用程序,總耗時為320分鐘,在這次分析當中發(fā)現(xiàn)了有6項應(yīng)用程序包含有能力泄露漏洞,它們分別是com.madgag.agit, com.matburt.mobileorg, com.robert.maps,com.jadn.cc,com.cradle.iitc.mobile.IITC,com.voidcode.diasporawebclient,其中泄露的權(quán)限如表4所示。

表4 App的權(quán)限泄露
本節(jié)主要對論文所做的研究工作進行總結(jié),以及分析工作中存在的問題和不足,并對未來的研究方向和發(fā)展趨勢進行展望。本文首先研究了Android系統(tǒng)的框架結(jié)構(gòu)、四大組件、組件通信機制以及Android安全機制等,其次分析了能力泄露漏洞繞過Android系統(tǒng)安全機制的原理,最后通過污點分析技術(shù),自動化實現(xiàn)過程間控制流圖的繪制,以及靜態(tài)污點跟蹤技術(shù)來檢測可利用數(shù)據(jù)路徑,從而達到能力泄露漏洞的檢測。該框架還存在很多不足的地方,其一是在污點傳播分析當中只能進行顯式流分析,不能進行隱式流分析,有些數(shù)據(jù)可以通過隱式流方式傳遞給其他數(shù)據(jù),這樣就造成了沒有標記隱式流傳播的數(shù)據(jù)為污點數(shù)據(jù),導(dǎo)致了欠污染情況;其二是效率問題,面對分析大型的應(yīng)用,分析的效率會降低;其三是未對fragment組件的生命周期考慮在內(nèi),從而導(dǎo)致漏報,這個可能是未來的一個研究方向。隨著計算機系統(tǒng)的發(fā)展以及軟件規(guī)模的擴大,污點分析技術(shù)將在應(yīng)用中發(fā)揮更大的作用,筆者認為在未來研究能力泄露漏洞檢測會采用靜態(tài)污點分析和動態(tài)污點分析結(jié)合的方式來獲取更高的精確度。