跟着大神学App安全测试,事半功倍(二)

发表于:2020-12-21 10:14

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:book4yi    来源:简书

  4、组件安全:
  本项主要测试客户端是否包含后台服务、ContentProvider、第三方调用和广播等组件,Intent权限的设置是否安全。应用不同组成部分之间的机密数据传递是否安全。检查客户端是否存在组件劫持风险,查看客户端程序具有导出哪些应用信息的权限。反编译APK文件后,检查AndroidManifest文件中是否有多余的android:export声明,客户端是否存在导出其他应用信息的权限等。
  应用组件是组成安卓应用的关键部分。每个应用都是由一个或者多个组件组成,并且每个都是单独调用。这里主要分为4个主要的组件:
  1)、Activity:在屏幕上提供一个区域,提供一个可视化界面供我们点击,访问。
  2)、Service:服务是一种在后台运行的组件,用于执行长时间运行的操作或为远程进程执行作业。相当于你在听歌的时候,退出界面后,歌还继续放着,这就是服务的作用。
  3)、contentprovider:简单的来说就是管理数据的一个程序,除了放在SD卡里的数据,手机原本的或者各个程序之间的数据都是很封闭的,但是他们又不能完全封闭,因此使用内容提供程序进行封装,一般用sqlite进行报存数据。以表格的形式把数据展现给外部的应用。换句话来说ContentProviders可以被认为是连接两个处理器的之间的接口。
  4)、BroadcastReceiver:其实就是广播,它们可以创建状态栏通知,在发生广播事件时提醒用户,就像你手机里时不时会从屏幕上方发来一条推送,这就是这个组件最重要的功能。广播接收器是一个接受系统级广播的组件,(例如电量低,重启,耳机插入等)尽管大部分广播都是由系统发出,应用本身也可以发起广播。
  小结一下,安卓系统的其四大组件的主要用途分别为:
  Activity:呈现可供用户交互的界面,是最常见的组件;
  Service:长时间执行后台作业,常见于监控类应用;
  ContentProvider:在多个APP间共享数据,比如通讯录数据;
  BroadcastReceiver:注册特定事件,并在其发生时被激活;
  打开AndroidManifest.xml,查看对其中声明的各个组件,根据以下规则判断是否可导出:
  显式声明了android:exported="true",则可导出;
  显示声明了android:exported="false",则不可导出;
  未显示声明android:exported:
  a)若组件不是ContentProvider:
  若组件包含<intent-filter>则可导出,反之不可;
  b)若组件是ContentProvider:
  若SDK版本<17则可导出,反之不可。
  从测试的角度上,只能判断组件是否导出,但能否构成危害需要详细分析源代码后才能得出结论。一般来说,在测试时尽管写清所有的导出组件,由客户开发侧确认相关组件是否确实需要导出即可。
  由于功能需要,启动Activity和ContentProvider大多是导出组件,一般无须理会。
  并不是说所有导出的组件都是不安全的,如果要确定,必须看代码,对代码逻辑进行分析一般直接用drozer进行测试即可。
  Activity组件:
  主要测试在未经登录的情况下,该activity是否被正常显示,且是否会造成越权、信息泄露等风险。如果存在,停止测试,记录漏洞
  Service:
  是没有界面且能长时间运行于后台的应用组件.其它应用的组件可以启动一个服务运行于后台,即使用户切换到另一个应用也会继续运行.另外,一个组件可以绑定到一个service来进行交互,即使这个交互是进程间通讯也没问题.例如,一个service可能处理网络事物,播放音乐,执行文件I/O,或与一个内容提供者交互,所有这些都在后台进行。
  检查有没有export的Service:
  ·检查AndroidManifest.xml文件中注册的Service(MobSF)
  ·检查有没有export的Service查看service类,重点关注onCreate/onStarCommand/onHandleIntent方法
  检测是否有数据泄露的可能:
  ·检测有没有处理不当的方法检索所有类中startService/bindService方法及其传递的数据。
  BroadcastReciever:
  广播接收器是一个专注于接收广播通知信息,并做出对应处理的组件。很多广播是源自于系统代码的──比如,通知时区改变、电池电量低、拍摄了一张照片或者用户改变了语言选项。应用程序也可以进行广播──比如说,通知其它应用程序一些数据下载完成并处于可用状态。应用程序可以拥有任意数量的广播接收器以对所有它感兴趣的通知信息予以响应。所有的接收器均继承自BroadcastReceiver基类。广播接收器没有用户界面。然而,它们可以启动一个activity来响应它们收到的信息,或者用NotificationManager来通知用户。通知可以用很多种方式来吸引用户的注意力──闪动背灯、震动、播放声音等等。一般来说是在状态栏上放一个持久的图标,用户可以打开它并获取消息。
  查找静态BroadcastReceiver:
  检查AndroidManifest.xml文件中注册的BroadcastReceiver,查找动态BroadcastReceiver:
  runapp.broadcast.info-aAPP包名
  查找发送广播内的信息检索sendBroadcast与sendOrderedBroadcast:
  注意检索setPackage方法与receiverPermission变量。
  runapp.broadcast.send--componentcom.package.name--actionandroid.intent.action.XXX
  检测是否存在信息泄露或拒绝服务的问题:
  查看onReceive方法
  测试方法:
  1、反编译后检索registerReceiver(),查找动态广播接收器,或者直接使用drozer:runapp.broadcast.info-aAPP包名
  2、尝试向应用程序的receiver组件发送空值,ambroadcast-aMyBroadcast-n
  com.isi.vul_broadcastreceiver/.MyBroadCastReceiver,查看是否能够造成应用程序崩溃,形成拒绝服务
  ContentProvider:
  AndroidContentProvider存在文件目录遍历安全漏洞,该漏洞源于对外暴露ContentProvider组件的应用,没有对ContentProvider组件的访问进行权限控制和对访问的目标文件的ContentQueryUri进行有效判断,攻击者利用该应用暴露的ContentProvider的openFile()接口进行文件目录遍历以达到访问任意可读文件的目的。在使用ContentProvider时,将组件导出,提供了query接口。由于query接口传入的参数直接或间接由接口调用者传入,攻击者构造sqlinjection语句,造成信息的泄漏甚至是应用私有数据的恶意改写和删除。
  静态检测:
  1、查看AndroidManifest.xml文件,定位各Provider,尤其是设置了android:exported="true"的
  2、在反编译后使用关键字:addURI查找
  动态检测:
  主要通过drozer测试是否存在URI数据泄露、目录遍历、SQL注入风险。
  如果能够正确访问到共享资源,并且具备敏感信息,则记录漏洞。
  .Intent本地拒绝服务检测:
  Android应用本地拒绝服务漏洞源于程序没有对Intent.getXXXExtra()获取的异常或者畸形数据处理时没有进行异常捕获,从而导致攻击者可通过向受害者应用发送此类空数据、异常或者畸形数据来达到使该应用crash的目的,简单的说就是攻击者通过intent发送空数据、异常或畸形数据给受害者应用,导致其崩溃。
  通过使用drozer工具查看对外暴露组件的应用如下:
  runapp.activity.info-acom.mwr.example.sieve
  grep-rn"get*Extra"./|more#(在导出组件代码中测试)-检测在获取intent数据时是否进行了异常处理
  测试方法:
  1、使用反编译工具打开应用,反编译出应用源码。
  2、在源码中查找以下示例源码(主要查找getAction):
Intent i = new Intent();
if (i.getAction().equals("TestForNullPointerException")) {
 Log.d("TAG", "Test for Android Refuse Service Bug");
}
  3、如出现像以上代码,getIntent()的intent附带空数据、异常或畸形数据,而且处理。
  getXXXExtra()获取的数据时没有进行异常捕获,便存在风险。
  4、如果服务端出现崩溃界面,则可以证明漏洞存在。记录漏洞,停止测试。
  同样可以造成本地拒绝服务的有:
  ClassNotFoundException异常导致的拒绝服务
  源于程序没有无法找到从getSerializableExtra()获取到的序列化类对象的类定义,因此发生类未定义的异常而导致应用崩溃。
  漏洞应用代码片段:
  <pre><code>Intenti=getIntent();
  getSerializableExtra("serializable_key");
  攻击应用代码片段:
Intent i = new Intent();
i.setClassName("com.alibaba.jaq.pocforrefuseservice", 
"com.alibaba.jaq.pocforrefuseservice.MainActivity");
i.putExtra("serializable_key", BigInteger.valueOf(1));
startActivity(i);

  本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理。
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号