不多讲,开始吧,嗯
一 Activity漏洞挖掘
设置了exported=”true”,或者添加了属性,但是并没有显示的设置为exported=”false”,此时Activity是导出的, 不合理的Activity组件导出导致的问题:
1 基于Android Brower Intent Scheme URLs攻击手段
利用了浏览器保护措施的不足,通过浏览器去调用应用自定义的scheme规范的链接启动Activity,把浏览器作为桥梁间接实现Intend-Based攻击,相比于普通Intend-Based攻击,这种方式更具隐蔽性,而且恶意代码隐藏WebPage中,传统的特征匹配完全不起作用;
2 拒绝服务
通过Intent给Activity传输畸形数据使得程序崩溃从而影响用户体验;
3 越权绕过
Activity用户界面绕过会造成用户的信息窃取,Activity界面被劫持产生欺诈等安全事件。比如在业务过程中会有一些敏感的界面是需要用户输入密码才能查看的,但是如果没有对调起此Activity的组件进行权限验证,那么就会造成验证的越权问题,导致恶意的攻击者不需要输入密码等信息也可以打开这个界面。
对于越权绕过的防护:私有Activity不应被其他应用启动,创建Activity时:设置exported属性为false;公开暴露的Activity组件,可以被任意应用启动,创建Activity:设置exported属性为true;谨慎处理接收的intent,有返回数据时不应包含敏感信息;不应发送敏感信息;当收到返回数据时谨慎处理。
组件导出导致钓鱼欺诈 :原理Activity栈,当新的Activity启动时,前一个Activity就会停止,压入历史栈,当用户按下back键时,顶部Activity弹出,恢复前一个Activity,栈顶指向当前的Activity。由于Activity的这种特性,如果启动一个Activity时,给它加入一个标志位FLAGACTIVITYNEW_TASK ,就能使它置于栈顶并立马呈现给用户,如果这个Activity是用与盗号的伪装Activity ,那么就会产生钓鱼安全事件或者是一个 Activity中有webview加载,如果允许加载任意网页也有可能会产生钓鱼事件。防护:可在onStop()及时提醒用户;
拒绝服务攻击:攻击者通过intent发送空数据,异常或畸形数据给受害者应用导致其崩溃。本地拒绝服务漏洞不仅可以导致安全防护等应用的防护功能被绕过或失效,而且也可被竞争方应用利用来攻击,使得自己的应用崩溃,造成不同程度的经济利益损失。防护:常见异常处理:空指针异常处理,类型转换异常(序列化),数组越界访问异常,类未定义异常等。
Android Intent Scheme URLs攻击原理及防护措施:这里就借鉴一篇博客。Android Intent Scheme URLs攻击
二 Service 漏洞挖掘
如果一个导出的Service没有做严格的限制,任何应用可以去启动并且绑定到这个Service上,取决于被暴露的功能这有可能使得一个应用去执行未授权的行为,获取敏感信息或者污染修改内部应用的状态造成威胁。Service漏洞分类:权限提升,services劫持,消息伪造,拒绝服务。
1 权限提升
当一个Service配置了Intent-filter默认是被导出的,如果没有对这个Service进行权限限制或者是没有对调用者身份进行有效的验证,那么构造恶意构造的App都可以对次Service传入恰当的参数进行调用,导致恶意行为。
2 services劫持
隐式启动serviece,当存在同名service,先安装应用的service优先级高。
3 消息伪造
暴露的Service对外接收Intent,如果构造恶意的消息放在Intent中传输,被调用的Service接受可能产生安全隐患。
4 拒绝服务
主要来源于Service启动时对接收的Intent等没有做异常情况下的处理,导致的程序崩溃。
主要体现的方面如给Service传输未null的Intent或者传输序列化对象导致接收时的类型转化异常。
安全防护
1. 私有service不定义intent-filter并且设置exported为false;
2. 公开的service设置exported为true,intent-filter可以定义或者不定义。
3. 合作service需对合作方的app签名做校验。
4. Service接收到的数据需谨慎处理。
5. 内部Service需使用签名级别的protectionLevel来判断是否来自内部应用的调用。
6. 不应该在Service创建(onCreate方法调用)的时候决定是否提供服务,应在onStartCommand/onBind/onHandleIntent等方法调用的时候做判断。
7. 当Service有返回数据的时候,应判断数据接受app是否有信息泄露的风险。
8. 有明确的服务需调用时使用显示意图。
9. 尽量不发送敏感信息。
10. 启动Service时不设置Intent的FLAG_ ACTIVITY_NEW_TASK标签。
三 Broadcast Receiver 漏洞挖掘
当发送一个广播时,系统会将发送的广播(Intent)与系统中所有注册符合条件的接收者的IntentFilter进行匹配,若匹配成功,将执行相应接收者的onReceiver函数。发送广播时如果处理不当,恶意应用便可以嗅探,拦截广播,致使敏感数据泄漏等;如果接收广播时处理不当,便可导致拒绝服务攻击,伪造消息,越权操作等。Broadcast Receiver漏洞分类:1. 敏感信息泄漏2. 权限绕过3. 消息伪造4. 拒绝服务
1 敏感信息泄漏
发送的Intent没有明确指定接收者,而是简单的通过action进行匹配。恶意应用便可以注册一个广播接收者嗅探拦截到这个广播,如果这个广播里存在敏感数据,就被恶意应用窃取了。
2 权限绕过漏洞
可以通过两种方式注册广播接收器,一种是在AndroidManifest.xml文件中通过<receiver/>标签静态注册。另一种是通过Context.registerReceiver()动态注册,指定相应的IntentFilter参数。然后动态注册的广播是默认导出的。如果导出的BroadcastReceiver没有做权限控制,导致BroadcastReceiver组件可以接受一个外部可控的url,或者其他命令,导致攻击者可以越权利用应用的一些特定功能,比如发送恶意广播,伪造消息,任意应用下载安装,打开钓鱼网张等。
3 消息伪造
暴露的Receiver对外接受Intent,如果构造恶意的消息放在Intent总传输,被调用的Receiver接收有可能产生安全隐患。
4 拒绝服务
如果敏感的BroadcastReceiver没有设置相应的权限保护,很容易收到攻击。传递恶意畸形的Intent数据给广播接收器,造成crash。
安全防护
1 修复代码,使用LocalBroadcastManager.sendBroadcast(…)发出广播只能被app自身广播接收器接收。
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
lbm.sendBroadcast(new Intent(LOCAL_ACTION));
2 推荐使用LocalBroadcastManager类来进行动态注册。
lbm.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// TODO Handle the received local broadcast
}
}, new IntentFilter(LOCAL_ACTION));
3 如果Receiver设置导出,则可以设置android:protectionLevel = “signature”
4 拒绝服务攻击防护如上
四 Content Provider漏洞挖掘
Content Provider起到在应用程序间共享数据的作用,通过Binder进程间通信机制以及匿名共享内存机制来实现。Content Provider组件本身提供读写权限控制,但是它的控制粒度是比较粗的。漏洞分类:1. 信息泄漏2. Sql注入3. 目录遍历
1 信息泄漏
content URI是一个标志Provider数据的URI。Content URI中包含了整个Provider的以符号表示的名字(authority)和指向一个表的名字(一个路径)。如果对Content Provider的权限没有做好控制,就有可能导致恶意程序通过这种方式读取app的敏感数据。
所有联系人的Uri:content://contacts/people
某个联系人的Uri:content://contacts/people/5
所有图片Uri:content://media/external
某个图片的Uri:content://media/external/images/media/4
2 SQL注入漏洞
对Content Provider进行增删改查时,程序没有对用户的输入进行过滤,未采用参数滑查询的方式,可能导致sql注入攻击。所谓的Sql注入攻击指的是攻击者可以精心构造selection参数,projection参数以及其他有效的SQL语句组成部分,实现未授权的情况下从Content Provider获取更多信息。
3 目录遍历漏洞
Android Content Provider存在文件目录遍历安全漏洞,该漏洞源于对外暴露Content Provider组件的应用,没有对Content Provider组件的访问进行权限控制和对访问的目标文件的Content Query Uri进行有效判断,攻击者利用该应用暴露的Content Provider的openFile()接口进行文件目录遍历以达到访问任意可读文件的目的;
漏洞位置: ContentProvider.openFile(Uri uri, String mode)
漏洞触发前提条件:
1. 对外暴露的Content Provider组件实现了openFile()接口;
2. 没有对所访问的目标文件Uri进行有效判断,如没有过滤限制如“../”可实现任意可读文件的访问的Content Query Uri;
漏洞原理:对外暴露的Content Provider实现了openFile()接口,因此其他有相应调用该Content Provider权限的应用即可调用Content Provider的openFile()接口进行文件数据访问。但是如果没有进行Content Provider访问权限控制和对访问的目标文件的Uri进行有效判断,攻击者利用文件目录遍历访问任意可读文件。
安全防护
1. 不向外部app提供数据的私有content provider显示设置exported = “false”,避免组件暴露。
2. 内部app通过content provider交换数据时,设置protectionLevel = “signature”验证签名。
3.公开的content provier确保不存储敏感数据。
4.应避免SQLiteDatabase.rawQuery()进行查询,而应该使用编译好的参数化语句。
使用预编译好的语句比如SQLiteStatement,不仅可以避免SQL注入,而且操作性能上也大幅提高,因为不用每次都进行解析。另一个方法是使用query(),insert(),update()和delete()方法,因为这些函数也提供了参数化的语句。
5.去除没有必要的openFile()接口
6.过滤限制跨域访问,对访问的目标文件的路径进行有效判断
7. 设置权限来进行内部应用通过Content Provider的数据共享
使用签名验证来控制Content Provider共享数据的访问权限:设置protectionLevel=”signature”;