Android安全测试工具-Drozer
Drozer简介
drozer是一款针对Android
系统的安全测试框架,它能够通过自身实现的协议,与Android
虚拟机进行交互扫描应用各种漏洞。
特点
- 更快的Android安全评估:
drozer
可以大大缩减Android
安全评估的耗时,通过攻击测试暴露Android APP
的漏洞。 - 支持真机模拟器:
drozer
运行在Android
模拟器和真实设备上。 - 自动化和扩展:
drozer
有很多扩展模块,可以发现更多Android
安全问题。
基本架构
从本质上来看,Drozer
是一C/S
架构的程序。安装在PC
端的Drozer
处理用户的各种操作,并将这些操作按照一定的格式进行封装,发送到手机端。手机端的Agent
收到请求后,对请求进行解包,然后执行请求,并将结果返回到Drozer
端。
安装配置
环境要求
- jdk1.6以上
- python2.7
- Android SDK环境
安装步骤
安装drozer
- 下载地址:https://labs.mwrinfosecurity.com/tools/drozer/ 下载对应的系统版本即可,
- 安装时
Python
依赖路径选择,如果安装了python3
需要切换到Python2
路径
安装依赖库
安装VCForPython27.msi,由于
Twisted
对此文件有依赖,所以需要安装。安装
protobuf pyOpenSSL Twisted service_identity
需要使用Python2
的pip
安装。
1 | C:\Python27\Scripts |
- 如果安装上述的包出现超时报错,如下所示,可以切换到国内源如中科大源。
1 | ReadTimeoutError: HTTPSConnectionPool(host='files.pythonhosted.org', port=443): Read timed out. |
替换源之后的命令如下:
1
pip2 install protobuf pyOpenSSL Twisted service_identity -i https://pypi.mirrors.ustc.edu.cn/simple/
打开
cmd
进入Python2
的目录,输入命令drozer
看到如下命令说明安装成功。
1 | C:\Python27 |
设备安装agent
- 下载安装agent:下载地址
- 到手机打开启agent,如下图右下角按钮显示为
开启
状态(如果显示为关闭,在其上点击将其切换为开启即可)
- 点击底部
Embedded Server
然后点击顶部开关Disabled
使其变为Enabled
连接设备
打开cmd命令窗口,依次执行如下命令
- 设置端口转发
1
2adb forward tcp:31415 tcp:31415
- 连接设备看到如上显示,说明启动成功,下一步则可以进行测试。如果想提出
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20λ drozer console connect
Selecting 51f681da4fb98aad (vivo vivo X21A 8.1.0)
.. ..:.
..o.. .r..
..a.. . ....... . ..nd
ro..idsnemesisand..pr
.otectorandroidsneme.
.,sisandprotectorandroids+.
..nemesisandprotectorandroidsn:.
.emesisandprotectorandroidsnemes..
..isandp,..,rotectorandro,..,idsnem.
.isisandp..rotectorandroid..snemisis.
,andprotectorandroidsnemisisandprotec.
.torandroidsnemesisandprotectorandroid.
.snemisisandprotectorandroidsnemesisan:
.dprotectorandroidsnemesisandprotector.
drozer Console (v2.4.4)
dz>drozer
命令模式,则输入指令exit
即可退出。
安全测试
APP攻击面分析
分析Android
四大组件是否能被其他的的应用程序调用。
1 | dz> run app.package.attacksurface com.xxx.xxxx |
结果显示了潜在可以利用的组件个数: exported
表示组件可以被其他App使用。 is debuggable
表示我们可以用adb
绑定一个调试器到进程。
Activity组件暴露
Activity简介
应用程序中,一个Activity
通常就是一个单独的界面,它上面可以显示一些控件也可以监听并处理用户的事件做出响应。Activity
之间通过Intent
进行通信。在Intent
的描述结构中,有两个最重要的部分:action
和action
对应的数据。
Activity组件暴露概述
风险描述
Activity
组件的属性exported
被设置为true
或是未设置exported
值但Intent-filter
不为空时,activity
被认为是导出的,可通过设置相应的Intent
唤起activity
。
查看下反编译出的AndroidManifest.xml
文件,可看到将activity
的exported
设置为true
。说明存在被导出的风险。
1 | <activity android:exported="true" android:label="@string/view_checkin" android:name=".activities.ViewCheckin"/> |
危害描述
黑客可能构造恶意数据针对导出activity
组件实施越权攻击。
修复建议
如果组件不需要与其他app
共享数据或交互,请将AndroidManifest.xml
配置文件中设置该组件为exported = “False”
。如果组件需要与其他app
共享数据或交互, 请对组件进行权限控制和参数校验。
案例演示
我们测试的应用为 InsecureBankv2,供安全爱好者和开发人员通过测试此易受攻击的应用程序来学习Android
不安全性。它的后端服务器组件是用python
编写的。它与Python2
兼容。
注意:电脑上安装了杀毒软件,会将该
apk
视为病毒,忽略就好。
下载地址: Android-InsecureBankv2 选择最新版本安装下载即可。
查看对外的activity组件信息
使用命令:run app.activity.info -a xxx
可以查看对外的activity
组件信息。
1 | dz> run app.activity.info -a com.android.insecurebankv2 |
越权漏洞检测
我们可以通过命令run app.activity.start
调用activity
组件,命令具体用法如下:
1 | dz#> run app.activity.start --component 包名 Activity名 |
针对测试包,我们绕过登录界面导致可直接访问,说明存在越权漏洞。命令如下:
1 | run app.activity.start --component com.android.insecurebankv2 com.android.insecurebankv2.PostLogin |
登录之前的界面如下:
执行命令之后,直接进入到登录之后页面,界面如下:
BroadcastReceiver组件暴露
Broadcast简介
BroadcastReceiver
消息组件,应用可以使用它对外部事件进行过滤,只对特定的外部事件(如当电话呼入时,或者数据网络可用时)进行接收并做出响应。消息组件没有用户界面。然而,它们可以启动一个activity
或serice
来响应它们收到的信息,或者用NotificationManager
来通知用户。
通知可以用很多种方式来吸引用户的注意力──闪动呼吸灯、震动、播放声音等。一般来说是在状态栏上放一个持久的图标,用户可以打开它并获取消息。
BroadcastReceiver漏洞概况
风险描述
BroadcastReceiver
组件的属性exported
被设置为true
或是未设置exported
值但intent-filter
不为空时,BroadcastReceiver
被认为是导出的。
危害描述
导出的消息组件可以导致数据泄漏或者是越权。
修复建议
如果组件不需要与其他app
共享数据或交互,请将AndroidManifest.xml
配置文件中设置该组件为exported = “False”
。如果组件需要与其他app
共享数据或交互, 请对组件进行权限控制和参数校验。
案例演示
测试应用
拒绝服务攻击检测测试包 FourGoats
为OWASP的项目,集成了一堆漏洞的APK
,代码未经过混淆与加密,可以反编译后看到比较清晰的逻辑,分析漏洞成因。虽然是许多年前的项目,很多漏洞也早已消失,但对于入门的新手来说还是有一定的价值的。
Apk下载地址:FourGoats.apk
获取Broadcast信息
查看
Broadcast
具体信息,找到广播的类名,以及注册的Intent
的动作。1
2
3
4
5
6
7dz> run app.broadcast.info -a org.owasp.goatdroid.fourgoats -i
Package: org.owasp.goatdroid.fourgoats
org.owasp.goatdroid.fourgoats.broadcastreceivers.SendSMSNowReceiver
Intent Filter:
Actions:
- org.owasp.goatdroid.fourgoats.SOCIAL_SMS
Permission: null查看反编译的
AndroidManifest.xml
文件,可看到将receiver
的exported
设置未进行设置。说明存在越权问题,可发送恶意广播,伪造消息等等。
1 | <receiver android:label="Send SMS" android:name=".broadcastreceivers.SendSMSNowReceiver"> |
- 反编译
apk
文件,然后查看broadcast
的源代码,从中可以看到短信发送需要的关键字:phoneNumber
和message
1 | package org.owasp.goatdroid.fourgoats.broadcastreceivers; |
经过以上三步我们获取到的信息有:
action
动作名称为:org.owasp.goatdroid.fourgoats.SOCIAL_SMS
component
组件名称为:org.owasp.goatdroid.fourgoats.broadcastreceivers.SendSMSNowReceiver
intent
意图传递的参数为:phoneNumber
和message
执行broadcast攻击
- 根据上面掌握的信息,就可以构造短信发送的广播,在
drozer
中使用如下命令:
1 | run app.broadcast.send --action org.owasp.goatdroid.fourgoats.SOCIAL_SMS --extra string phoneNumber 10010 --extra string message hacked! |
- 上面命令表示向手机号为
10010
的用户发送短信,内容为:hacked!
,同时在App界面可以看到Toast
提示:Your text message has been send!
- 尝试拒绝服务攻击检测,向广播组件发送不完整
intent
使用空extras
,可看到应用停止运行。
1 | run app.broadcast.send --action org.owasp.goatdroid.fourgoats.SOCIAL_SMS |
Service组件
service简介
Service
是一段长生命周期的没有用户界面的程序,可以用来开发如监控类程序。 比如一个正在从播放列表中播放歌曲的媒体播放器。在一个媒体播放器的应用中有多个activity
,让使用者可以选择歌曲并播放歌曲。然而音乐续播这个功能并没有对应的activity
,因为用户当然会认为在切换到其它界面时音乐应该还在后台播放的。
在这个例子中,媒体播放器这个activity
会使用Context.startService()
来启动一个service
,从而可以在后台保持音乐的播放。同时,系统也将保持这个service
一直执行,直到这个service
运行结束。
另外,我们还可以通过使用Context.bindService()
方法,连接到一个service
上(如果这个service
还没有运行将启动它)。当连接到一个service
之后,我们还可以使用service
提供的接口与它进行通讯。拿媒体播放器这个例子来说,我们还可以进行暂停、切换等操作。
Service组件暴露
风险描述
Service
组件的属性exported
被设置为true
或是未设置exported
值但Intent-Filter
不为空时,Service
被认为是导出的,可通过设置相应的Intent
唤起Service
。
危害描述
黑客可能构造恶意数据针对导出Service
组件实施越权攻击。
修复建议
如果组件不需要与其他app
共享数据或交互,请将AndroidManifest.xml
配置文件中设置该组件为exported = “False”
。如果组件需要与其他app共享数据或交互, 请对组件进行权限控制和参数校验。
AndroidManifest检测
我们使用之前的测试应用FourGoats.apk
, 查看反编译的AndroidManifest.xml
文件,可以看出: intent-filter
不为空且未将exported
设置为false
,所以services
默认是导出的,org.owasp.fourgoats.goatdroid.LocationService
服务被导出,不需要任何权限。
这意味着恶意应用程序可以通过FourGoats
应用程序访问设备的位置。
1 | <service android:name=".services.LocationService"> |
同样使用run app.service.info -a [pkg]
可以查看对外暴露的service
组件。
1 | dz> run app.service.info -a org.owasp.goatdroid.fourgoats |
案例演示
调用服务组件进行拒绝服务攻击
使用命令 run app.service.start --action 服务名 --component 包名 服务名
我们可以对被导出的服务org.owasp.goatdroid.fourgoats.services.LocationService
执行攻击。
1 | dz> run app.service.start --action org.owasp.goatdroid.fourgoats.services.LocationService --component org.owasp.goatdroid.fourgoats org.owasp.goatdroid.fourgoats.services.LocationService |
执行完成之后,可以看到App直接崩溃。Android
应用使用Intent
机制在组件之间传递数据,如果应用在使用getIntent(),getAction(),Intent.getXXXExtra()
获取到空数据、异常或者畸形数据时没有进行异常捕获,应用就会发生Crash
,应用不可使用(本地拒绝服务)。恶意应用可通过向受害者应用发送此类空数据、异常或者畸形数据从而使应用产生本地拒绝服务。
当应用被恶意应用攻击时,本地拒绝服务一般会导致正在运行的应用崩溃,首先影响用户体验,其次影响到后台的Crash统计数据,另外比较严重的后果是应用如果是系统级的软件,可能导致手机重启。
ContentProvider组件
ContentProvider简介
Android
平台提供了Content Provider
使一个应用程序的指定数据集提供给其他应用程序。这些数据可以存储在文件系统中或存在一个SQLite
数据库。
其他应用可以通过ContentResolver
类从ContentProvider
中获取或存入数据, 只有需要在多个应用程序间共享数据是才需要ContentResolver
。
例如:通讯录数据被多个应用程序使用,必须存储在一个ContentResolver
中它的好处就是统一数据访问方式。
ContentProvider组件暴露
风险描述
Content Provider
组件的属性exported
被设置为true
或是Android API<=16
时,Content Provider
被认为是导出的。
危害描述
黑客可能访问到应用本身不想共享的数据或文件。
修复建议
如果组件不需要与其他app共享数据或交互,请将AndroidManifest.xml
配置文件中设置该组件为exported = “False”
。如果组件需要与其他app共享数据或交互, 请对组件进行权限控 制和参数校验。
案例演示
测试背景
这里我们使用drozer
官方提供的测试应用sieve
进行测试,这是一个密码管理工具,是官方用于展示常见安卓应用漏洞的应用。
下载地址:sieve.apk
获取Content Provider与URI
- 首先获取
Content Provider
信息,命令如下:
1 | dz> run app.provider.info -a com.mwr.example.sieve |
- 从上面扫描可以看到有
2
个Content Provider
:
com.mwr.example.sieve.DBContentProvider
com.mwr.example.sieve.FileBackupProvider
第一个是数据库相关,第二个是文件备份数据相关。
- 获取
URI
(统一资源标识符)列表,命令如下:
1 | dz> run scanner.provider.finduris -a com.mwr.example.sieve |
- 根据上面的扫描结果,存在
Accessible content URIs
说明存在注入风险。
执行攻击
- 打开
sieve
应用,输入password
(至少16位)和pin
- 我们获取
URI
数据如下所示,即可查到我们输入的password
和pin
的具体值。
1 | dz> run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Keys/ |
- 因为
Password
更改时有长度限制,至少16
位,看起来似乎是比较安全的,可这只是表面上的。
我们可以使用命令直接修改password
数据,运行:
1 | dz> run app.provider.update content://com.mwr.example.sieve.DBContentProvider/Keys/ --selection pin=1234 --string Password 12345 |
- 再次查询时发现密码已经被更改了,并且也不会限制密码的长度为至少
16
位了。
1 | dz> run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Keys/ |
检查是否有sql注入
SQL
注入是比较常见的网络攻击方式之一,它不是利用操作系统的BUG
来实现攻击,而是针对程序员编写时的疏忽,通过SQL
语句,实现无账号登录甚至篡改数据库等非法操作。
可以使用如下命令扫描查询是否存在SQL
注入
1 | dz> run scanner.provider.injection -a com.mwr.example.sieve |
检查是否存在遍历文件的漏洞
1 | dz> run scanner.provider.traversal -a com.mwr.example.sieve |
同样content
可能导致SQL
注入问题,使用以下语句进行测试发现报错,说明存在SQL
注入漏洞。
1 | dz> run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --projection "'" |
参考资料
- https://www.jianshu.com/p/4cddc928df06
- https://testerhome.com/topics/2209
- https://www.cnblogs.com/misswangxing/p/7712318.html
- https://labs.mwrinfosecurity.com/tools/drozer/
- https://labs.mwrinfosecurity.com/assets/BlogFiles/mwri-drozer-user-guide-2015-03-23.pdf
- https://bbs.pediy.com/thread-219107.html
- http://appscan.360.cn/vulner/list/
- https://developer.aliyun.com/article/20461
- https://testerhome.com/topics/10934
- https://xuanxuanblingbling.github.io/ctf/android/2018/02/12/Android_app_part1/
- http://www.atomsec.org/android/android%E5%BA%94%E7%94%A8%E5%AE%89%E5%85%A8%E7%B3%BB%E5%88%97-part-18-%E6%94%BB%E5%87%BBbroadcast-receivers/
- https://zgjx6.github.io/2018/01/16/%E5%88%A9%E7%94%A8drozer%E8%BF%9B%E8%A1%8Candroid%E6%B8%97%E9%80%8F/