何 鍇 琦
(吉林大學 大數據和網絡管理中心,長春 130012)
隨著移動應用(app)的快速發展,人們已經習慣通過手指的簡單操作完成各種事務.不僅包括簡單的網上交流和游戲,也包括一些安全敏感性的活動,如電子銀行和商務處理等.在這種應用環境下,用戶不再只關注于移動app功能方面的體驗,而是越來越重視自己的隱私信息安全.
移動應用需要使用智能手機上的敏感信息以實現產品功能,在使用這些敏感信息前,移動應用需要向用戶申請相應的權限才能訪問敏感數據.考慮到具有類似功能的產品應該使用相似的敏感權限[1-3],并且移動應用的功能信息與權限信息可通過挖掘其UI(user interface)和代碼有效地獲取,因此本文提出一種分析移動應用安全性的方法.首先,通過分析產品的UI挖掘移動應用具有的功能信息;然后,通過分析代碼中使用的API確定移動應用實際使用的敏感權限;最后,將具有類似功能的產品聚類到一起,使用孤立森林算法識別每個簇中異常使用了敏感權限的應用,進而完成安全性分析.
為支持后續app產品的安全分析工作,首先需要了解每個app具有的功能.受UI測試工具的啟發[4],本文開發一個UI探索工具完成挖掘app功能的任務.
用戶是通過各種動作與app產品進行交互的(如點擊、滑動和編輯等).本文UI探索工具基于該原理分析app的apk文件,進而獲取其具有的功能.將apk文件作為輸入,UI探索工具首先以app產品的一個UI頁面為起始點,嘗試識別當前UI頁面的可進行交互的UI組件,并且通過分析這些組件的屬性推測它們具有的交互功能.然后,該工具模擬人類動作觸發相應的UI事件,從而自動化地探索app產品的不同部分.在該過程中,工具可以收集app產品的UI截圖.以圖1為例,本文工具從UI-1出發,通過模擬動作滑動和兩次點擊依次跳轉到UI-2,UI-3和UI-4,從而收集到該app產品的4個UI截圖.

圖1 UI探索工具探索app產品的UI截圖實例Fig.1 UI explorer tool explores UI screenshot instances of app products
在探索過程中,使用UI Automator導出每個頁面對應的xml文件.UI Automator是安卓平臺提供的界面測試框架,UI Automator中提供了dump功能,該功能可用于導出移動應用當前的UI運行時前端代碼,該代碼以xml文件格式展示.該前端代碼對應的xml文件的形式可參考圖2中的示例,圖2的左側展示了一個UI截圖,右側是其對應的xml文件.

圖2 一個UI截圖及其對應的xml文件Fig.2 A UI screenshot and its corresponding xml file
由圖2可見,xml由很多節點(node)按層次結構進行組織.每個節點都有一系列屬性,例如: text屬性代表該節點的文本標簽;class屬性反應了該節點的類型;clickable節點反應了該節點是否是可點擊的.這些node有ViewGroup類型的(如FrameLayout),也有View類型的(如ImageView,TextView).通過分析該文件,可以獲取UI頁面中具有的組件、組件的屬性以及這些組件的層次結構.
基于這些xml文件,可以分析UI截圖上提供的功能.通過實際觀察app產品,絕大多數提供功能的UI組件都是通過點擊方式進行的(在本文觀察的與功能相關組件中,97%的UI組件激發動作是點擊).相應地,在分析xml文件時,也僅分析可點擊屬性為true的UI組件.為了解某個可點擊組件實現的功能,本文制定4條分析規則用于對可點擊組件進行分析,規則如下.
規則1) 若可點擊UI組件的text屬性不為空,則text屬性的值為該組件的功能.Text屬性用于設置顯示在UI組件上的文字,通過組件上的文字,用戶能了解與該組件實現的功能.如圖3(A)所示,藍框圈出的按鈕用于實現Send功能,該按鈕的text屬性值為Send.
規則2) 若可點擊UI組件為ViewGroup類型的組件,則使用其子節點的text值作為該組件的功能.ViewGroup類型的組件是用于存放其他UI組件的布局容器.當這類組件的clickable屬性為true時,其子節點的text屬性值可用于說明點擊該ViewGroup組件所實現的功能.如圖3(B)所示,藍框圈出的ViewGroup組件具有兩個子節點,由第二個子節點的text屬性可知該組件實現的功能是Translate.
規則3) 若可點擊UI組件為圖片組件(ImageView,ImageButton),則使用其相鄰節點的text屬性作為組件的功能.當可點擊組件為圖片組件時,圖片旁邊的相鄰節點通常會給出描述性文字用于對圖片對應的功能進行說明.如圖3(C)所示,通過分析相鄰節點可知,藍框部分圈出的ImageView組件的功能是Camera.
規則4) 若通過以上規則無法獲取有效的功能信息,則對UI組件的id屬性進行分析,從而獲得組件的功能.為保證開發時的代碼便于閱讀和理解,開發者通常會使用能表現組件功能的文本作為組件的id值.因此,通過對組件的id值進行分析可獲得組件代表的功能.如圖3(A)所示,通過對組件id進行分析,可知紅框圈出的組件功能為choose stickers.

