基于函数调用关系的Android应用权限泄露漏洞挖掘技术研究
2017-03-14谭翠江刘嘉勇
◆谭翠江 刘嘉勇
基于函数调用关系的Android应用权限泄露漏洞挖掘技术研究
◆谭翠江 刘嘉勇
(四川大学电子信息学院 四川 610064)
自Google发布Android系统以来,各大Android应用市场上APP的数量不断增长,Android应用程序安全问题也日益突出。本文通过对Android 应用程序中常见的权限泄露漏洞形成原理进行研究,提出一种针对由暴露组件引起的权限泄露漏洞挖掘方法,旨在帮助开发者和用户及时发现存在这种威胁的Android应用程序,防止用户的隐私泄露和财产损失。本文方法在对Android应用程序进行静态分析得到可疑路径的基础上构造测试用例进行验证测试,具有更强的针对性,避免了进行动态测试时的盲目性,可有效地发现Android应用中存在的权限泄露漏洞。
Android;函数调用;权限泄露;漏洞挖掘
0 前言
近几年,移动平台发展迅速,逐渐成为人们上网的主要方式,其中Android平台的发展最为显著。根据市场研究公司Strategy Analytics发布的最新研究报告显示,2016年第三季度Android手机目前的全球市场份额已经高达87.5%,远远超过了其他手机系统,占据全球手机操作系统第一的位置[1]。随着Android智能设备的普及,日益严峻的Android平台安全问题变得越来越不可忽视。根据AVD Android漏洞库显示,目前该漏洞库已收录662条漏洞信息,其中来自第三方应用软件的漏洞数量为349个,占了52.72%。因此保证第三方应用软件的安全对保障Android平台安全显得尤为重要。而在第三方应用软件中,由于开发者的疏忽或安全意识不强,常导致应用软件中存在权限泄露漏洞,对用户的隐私和财产安全造成极大的威胁。因此,本文就针对由Android组件暴露引起的Android权限泄露漏洞提出一种基于函数调用关系分析的漏洞挖掘方法,并通过实验的方式验证了该方法的有效性和实用性。
1 相关技术研究
1.1 Android安全机制
Android系统基于Linux内核,在继承了Linux固有安全机制的同时,还增加了沙箱机制、权限机制和数字签名机制。Android权限机制采用了安装时期权限机制,即要求开发者预先声明他们的权限请求,使得用户可以在安装时期对这些权限请求进行授权,这区别于iOS采用的实时权限机制[2]。Android权限机制对Android应用程序可以执行的某些具体操作进行权限细分和访问控制,以保证系统资源不被滥用。默认情况下,应用程序在使用如网络、短信、通话、SDCard存储等系统资源之前,都必须在程序的AndroidManifest.xml文件中通过
1.2 Intent机制
Android系统为支持不同应用程序间的通信,提供了Intent机制来协助应用程序组件间的交互。Intent是一种运行时绑定机制,它能在程序运行过程中连接两个不同的组件,负责描述应用中一次操作的动作、动作涉及数据以及附加数据。系统则根据此Intent的描述,找到对应的组件,并将 Intent传递给调用的组件,从而完成组件的调用[4]。
Intent一般包含两部分:目的和内容,其中目的用来表示该Intent要传递给哪个组件,而内容则表示向目的组件传递什么内容。这些可以通过Intent的动作(Action)、数据(Data)、类别(Category)、类型(Type)、组件名称(Component)以及扩展信息(Extra)等属性来指定。Intent根据用法可以分为两种:显式Intent和隐式Intent。显式Intent在构造的时候需要指明接收对象,而隐式Intent在构造时,并不知道明确的接收对象,需要用
1.3 权限泄露漏洞概述
一般情况下,Android应用程序所使用的组件需要在AndroidManifest.xml文件中进行声明,如:Activity、Services等。在Android系统中,签名相同且用户ID相同的程序在执行时共享同一个进程空间,彼此之间没有组件访问限制。而签名不同、用户ID不同的程序之间只能访问处于暴露状态的组件。
组件是否处于暴露状态一方面可以通过组件的android:expor ted属性值来判断,当组件显式地将android:exported的属性值设为true时,组件处于暴露状态;当其值被设为false时,组件处于非暴露状态。另一方面当组件没有显式地设置android:exported的属性值时,组件是否处于暴露状态由其是否设置了Intent过滤器(intent-filter)决定。如果组件设置了过滤器,则表示该组件可以被外部隐式的Intent访问调用,否则该组件则不能被外部程序访问调用。此外,如果组件在注册时设置了android:permission属性,则该组件在被外部应用调用时,系统会检查调用者是否具有对应的权限,若外部应用没具备该权限,系统则会抛出异常。权限泄露模型如图1所示:
图1 权限泄露模型
当暴露的组件没有设置android:permission属性且在进程中存在敏感权限的API操作时,就有可能被攻击者通过调用暴露的组件来绕过Android系统的权限机制,将外部应用的权限提升至暴露组件所具有的权限,进行一些其本身无权进行的敏感操作,如打电话、发短信等,从而造成了Android应用权限泄露[5]。
2 权限泄露漏洞挖掘
2.1 APK文件预处理
由前面的分析可知,导致Android 应用权限泄露漏洞的组件需要一定的条件,即组件必须是暴露的,没设置android:permissio n属性且进行了敏感权限的API操作。因此在对APK进一步分析前需要先对APK文件进行预处理,提取后续分析所需的一些信息。整个预处理过程如图2所示。首先对apk文件进行解压缩,获取APK包中的dex文件、AndroidManifest.xml文件。然后使用xml解析工具对AndroidManifest.xml文件进行解析,提取应用程序申请的权限信息和程序注册的组件信息,检查各组件的andr oid:exported属性值,以及android:permission属性、Intent过滤器的设置情况,筛选出处于暴露状态的组件。另一方面对dex文件进行反编译,得到细粒度的smali代码,为后面构建函数调用关系图做准备。
图2 APK预处理过程
2.2 函数调用关系图的建立
函数调用关系图是一个有向图,图中的每个节点为应用程序中的一个函数,图中的边为函数的一个调用点。目前生成Android应用程序函数调用关系图的方法,一般是利用开源的Flowdroid或Androguard工具来生成,但生成的函数调用关系图中包含了很多的与本文分析内容无关的节点,增加了后续分析的复杂度,因而本文不采用上述方法生成程序的函数调用关系图。
本文根据后续分析的需要,在smali代码级别上构建Android应用程序的函数调用关系图。主要过程是对预处理过程中得到的smali代码进行搜索遍历,提取程序中定义的方法以及各方法中调用的API函数,并通过回溯,得到各个函数间的调用关系。
因为本文是针对由Intent机制调用Android暴露组件引起的权限泄露漏洞进行研究,而Acitivity、Service、BroadCastReceiver组件可由Intent机制访问调用,所以只需关注这三类暴露组件入口函数后的函数调用关系即可。因此,将Android应用程序中上述三类暴露组件的入口函数设置为起始节点,其中这三类Android组件的入口函数如表1所示[6]。然后对Android应用程序的函数调用关系图进一步优化,去除其它与组件入口函数不连通的无关节点,由此可得到应用程序中各个暴露组件对应的函数调用关系图。以Test.apk的MainActivity组件为例,得到的函数调用关系图如图3所示。
表1 Android组件入口函数
图3 Test.apk的MainActivity组件函数调用关系图
2.3 基于函数调用关系图的分析
APK预处理阶段得到了应用程序所申请的权限信息,权限所对应的API函数即为应用程序中可能造成权限泄露的点。其中Android权限与API函数的对应关系如表2所示,限于篇幅本文只列出了部分对应关系。
表2 Android权限与API对应表(部分)
图4 深度优先搜索算法示例
为了简化分析,在生成的应用程序暴露组件的函数调用关系图中,将程序中可能导致用户信息泄露的点,即权限所对应的API函数标记为终止节点。结合组件的入口函数,即函数调用关系图的起始节点,所构成的路径即为存在权限泄露漏洞的可疑路径。为了得到由暴露组件引发的权限泄露漏洞的全部可疑路径,本文采用深度优先搜索算法对暴露组件的函数调用关系图进行搜索遍历。深度优先搜索算法是按照深度优先展开搜索树的搜索算法[7],可以有效地求出两点间的所有路径。以图4为例,简要说明深度优先搜索算法搜索从v0到v4节点所有路径的过程。
(1)首先建立一个存储节点的栈结构,将起始节点v0入栈,并将其标记为入栈状态。
(2)从v0节点出发,找到下一个相邻的非入栈节点v1、v2或v3,假设先访问v1节点,将v1节点入栈,并标记为入栈状态。
(3)从v1节点出发,搜索下一个相邻的非入栈节点。由于v1节点没有下一个相邻的节点,所以从栈顶弹出v1节点,并将v1节点标记为非入栈状态。此时栈顶是v0节点。
(4)从v0节点出发,找到下一个除v1节点外相邻的非入栈节点v2或v3,假设先访问v2节点,将v2节点入栈,并标记为入栈状态。
(5)从v2节点出发,找到v2节点的下一个相邻的非入栈节点v4,将v4节点入栈,并标记为入栈状态。
(6)由于v4节点是终止节点,因此得到了一条从起始节点v0到终止节点v4的路径:v0-> v2-> v4。
(7)从栈顶弹出v4节点,并将v4节点标记为非入栈状态。
(8)此时栈顶是v2节点,由于v2节点没有除刚出栈的v4节点外的相邻非入栈节点,因此将v2节点出栈,并标记为非入栈状态。
(9)此时栈顶是v0节点,重复步骤(4)~(6)得到第二条从起始节点v0到终止节点v4的路径:v0-> v3-> v4。
(10)重复步骤(7)(8),此时栈顶是v0节点,由于与v0节点相邻的节点都已被访问过,因此弹出v0节点,并标记为非入栈状态。此时栈结构为空,结束整个路径搜索过程。
如图3所示的Test.apk的MainActivity组件函数调用关系图,以组件入口函数”MainActivity;onCreate()”节点为起始节点,应用的权限泄露点”SmsManager;sendTextMessage()”节点为终止节点,使用深度优先搜索算法进行路径搜索,得到由起始节点到终止节点的所有路径为:
(1)”MainActivity;onCreate()”->”MainActivity;fun1()”->”MainActivity;fun2()”->”SmsManager;sendTextMessage()”;
(2)”MainActivity;onCreate()”->”SmsManager;sendText Message()”;
即Test.apk的MainActivity中存在权限泄露的可疑路径集为{(1)(2)}。
然而在得到的可疑路径集中,并非所有的路径都能在程序运行时得到执行,大部分的路径都需要满足一定的条件才能执行。因此需要对存在可疑路径的危险组件进行动态测试才能最终确认应用中是否存在权限泄露漏洞。
2.4 对可疑路径进行测试
为了对得到的可疑路径集进行测试,需要解决三个问题:
(1)构造测试用例;
(2)将测试用例输入到Android模拟器或真机中执行;
(3)监视测试用例运行结果。
对于测试用例的构造,由前面得到的可疑路径集,分别取出每一条可疑路径,结合预处理过程中得到的暴露状态的组件信息,得出可疑路径所在的组件名、组件所设置的Intent过滤器信息和组件接收的各参数的数据类型。由此可以构造一个显式的Intent或隐式的Intent来模拟攻击者对该组件进行访问调用,其中需要传递的参数根据不同的数据类型分别设置默认值来进行测试。
为更加方便地解决第二个问题,本文采用Android系统提供的am命令将测试用例输入Android模拟器进行测试。am命令使用方法如下:
am [subcommand] [options]
即命令后面跟着一个子命令,本文主要用到start、startservice、broadcast三个子命令,它们分别可以启动Activity、Service组件和发送广播。以start子命令为例,其后接一系列可选参数和
am start –n 包名/组件名。
对于隐式的Intent,其转换成命令行的规则为: am start [-a
在向Android模拟器输入测试用例后,需要监测测试用例的运行情况,本文采用修改系统源码的方式,在系统源码相应的API函数中加入打印日志信息语句来监视相关API函数被调用情况,进而根据日志信息判断漏洞是否存在。
3 实验测试结果
为了验证本方法的有效性,本文首先设计了一个存在两处权限泄露漏洞的Android应用来测试本方法对一个应用中存在多处权限泄露的检测效果。该应用中包含了3个Activity、3个Servi ce。其中每类组件又分别设置为非暴露、暴露且设置了android: permission属性、暴露没设置android:permission属性三种状态,且每个组件都进行了一次权限调用。实验结果如表3所示。
表3 实验结果
为进一步验证方法的实用性,本文在Android应用市场上随机下载了涵盖金融类、系统工具类、社交类、多媒体类和生活服务类共100个Android应用依次进行测试。除了其中13个应用程序由于进行了加固处理,在预处理阶段反编译时出错,无法进一步分析外,剩余的应用程序经过预处理阶段共发现了1136个暴露组件。生成函数调用关系图进行分析后,共得到了9条造成权限泄露的可疑路径。构造Intent测试用例对可疑路径进行测试后,从日志信息中发现成功地执行了其中的三条可疑路径,其中两条权限泄露路径属于同一应用。这表明利用本文的方法成功地从实验随机选取的100个Android应用中挖掘出了两个存在权限泄露漏洞的应用。
通过上述实验结果可以看出,本文的方法能有效地挖掘出Android应用中由暴露组件引起的权限泄露漏洞。
4 结束语
本文通过对Android应用进行预处理,获取程序的暴露组件和申请的权限等信息后,结合暴露组件信息构建程序的函数调用关系图。再结合Android应用权限与API函数的对应表,以及Android组件的入口函数,采用深度优先搜索算法对函数调用关系图进行搜索,得到应用程序中存在权限泄露的可疑路径集。最后再通过静态分析的结果构造测试用例对可疑路径集进行验证测试,大大改善了动态测试的盲目性,有效地挖掘出了Android应用中存在的权限泄露漏洞。该方法不足之处在于,在构造测试用例时,对于组件接收的参数只是根据类型设定了固定的默认值,这使得不能发现组件需要传入特定数据才能触发的漏洞,下一步研究工作将重点在这方面展开。
[1]手机中国2016年第三季度智能手机市场份额调研报告[R].http://www.cnmo.com/os/561651.html,2016.
[2]朱佳伟,喻梁文,关志.等.Android权限机制安全研究综述[J].计算机应用研究,2015.
[3]李淑民.Android智能手机隐私泄露机制及防范方法研究[D].北京交通大学,2015.
[4]Chen F.METHOD,DEVICE AND TERMINAL FO R STARTING APPLICATION PROGRAM:,WO/2014/16 1292[P],2014.
[5]董国伟,王眉林,邵帅等.基于特征匹配的Android应用漏洞分析框架[J].清华大学学报自然科学版,2016.
[6]李智,陈金威,陈世喆等.基于静态污点分析法的Andr oid信息泄露研究[J].电子质量,2015.
[7]龚建华.深度优先搜索算法及其改进[J].现代电子技术,2 007.