利用App中的漏洞

利用工具分析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泄露的信息

  1. adb logcat
  2. adb logcat [options] [filter]

  1. adb logcat > output.txt,把日志的输出转存到一个文件中去。
  2. adb logcat | [其他程序],利用“管道”把日志信息输入到另一个程序中去。(如adb logcat | grep [pattern]
  3. 例如,下述例子可以帮助过滤给出日志文件中与Web相关的信息,adb logcat | grep [Cc]ookieadb 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 -
对于上述主要步骤中的命令参数的补充说明
  1. 关于adb push tcpdump /data/tcpdump/.

  1. 关于./data/tcpdump/tcpdump -w - | nc -l -p 31337

  1. 关于wireshark -k -S -i -

(4)通过activity manager被动嗅探intent

准备

需要给drozer的手机端代理添加android.permission.GET_TASKS权限,有以下两种方式。

  1. 因为agent.apk并没有加壳和混淆,所以可以直接利用AndroidKiller工具对其Manifest文件进行修改,然后重新编译apk。
  2. 将其源码导入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。

No such property: javaCompilerTask for class: com.android.build.gradle.internal.variant.TestVariantData.

关于报错Unable to find method 'org.gradle.api.tasks.compile.CompileOptions.setBootClasspath(Ljava/lang/String;)V'——将android Gradle插件升级到3.4.0版本和Gradle 5.1.1。

Unable to find method ‘org.gradle.api.tasks.compile.CompileOptions.setBootClasspath(Ljava/lang/String;)V’.

关于报错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的,下次要仔细阅读安装说明才行。

Gradle 5.0 Depreciated API features

关于报错Could not find com.android.tools.build:gradle:3.1.4——在项目的 build.gradle 文件中,添加 google() 依赖项。

Could not find com.android.tools.build:gradle:3.1.4

关于报错Cannot run program "protoc": CreateProcess error=2, 系统找不到指定的文件。——一是因为我当时并没有在电脑上安装protobuf,二是因为我安装的protobuf的版本不符合项目需求,但去查阅官方安装说明文档,2.6.1及以上的版本都是满足的,而我安装的是3.3.0的,按理说不会存在版本不合适的问题呀,具体原因参见下一个问题。

在windows上安装protobuf
Maven: Cannot run program “protoc”

关于报错错误: 程序包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文件,改变其版本信息即可。

Could not expand ZIP错误

实现一个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 [路径]创建目录时,并没有创建成功;二是因为待安装的文件不能放在创建的目标目录下,而是应该放在另外的目录中。

drozer/issues

安装成功之后报错如下图所示。——关于这个错误,我尝试重新换一个自定义模块进行安装运行,结果就没有出现这个错误了,但出现了下面的错误。

drozer模块的编写及模块动态加载问题研究

关于如下图所示的报错,是因为在安装jdk的时候,当时系统默认的路径中包含了空格,所以会报错,想解决的话可以重装jdk(注意空格问题)。

安装drozer的坑

针对上面那个报错的脚本,在虚拟机上重新安装到drozer中,成功运行,但是最上面那个Skipping source file at ex.sniffer.intents. Unable to load Python module.的报错还是没有解决,猜测是因为脚本的编写有问题,估计是导入的库缺失导致的报错。

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。

主要步骤

  1. 寻找手机上各个app中导出的services:run app.service.info –permission null
  2. 在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后,可通过下述命令进行测试。

  1. run app.provider.query [URI]——尝试提取URI中的数据;

3.向content provider插入数据

  1. 在向content provider插入数据前,我们需要用以下命令获取数据的结构及各列的名称等信息:run app.provider.columns [URI]
  2. 用以下格式的命令将数据插进content provider。

实例(drozer自带测试app-Sieve)

4.枚举有SQL注入漏洞的content provider

利用drozer对下述两类SQL注入漏洞进行测试。

(1)SQL语句中的查询子句是可注入的

如果存在该漏洞,那么在执行完该命令后,被查询的整张表都会被返回并打印出来。

(2)投影操作子句是可注入的

(8)利用可调试的app(Java调试器)

  1. 列出Android设备上所有被设为可调试的package,以及它们被赋予的权限:run app.package.debuggable

  2. 在找到目标后,利用下述命令去运行: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

一个包含各种安全问题的APP示例——OWASP的GoatDroid项目

(5)关于content provider

Android基础总结八:ContentProvider
Provider 权限详解

(6)对app做中间人攻击

宝刀未老之 ettercap 基础使用 (一)
使用Ettercap filter进行流量监听和数据篡改
Ettercap:“中间人攻击”神器