利用工具分析Android App,以发现漏洞和开发漏洞利用代码。
1.概述
(1)主要内容
- 收集logcat泄露的信息
- 检查网络流量
- 通过activity manager被动嗅探intent
- 攻击service
- 攻击broadcast receiver
- 枚举有漏洞的content provider
- 从有漏洞的content provider中提取数据
- 向content provider中插入数据
- 枚举有SQL注入漏洞的content provider
- 利用可调试的App
- 对App做中间人攻击
(2)App中存在的攻击面/安全目标
- 保护用户数据(如口令、认证令牌、联系人、通信记录、敏感服务器的IP地址或域名等)
- App间的保护(隔离和权限分离)
- 保护敏感信息的通信(组件间通信(可以通过intent和intent filter来完成)、App间通信、与其他设备进行通信)
2.内容要点
(1)收集logcat泄露的信息
adb logcat
adb logcat [options] [filter]
adb logcat > output.txt
,把日志的输出转存到一个文件中去。adb logcat | [其他程序]
,利用“管道”把日志信息输入到另一个程序中去。(如adb logcat | grep [pattern]
)- 例如,下述例子可以帮助过滤给出日志文件中与Web相关的信息,
adb logcat | grep [Cc]ookie
、adb logcat | grep "http[s]"
、adb logcat | grep "ftp[s]"
(2)使用Monkey框架对App进行测试
adb shell monkey -p [package] -v [event count]
,其中[package]是你想要把事件发送给它的package或app的名称,而[event count]是你想要发送的随机事件的数量。
(3)检查网络流量
主要工具
- Wireshark
- Netcat
- TCPdump for Android
主要步骤
在首次进行上述步骤,配置完所有操作环境后,后面再想监听网络流量就只需要进行第三步和第六步了,也即是依次执行下面2条命令。
./data/tcpdump/tcpdump -w - | nc -l -p 31337
adb forward tcp:12345 tcp:31337 && nc 127.0.0.1 12345 | wireshark -k -S -i -
对于上述主要步骤中的命令参数的补充说明
- 关于adb push tcpdump /data/tcpdump/.
- 关于./data/tcpdump/tcpdump -w - | nc -l -p 31337
- 关于wireshark -k -S -i -
(4)通过activity manager被动嗅探intent
准备
需要给drozer的手机端代理添加android.permission.GET_TASKS
权限,有以下两种方式。
- 因为agent.apk并没有加壳和混淆,所以可以直接利用AndroidKiller工具对其Manifest文件进行修改,然后重新编译apk。
- 将其源码导入Android Studio,然后修改编译生成apk。
在将源码导入Android Studio中时,从导入到成功编译过程中遇到了很多问题,折腾了将近一天。所以说环境问题真的太让人无语了。。。。。。
接下来是在这个过程中遇到的各种问题的记录。
关于报错Expected caller to ensure valid ABI: MIPS
——最新版本的ndk去除了MIPS的编译工具,升级到最新的gradle版本可以解决。
NDK android Error:Expected caller to ensure valid ABI: MIPS
ndk r17版本不再支持mips
Expected caller to ensure valid ABI: MIPS
关于报错No toolchains found in the NDK toolchains folder for ABI with prefix: mips64el-linux-android
——详细解决见下面的链接。
完美解决 No toolchains found in the NDK toolchains folder for ABI with prefix: mips64el-linux-android
关于报错No such property: javaCompilerTask for class: com.android.build.gradle.internal.variant.TestVariantData
——在gradle.build文件中将protobuf-gradle-plugin的版本增加到至少0.8.6。
关于报错Unable to find method 'org.gradle.api.tasks.compile.CompileOptions.setBootClasspath(Ljava/lang/String;)V'
——将android Gradle插件升级到3.4.0版本和Gradle 5.1.1。
关于报错Could not find com.android.tools.build:gradle:5.1.1
——应该在build.gradle文件中指定版本为3.4.0,在gradle-wrapper.properties文件中设置版本为5.1.1。
gradle下载
Android Studio中的Gradle版本和更新
Could not find com.android.tools.build:gradle:5.1.1
关于报错Configuration with name 'prodDebugAndroidTestCompile' not found
——将protobuf0.8.0升级到0.8.2。
Configuration with name ‘prodDebugAndroidTestCompile’ not found
关于报错Issue when compiling: minSdk version should not be declared in the android manifest
——在AndroidManifest文件中删除申明的minSDK项。
Issue when compiling: minSdk version should not be declared in the android manifest
关于报错ERROR: CreateProcess error=2, 系统找不到指定的文件。
——通过在网上查找资料,先后尝试卸载NDK、在Android Studio中添加git.exe路径,最终添加git路径解决了该问题。
全面介绍Android Studio中Git 的使用(一)
android studio运行程序时CreateProcess error=2, 系统找不到指定的文件
请教 导入Sample Error:(19, 0) CreateProcess error=2, 系统找不到指定的文件。
关于报错ERROR: Directory xxx specified for property xxx does not exist
——折腾了很久,最后发现是没有在电脑上安装protobuf的原因。然后去看了drozer开源项目的readme,发现环境的确是需要安装protobuf的,下次要仔细阅读安装说明才行。
关于报错Could not find com.android.tools.build:gradle:3.1.4
——在项目的 build.gradle 文件中,添加 google() 依赖项。
关于报错Cannot run program "protoc": CreateProcess error=2, 系统找不到指定的文件。
——一是因为我当时并没有在电脑上安装protobuf,二是因为我安装的protobuf的版本不符合项目需求,但去查阅官方安装说明文档,2.6.1及以上的版本都是满足的,而我安装的是3.3.0的,按理说不会存在版本不合适的问题呀,具体原因参见下一个问题。
关于报错错误: 程序包com.google.protobuf.GeneratedMessageV3不存在
——这是因为不仅需要在电脑上安装protobuf,还需要在Android项目的lib文件夹中添加对应版本的jar文件(如protobuf-java-3.3.0.jar
),而我后来在电脑上安装的是3.3.0版本的protobuf,从github上下载下来的drozer-agent项目中自带的是2.6.1版本的jar,所以会报错。只需要将其中的jar文件替换成对应的版本,然后在build.gradle文件中修改对应的依赖项的版本信息即可。补充:在最开始没搞清楚具体原因时,为了解决这个问题,我还尝试在Android Studio中安装Protobuf Support插件,但这个好像只是一个用于支持.proto格式的文件操作的,所以对于解决问题并没有什么帮助。
Intellij IDEA中使用Protobuf的正确姿势
Android Studio 三种添加插件的方式
Protocol Buffer V3.3.0 在Andoroid中的使用介绍
protobuf-java-3.3.0.jar下载、源码下载
关于错误gradle could not expand zip
——这是因为在解决上一个错误的过程中,最后忽略了还要修改build.gradle文件中对应的依赖项的版本信息,导致即使在项目中将2.6.1版本的jar替换成3.3.0的jar,项目在编译时还是尝试去寻找2.6.1版本的jar文件,改变其版本信息即可。
实现一个intent嗅探模块
模块代码
代码说明
各种问题
在将上述自定义模块安装到drozer中去的时候又碰到了问题。
首先是在利用module install [路径]文件名
安装模块时,并没有任何报错信息,直接输出Successfully installed 0 modules, 0 already installed.
,后来利用python运行对应python代码,发现是python代码存在语法错误,于是改正代码中的语法错误。
python错误之SyntaxError: invalid syntax
wiki doesn’t demonstrate how to call your module
关于报错Failed to get module for
,具体报错如下图,提示找不到待安装的模块,这个一是因为我最开始利用module repository create [路径]
创建目录时,并没有创建成功;二是因为待安装的文件不能放在创建的目标目录下,而是应该放在另外的目录中。
安装成功之后报错如下图所示。——关于这个错误,我尝试重新换一个自定义模块进行安装运行,结果就没有出现这个错误了,但出现了下面的错误。
关于如下图所示的报错,是因为在安装jdk的时候,当时系统默认的路径中包含了空格,所以会报错,想解决的话可以重装jdk(注意空格问题)。
针对上面那个报错的脚本,在虚拟机上重新安装到drozer中,成功运行,但是最上面那个Skipping source file at ex.sniffer.intents. Unable to load Python module.
的报错还是没有解决,猜测是因为脚本的编写有问题,估计是导入的库缺失导致的报错。
在解决上述问题后,还剩以下2个问题没有解决。
在网上学习其他人的教程时,发现他们提到的有些模块我的电脑上安装的drozer并没有包含,后来发现这些属于第三方开发者开源的插件,在这里可以找到,将其下载下来安装到本机drozer中即可。另外在这里可以找到几个官方自带的插件。
另外,不清楚怎么卸载安装的自定义模块,后来发现直接在repository目录中删除模块对应的python文件即可。
本以为完事大吉,结果在虚拟机santoku中安装drozer模块时又遇到以下问题。
在成功安装完模块后,运行所有drozer命令都会报如下图所示的错误。——本来以为已经绕过这个错误了,结果看来不解决是不行了。网上并没有相关的解答,唯一能查到的解答感觉又不符合我的情况。捣鼓了很久终于发现原因:只要自定义模块名字的第一部分和drozer自带的模块的命名相同(这里注意两个自定义模块相同则并不会产生这样的错误),就会出现这样的报错,我将要安装的模块的名字由scanner.misc.weburls
改为exp.misc.weburls
,终于安装成功了,简直开心哈哈哈。
(5)攻击service
主要内容:列出APP中导出的services,通过drozer框架编写一些定制的intent去触发这些services。
主要步骤
- 寻找手机上各个app中导出的services:run app.service.info –permission null。
- 在1中得到的结果中选定目标services,反编译对应apk,在其AndroidManifest.xml文件中获取目标service的
intent filter
等信息,构造命令启动service,具体命令如下图。
注:某些 service可能扮演的是原生库接口的角色—它会把从 intent中接收到的数据转换成类似基于堆或栈的变量的C/C++数据结构。在审计这类 service的安全性时,你一定要尝试识别出由于 intent中的数据,而导致的任何潜在的**内存溢出漏洞。**
(6)攻击broadcast receiver
在发掘 broadcast receiver中的漏洞时,最大的问题是确定输入是否可信,以及破坏性有多强。要做到这一点,你必须要去阅读源码,或是想办法有效地搞清你的目标app中,相关 broadcast receiver中的 intent filter的定义。如果你成功地搞定了它,接下来就该去分析 broadcast receiver会对哪类数据进行操作,以及它是如何进行操作的。
实例
对于GoatDroid项目中存在的如下图所示的漏洞进行利用。
(7)关于content provider(1-4是递进的关系)
1.枚举有漏洞的content provider
如下图运行结果所示。
2.从有漏洞的content provider中提取数据
在上一步中获取到一些目标uri后,可通过下述命令进行测试。
- run app.provider.query [URI]——尝试提取URI中的数据;
3.向content provider插入数据
- 在向content provider插入数据前,我们需要用以下命令获取数据的结构及各列的名称等信息:run app.provider.columns [URI]。
- 用以下格式的命令将数据插进content provider。
实例(drozer自带测试app-Sieve)
4.枚举有SQL注入漏洞的content provider
利用drozer对下述两类SQL注入漏洞进行测试。
(1)SQL语句中的查询子句是可注入的
如果存在该漏洞,那么在执行完该命令后,被查询的整张表都会被返回并打印出来。
(2)投影操作子句是可注入的
(8)利用可调试的app(Java调试器)
列出Android设备上所有被设为可调试的package,以及它们被赋予的权限:run app.package.debuggable。
在找到目标后,利用下述命令去运行:run app.activity.start –component [package] [package.MainActivity]。
(9)对app做中间人攻击
1.在linux下查看ip和网关
如果有一台和设备连接在同一个路由器的Android手机,也可以直接在Android手机上查看网关信息。
2.利用Ettercap对Android手机进行中间人攻击
3.参考资料
(1)drozer学习
drozer安装中的一些问题
打造您自己的Drozer模块,测试Android应用安全
安卓Hacking Part 13:使用Drozer进行安全测试
droidsec
drozer入门讲解
(2)检查网络流量
windows环境下netcat的安装及使用
BusyBox
android编译netcat
Android问题集锦之四十:Android NDK: Could not find application project directory
Win10 设置了环境变量,但是没有用啊,怎么回事?
系统cmd命令提示符出现“不是内部或外部命令,也不是可运行的程序或批处理文件”
(3)通过activity manager被动嗅探intent
ActivityManager 和 内部类 RecentTaskInfo的学习
Android漏洞挖掘工具收集与整理
理解 Context.getSystemService 原理
(4)攻击service
(5)关于content provider
(6)对app做中间人攻击
宝刀未老之 ettercap 基础使用 (一)
使用Ettercap filter进行流量监听和数据篡改
Ettercap:“中间人攻击”神器