Android抓包的常见姿势

文章最后更新时间为:2021年06月02日 10:38:09

这里总结一下安卓 app 抓包的常见姿势,如有错误,还请各位大佬指正。

抓包代理工具有很多种,比如常见的 fiddler、burpsuite、Charls,或者是可以抓 tcp/udp 层的 wireshark 。因为大部分 app 使用的 http 协议,所以这里我只考虑了抓取 http 协议包,选取 burpsuite 作为代理工具。如果使用其他抓包工具,大同小异类比着来就行了。

1. Android 7.0 的 CA 信任变化

根据文章:

在 Android 7.0 之后,默认不再信任用户添加的 CA 证书,只信任系统证书。如果 app 需要信任用户证书(比如在调试模式下),则需要手动在配置文件中进行配置,比如以下示例:

<network-security-config>  
      <debug-overrides>  
           <trust-anchors>  
                <!-- Trust user added CAs while debuggable only -->
                <certificates src="user" />  
           </trust-anchors>  
      </domain-config>  
 </network-security-config>

但是正版上线的 app 一般都不会主动配置信任用户证书。

而在 Android 9.0 之后,默认网络安全性配置如下

<base-config cleartextTrafficPermitted="false">
    <trust-anchors>
        <!-- 信任系统预装 CA 证书 -->
        <certificates src="system" />
    </trust-anchors>
</base-config>

可以看到默认配置禁止了未加密的网络传输,也就是说 Android 9.0 之后默认情况下甚至只允许经过 tls 加密的 http 流量。

所以 Android 7.0 之后版本的抓包难度有了明显的提升,在 Android 7.0 版本以下,我们只需要导入用户级别的 CA 证书即可抓取到 app 包,而在 Android 7.0 版本以上,直接导入用户 CA 证书是不被信任的,则需要进行证书校验的绕过,一般有下面两种绕过原理:

  • 添加系统级别的证书(需要 root 权限)
  • 绕过 app 对证书的校验(hook/修改源码)

原理有两种,但是每种原理的具体做法可以有多种。下面我们来实验一些常见的抓包方式。

2. 直接导入用户证书

此种方式最简单,但是仅适用于 Android 7.0 以下的安卓版本,我们直接安装用户证书,然后设置代理就可以了。

下面利用 mumu 模拟器来进行 burpsuite 抓取 app 网络的实验:

1.首先安装mumu模拟器:http://mumu.163.com/

目前安装完后,默认情况下,模拟器中的 android 版本为 android 6:

2021-05-26T07:34:47.png

2.然后 burp 开启监听,这里的监听不能再是默认的 127.0.0.1 了,我们需要设置成模拟器可以访问的 ip ,比如 wifi 网卡的 ip 。

3.将 burp 的证书导出来,默认是 cacert.der ,将其重命名为 cacert.cer 。然后将证书复制证书到 mumu 中。(我是利用共享文件夹的方式,复制证书到到 mumu 共享文件夹即可)

4.模拟器导入证书

点击设置->安全->从 SD 卡安装证书,然后选择证书 cacert.cer ,下面的证书名称随意:

2021-05-26T07:30:29.png

导入完成后,在 设置->安全->信任的凭据 中可以看到我们导入的证书:

2021-05-26T07:30:56.png

5.设置模拟器的代理

在设置-> WLAN 中设置代理为 burp 监听的 ip 和端口

2021-05-26T07:39:41.png

然后就可以在 burp 中抓取到模拟器的包了,这里使用了微信和手机自带的浏览器进行抓包实验,可以看到是可以正常抓到 https 包的。

2021-05-26T07:41:07.png

3. 添加系统级别的证书

默认情况下,用户添加的证书属于用户级别的证书,要想添加系统级别的证书,需要我们获取手机的 root 权限。获取 root 的过程就不说了,这里我的测试手机之前已经刷过机了。

root 之后,我们进入手机的开发者选项,然后开启 usb 调试功能,并且连接电脑。

下面是使用 adb 安装 burp 证书到手机系统证书的过程:

1.安装adb工具

# 我这里是 mac, 直接 brew 安装
brew install android-platform-tools

2.格式化证书

$ ls | grep cacert
cacert.der

# 转换成PEM文件
$ openssl x509 -in cacert.der -inform DER -out cacert.pem -outform PEM

# 提取hash
$ openssl x509 -inform PEM -subject_hash -in cacert.pem | head -1
7bf17d07

# 生成新的带指纹的证书文件7bf17d07.0 
$ cat cacert.pem > 7bf17d07.0 
$ openssl x509 -inform PEM -text -in cacert.pem -out /dev/null >> 7bf17d07.0 

2021-05-26T08:48:34.png

3.传输证书到手机

上一步骤的7bf17d07为证书的 hash 值, 将该目录下生成的7bf17d07.0文件上传到手机中, 最后移动到/system/etc/security/cacerts/目录下,操作步骤如下

$ adb push 7bf17d07.0 /data/local/tmp

$ adb shell                          
raphael:/ $ su (这里需要点击手机root权限授权弹框)
raphael:/ # mount -o rw,remount /
raphael:/ # mv /data/local/tmp/7bf17d07.0 /system/etc/security/cacerts/7bf17d07.0
raphael:/ # chmod 644 /system/etc/security/cacerts/7bf17d07.0                                                                                               

2021-05-26T08:54:47.png

4.然后我们重启手机,重启完成后证书会自动安装到系统里。

可以从已安装的凭据中查看到安装的 burp 证书。

2021-05-26T08:58:59.png

5.设置代理,然后尝试抓包:

2021-05-26T09:44:04.png