圖3 UI組件及其對應的頁面UI代碼Fig.3 UI component and its corresponding page UI code
對于一個app,先使用UI探索工具遍歷獲得它具有的頁面及對應的xml文件后,再根據以上4條規則對每個頁面的xml文件進行分析.這樣就能獲得一個app所具有的功能.
由于同一個功能在不同的app中會有不同的表述方式,因此需要對提取出的功能進行聚類.首先,將功能轉換成向量: 給定一個功能,使用BERT[5]將功能中的單詞依次轉換成詞向量,取所有單詞詞向量的平均值作為該功能的向量表示.BERT是基于Transformer架構的用于自然語言處理的預訓練技術.與基于word embedding的word2vec[6]相比,BERT在為單詞生成詞向量時,會考慮單詞出現的上下文.例如,詞“蘋果”的word2vec詞向量在“我愛吃蘋果”和“我買了一部蘋果手機”中相同.而BERT則會根據上下文的不同含義提供不同的詞向量.完成功能的向量化后,使用Mean shift算法[7]對功能向量進行聚類.Mean shift算法是一種基于聚類中心的聚類算法,與傳統的k-means[8]聚類算法相比,Mean shift算法不需要提前設置聚類的類別個數k,能較好處理聚類個數未知的情形.對于給定d維空間d中的n個樣本點xi(i=1,2,…,n),對于x點,其Mean shift的向量形式為

(1)
其中:

(2)
G(x)是一個單位的核函數;H是一個正定的對稱d×d矩陣,稱為帶寬矩陣,是一個對角矩陣;w(xi)≥0是每個樣本的權重.對角矩陣H的形式為

(3)
完成app的功能分析后,先基于app的功能進行風險app檢測工作,過程如圖4所示.