可以抓到 https 的包了,但是在我实验过程中,知乎和微博一直提示网络错误,微信公众号文章是可以打开的,可能是部分 app 使用了双向证书信任,原因还待进一步的分析。

4. Hook app 的证书检验逻辑

Hook 意思是钩子,可以把一段执行着的代码钩下来,然后加入我们自己的逻辑,最后在放回去。比如我们可以 Hook 住一段系统代码,在执行系统代码之前加入我们自己的逻辑。

下面我们使用 xposed 来实现 hook app 的 ssl 证书校验。

关于xposed的工作原理:来自Android Hook技术防范漫谈

在 Android 系统中 App 进程都是由 Zygote 进程“孵化”出来的。Zygote
进程在启动时会创建一个虚拟机实例,每当它“孵化”一个新的应用程序进程时,都会将这个 Dalvik 虚拟机实例复制到新的 App
进程里面去,从而使每个 App 进程都有一个独立的 Dalvik 虚拟机实例。

Zygote 进程在启动的过程中,除了会创建一个虚拟机实例之外还会将 Java Rumtime 加载到进程中并注册一些 Android
核心类的 JNI(Java Native Interface,Java本地接口)方法。一个 App 进程被 Zygote
进程孵化出来的时候,不仅会获得Zygote 进程中的虚拟机实例拷贝,还会与 Zygote 进程一起共享 Java
Rumtime,也就是可以将 XposedBridge.jar 这个Jar包加载到每一个 Android App 进程中去。安装
Xposed Installer 之后,系统 app_process 将被替换,然后利用 Java 的Reflection
机制覆写内置方法,实现功能劫持

xposed 框架中已经有很多模块实现了对 ssl 验证的绕过,比较常见的模块有:

下面我们使用 xposed + TrustMeAlready来尝试绕过 app 的证书校验,进行抓包。

首先 root 手机后,安装 xposed 模块,这部分在常见的刷机教程中都有涉及,就不多说了。

然后下载 TrustMeAlready 的 apk 安装包,安装后在 xposed 模块中勾选该模块,重启手机生效。

2021-05-26T10:14:15.png

设置网络代理后进行抓包

2021-05-26T10:16:09.png

测试下来常见的 app 都可以正常抓包,包括知乎,微博,微信等。

5. VirtualXposed + Hook SSL 校验

VirtualXposed 可以看成是一个“虚拟机”环境,在这个“虚拟机”已经安装了 Xposed 框架。只要我们把 app 安装在这个虚拟机中,就可以使用 xposed 框架对 app 进行控制。与3中的方法相比,好处是不需要获取手机的 root 权限,一切都是虚拟的。

举个例子,如果我们需要抓取微信的包,我们需要将微信和 xposed 模块 TrustMeAlready 都安装到 VirtualXposed 中即可。

更多关于 VirtualXposed 的介绍可以参考 https://mp.weixin.qq.com/s/8bpyIjRS21NGseq1DFQmQQ ,接下来我们使用VirtualXposed进行抓包实验。

首先安装 VirtualXposed:https://github.com/android-hacker/VirtualXposed

打开 VirtualXposed 应用,如下图所示,点击“6个点”,进入设置页面

2021-05-26T11:46:12.png

在设置页进入添加应用模块中

2021-05-26T11:48:39.png

选择要使用的 App,有两种方式,一个是软件列表中通过已安装的软件进行克隆,还有一个是点击+号通过 apk 包进行安装,安装/克隆 App 结束以后,在首页上滑进入应用列表,点击打开应用即可

2021-05-26T11:49:44.png

这里我通过上述方法安装了微信、酷安和 xposed 模块 TrustMeAlready。

下面来抓包测试:

2021-05-26T11:58:50.png

和3的原理和效果都是一致的。

6. 通过 VPN 方式设置代理

在上面四种方法中,我们都是谈如何绕过 app 对证书的校验,都是简单的设置了系统 wifi 代理,但是还是有可能抓不到包,其中有一个原因就是代理的问题。

app 可以在网络请求类库中通过自定义代理设置,选择是否要走系统代理。所以我们设置的系统代理可能对于某些 app 来说是无效的,这种情况我们可以尝试使用本地 VPN 代理软件直接抓系统的包,下面我们使用常见的 VPN 软件 Drony 来进行实验。

安装完成后:

1.打开 Drony, 看到 LOG 页,右滑进入 SETTING 页

2021-05-30T03:35:00.png

2.选择无限网络,点击当前在用的 wifi,进入网络细节设置页。

2021-05-30T03:36:45.png

3.在此页面设置代理为手动,然后填入代理地址和端口,代理类型选择 http 类型。

4.下滑设置代理默认值为允许全部,然后点击规则

2021-05-30T03:37:43.png

5.添加一个规则,行动选择本地代理,应用选择需要抓包的应用,这里我选择了微信。

2021-05-30T03:38:40.png

6.回到主页,然后打开开关即可

2021-05-30T03:51:07.png

然后配合前面几种方式解决证书信任问题,就可以抓到 https 包了

7. 总结

本文实验了常见的抓取 app http 层流量的方式,当然在具体的实践中可能也有一些例外情况。比如有些 app 直接使用 socket 发 TCP 层的包,这样我们就没办法使用 http 代理软件抓包了,解决方法一般有:

  1. 手机上使用 tcpdump 抓包,然后使用 wireshark 进行分析
  2. 或者使用 Drony/ProxyDroid + Charles,进行 socks 代理抓包

还有些比较严格的 app ,会检测是否使用了vpn/是否处于 root 环境等,这些就欢迎各位多多分享了。

参考

1 + 9 =
1 评论
    666Chrome 91Windows 10
    6月2日 回复

    大佬牛逼