圖4 風險app檢測過程Fig.4 Detection prosess of risk app
首先,根據app具有的功能為其建立一個功能向量,并使用Mean shift算法對app進行聚類.App的功能向量建立過程如圖4(A)所示,app功能向量的維數與集合中的功能簇數量一致,向量中的每個元素與集合中的每個功能簇具有對應關系.將app中具有的功能與集合中的功能簇依次進行比較,若app擁有簇中的某個功能,則將該簇對應維的值設為1,否則設為0.基于Mean shift算法完成聚類工作后,可得到一個app的簇集合,屬于同一個簇的app具有相似功能.
其次,利用孤立森林(isolation forest,iForest)算法[9]對每個簇進行分析,以識別出可能異常使用了敏感權限的風險app產品.iForest是一種無監督異常檢測算法,廣泛應用于數據的異常檢測中,如網絡安全中的攻擊檢測、金融交易欺詐檢測、疾病偵測和噪聲數據過濾等.孤立森林算法的理論基礎有兩點: 1) 異常數據占總樣本量的比例很小;2) 異常點的特征值與正常點的差異很大.基于上述理論基礎,查找異常點的策略如下: 假設用一個隨機超平面切割數據空間,切一次可以生成兩個子空間.然后再繼續用一個隨機超平面切割每個子空間,循環進行,直到每個子空間中只有一個數據點為止.那些密度很高的簇被切割很多次才能停止,即每個點都單獨存在于一個子空間內.但那些密度很低的點會很早停止切割.如何對數據空間進行切割是孤立森林設計的核心思想.iForest由t個孤立樹(isolation tree,iTree)組成,每個iTree是一個二叉樹結構.iTree的訓練算法如下.
算法1iTree(X′)算法.
輸入:X′;
輸出: iTree;
步驟1) ifX′不能被分割 then
步驟2) return exNode{Size←|X′|};
步驟3) end
步驟4) else
步驟5) 設Q為X′中屬性的列表;
步驟6) 隨機選擇一個屬性q∈Q;
步驟7) 在X′中的屬性q的最大值和最小值之間隨機選擇一個分割點p;
步驟8)Xl←filter(X′,q
步驟9)Xr←filter(X′,q≥p);
步驟10) return inNode{Left←iTree(Xl),right←iTree(Xr)},SplitAtt←q,SplitValue←p};
步驟11) end.
1) 從訓練數據中隨機選擇Ψ個樣本點作為子樣本,放入樹的根節點;
2) 隨機指定一個維度,在當前節點數據中隨機產生一個切割點p(切割點產生于當前節點數據中指定維度的最大值和最小值之間);
3) 以此切割點生成一個超平面,然后將當前節點數據空間劃分為兩個子空間: 把指定維度中小于p的數據放在當前節點的左邊,把大于等于p的數據放在當前節點的右邊;
4) 在子節點中遞歸步驟2)和3),不斷構造新的子節點,直到子節點中只有一個數據(無法再繼續切割)或子節點已到達限定高度.
同一個簇的app具有相似的功能,相應地,這些產品也應該使用類似的敏感權限.安卓官方文檔將28個權限定義為敏感權限,這些權限涉及到用戶的隱私及安全問題,例如短信權限、位置權限等.獲得app使用權限的一種方式是從apk的manifest文件中的權限聲明部分直接獲取.但研究表明30%的app聲明權限會比實際使用的權限更多[10].為避免這種分析方法帶來的誤差,本文通過分析app中實際調用的API進一步獲得其使用權限.本文使用安卓靜態分析工具androguard(https://github.com/androguard/androguard)對apk文件進行反編譯,并獲取程序中調用的API.論文PScout[11]為安卓應用的API與權限之間建立了映射關系,從而為根據調用API獲得其使用權限提供了基礎: 若app調用了與某個權限有映射關系的API,則該app使用了此權限.根據app對這28個敏感權限的使用情況,為每個app生成一個28維的權限向量,向量中每個元素代表該app是否使用了相應的敏感權限: 1表示使用了相應的權限;0表示未使用.完成上述工作后,再使用孤立森林算法對獲取的向量進行處理,以識別出其中的異常點,進而判斷app是否異常使用了敏感權限.孤立森林算法會為每個app生成一個位于[0,1]內的異常得分,異常得分越接近于1,說明該app的權限使用情況越異常.本文將異常得分高于0.5的app識別為風險app.
下面通過實驗對上述方法進行驗證.本文從Google play應用商店中選取4個類別的app作為研究對象,這4個類別分別為Social,Photograph,Music&Audio,Navigation.分別從這4個類別中隨機選取1 000個app,組成一個共包含4 000個app的集合.按照本文方法對該集合中的app進行分析,從而識別出其中的風險app.對于每個類別,從中隨機選取20個被本文方法識別為風險的app和20個被識別為安全的app作為實驗的測試集.
建立完實驗測試集后,由3個具有安卓應用開發經驗的開發者對測試集中app的安全性進行評估.首先,為開發者提供app的描述文本信息,通過分析API得到的app使用的權限列表以及app的apk安裝包,開發者閱讀描述文本和權限列表后,將apk安裝到手機上進行實際操作和使用.然后,開發者判斷該app是否異常使用了敏感權限,若使用了則標記為風險app,否則標記為安全app.若3名開發者對同一個app的標記情況不一致,則3人進行討論并得到最終標記結果.將本文方法得到的識別結果與實驗人員的標記結果進行比較以評估本文方法的有效性.
表1列出了風險app識別方法的評估結果.實驗結果表明,本文方法能完成app的安全分析工作: 利用本文方法得到的80個風險app中,超過半數的app(65.00%)被開發者標記為風險app;利用本文方法獲得的80個安全app中,有72個被開發者標記為安全應用程序.有28個安全app被本文方法錯誤地識別為風險app,對這些app進行分析并總結了分析錯誤的主要原因: 某些app使用了大量的圖標用于表示產品中的功能,這些圖標周圍并未給出對圖標功能的說明性文本,從而導致本文方法無法準確地獲取app具有的功能,最后導致分析結果的錯誤.

表1 風險app識別方法的評估結果
綜上所述,針對移動應用隱私信息的安全性問題,本文提出了一種移動應用安全性分析方法,它通過挖掘UI與代碼中的信息識別出產品具有的功能與實際使用的敏感權限,并且基于具有相似功能的應用應該使用相似敏感權限的思想分析移動應用是否具有風險.實驗結果表明,該方法能有效完成移動應用的安全分析.