前言
最近在对一个app进行测试的时候,尝试抓取数据包,发现以前的使用方法失效了,原因是随着安卓版本的提高,对证书的限制越发严格,而我身边的老机子放在学,不在身边,没得办法,只好研究一下怎么绕过这种限制。
经过一方查找,终于发现了一个相对比较简单的办法,这里就开一篇文章,记录一下。
过程
首先下载所需要的工具:
● Charles——
https://www.charlesproxy.com/download/
● Charles-Crack(有能力的同学请支持正版)——
https://github.com/8enet/Charles-Crack
● VirtualXposed——
https://github.com/android-hacker/VirtualXposed/releases
● TrustMeAlready——
https://github.com/ViRb3/TrustMeAlready/releases
PC端
PC端下载并安装好之后,运行Charles。
依次点击菜单栏的:Proxy→Proxy Settings,并按如下进行勾选。
接着点击菜单栏:Proxy→SSL Proxying Settings
按照下图进行配置:
若事先确定要抓取的Host和Port信息,可自行进行更改。
接着点击Proxy→Windows Proxy (注:不同版本名称不同),将不再抓取本地流量。
然后点击Help→SSL Proxying→Install Charles Root Certificate on a Mobile Device or Remote Browser,将证书挂载到chls.pro/ssl这个地址上。
手机端用浏览器打开上述地址,将证书下载到本地。这步也可以选择点击菜单栏:Help→SSL Proxying→Save Charles Root Certificate...,来将证书下载到PC,通过数据线、QQ等方法传到手机。
手机端
首先需要把手机与电脑连接到同一个网络内。
打开WLAN,选择对应的WIFI,进行代理配置。如下图所示:
主机名为PC端的内网IP,端口为配置Charles时Proxy Settings配置中的Http Proxy里的Port内容。
PC端内容不清楚的同学可以打开终端运行如下命令:
● Windows: ipconfig
● Linux: ifconfig
● Mac: ifconfig
成功代理上之后,手机端的流量都会经过PC端的Charles。如果是第一次配置,则Charles会弹出一个窗口,提示有新的连接,点击Allow按钮。
其次需要将电脑端Charles的证书给安装上。
若在PC端选择的是Install Charles Root Certificate on a Mobile Device or Remote Browse,则先需要通过手机浏览器访问chls.pro/ssl这个网址获得证书文件。
这里我使用的手机为小米8 Lite,不同的手机品牌/型号安装证书的方法可能有所不同,具体可通过搜索引擎来获得安装的方法。
依次点击:设置→更多设置→系统安全→加密与凭据→从SD卡安装,接着在文件浏览器中选择你下载好的证书。
然后给证书凭据起个名字,可随意填写,凭据用途选择VPN和应用。
安装完毕后依次点击:信任的凭证→用户,即可查看到刚刚添加进来的Charles证书——XK72 Ltd。
以往我们只需要执行到这里,便可以成功抓取到数据包。不过由于Android的版本更新,对用户自身添加的证书进行了限制,导致我们直接地无法抓取的HTTPS数据包,在Charles里会发现HTTPS的流量都显示Unknown。
这里我选择的办法是用VirtualXposed工具进行绕过,如果你不想使用这个方法,也可以考虑通过将手机进行Root处理,并将Charles的证书添加到系统级的证书中,不过这并不在本文讨论的范畴。
手机下载好VirtualXposed和TrustMeAlready两个apk文件,安装VirtualXposed.apk之后运行。
在VirtualXposed中,先进入设置页面,点击添加应用,选择你想抓取流量的应用,以及TrustMeAlready.apk文件进行安装。注意:由于TrustMeAlready.apk未安装,需要点击+号按钮,在对应的目录选择apk文件即可。
然后再回到设置页面,点击模块管理,可以看到我们刚刚添加的TrustMeAlready便在其中,点击右边的框框进行勾选,接着回到设置页面,在最下方点击重启、确定。
到这里我们便已经完成了全部的操作,之后你可以在VirtualXposed框架内打开任意的app都可以成功取到HTTPS流量。
关于Charles的使用方法,本文不再赘述,网络上已有许多教程,稍微花点时间搜索即可。
分析
Android7.0+为何无法直接截取HTTPS流量
在Android开发者平台文档,我们可以查到这么一段话:
默认情况下,来自所有应用的安全连接(使用 TLS 和 HTTPS 之类的协议)均信任预装的系统 CA,而面向 Android 6.0(API 级别 23)及更低版本的应用默认情况下还会信任用户添加的 CA 存储区。应用可以使用 base-config(应用范围的自定义)或 domain-config(网域范围的自定义)自定义自己的连接。
自定义可信 CA|Android Developer
以上说明了安卓6.0以上的版本,在默认情况下应用是不会相信用户添加的CA证书,导致我们使用老方法无法完整地获取到应用发出的HTTPS数据。
VirtualXposed+TrustMeAlready实现原理
简单的说,VXP相当于手机上的虚拟机,在手机原有的系统上创建一块虚拟空间,类似沙盒般的效果,而通过TrustMeAlready插件,便可HOOK到 APK 中所有用于校验 SSL 证书的 API (详情可以点击参考里的《JustTrustMe原理分析》),从而绕过证书校验,故此达到https抓包的效果。
一、什么是Virtual Xposed?
Xposed
众所周知Xposed是来自国外XDA论坛的rovo89开发的一款开源的安卓系统框架。
它是一款特殊的安卓App,其主要功能是提供一个新的应用平台,玩家们安装Xposed框架后,就能够通过Xposed框架搭建起的平台安装更多系统级的应用,实现诸多神奇的功能。
Xposed框架的原理是修改系统文件,替换了/system/bin/app_process可执行文件,在启动Zygote时加载额外的jar文件(/data/data/de.robv.android.xposed.installer/bin/XposedBridge.jar),并执行一些初始化操作(执行XposedBridge的main方法)。然后我们就可以在这个Zygote上下文中进行某些hook操作。
Xposed真正强大的是它可以hook调用的方法.当你反编译修改apk时,你可以在里面插入xposed的命令,于是你就可以在方法调用前后注入自己的代码.
Github开源地址:
https://github.com/rovo89/Xposed
由于Xposed最大的弊端在于设备需要root,并且编写插件模块后需要重启手机(当然也有办法可以不用重启),所以有了VirtualApp。
VirtualApp
VirtualApp是一个App虚拟化引擎(简称VA)。
VirtualApp在你的App内创建一个虚拟空间(构造了一个虚拟的systemserver),你可以在虚拟空间内任意的安装、启动和卸载APK,这一切都与外部隔离,如同一个沙盒。
运行在VA中的APK无需在外部安装,即VA支持免安装运行APK。
熟悉android系统开机流程的应该知道各services是由system server启动一系列的系统核心服务(AMS,WMS,PMS等等)ViratualApp就是构建了一个虚拟system_process进程,这里面也有一系列的核心服务。
VirtualApp主要技术用到了反射和动态代理来实现的
Github开源地址:
https://github.com/asLody/VirtualApp
VirtualXposed
VirtualXposed就是基于VirtualApp和epic 在非ROOT环境下运行Xposed模块的实现(支持5.0~8.1)。
Github开源地址:
https://github.com/android-hacker/VirtualXposed
来源:http://jackzhang.info/2018/04/09/VirtualXposed/
HTTPS抓包为何需要安装抓包工具的CA证书
为了弄清楚这个问题,我们首先得清楚SSL/TLS加密的原理。
通常来说,SSL与TLS都是非对称加密的,有一个公钥与私钥。公钥是公开的,私钥是私密的,存在于服务端。服务器返回的内容会被私钥加密,客户端需要使用公钥进行解密。同样的,用户端的数据便有公钥加密,私钥来解密。
而我们都知道,使用了SSL之后我们便可以保护我们的站点免受中间人攻击。那又何为中间人攻击呢?
举个例子,用户A要使用电脑访问网站http://example.com,而这台电脑已被攻击者B攻陷,那么攻击者B可通过修改A电脑上的hosts文件,将example.com的解析指向B自己的服务器,这样A用户就在”不知情“的情况下中了招。而如果该网站使用了SSL/TLS加密时,用户A在访问https://example.com的时候,需要向服务器请求公钥的内容,又因为公钥是放在CA证书里的,且CA证书通常是由相关的权威CA机构(权威性由微软等操作系统巨头决定)才能发布,类似我们的民政局才能发布身份证。这使得攻击者无法伪造CA证书,因为客户端在收到CA证书之后会根据不同的权威CA机构进行相应的验证,而若颁发该证书的机构不够权威(这使得权威机构也不会随意颁发CA证书,以免自身的权威性被取消),是不会被系统所信任的。这一连串的操作,使得使用了SSL/TLS的网站可以不受中间人攻击的影响。
OK回归正题,那这HTTPS抓包与中间人攻击有何关系呢?其实这两者的原理都是一样的,只不过攻击者的角色变成了抓包工具。
So,这次的问题就变成了中间人攻击如何在HTTPS通信中生效?
我们注意到,中间人攻击的最大难点就在于CA证书的权威性,而我们在没有域名解析权的情况下是不能去向权威CA机构申请证书的。那么既然如此,为何我们不考虑自己“开”一家权威机构呢,这样我们生成的证书不就会被信任了嘛。
这时候,就得需要安装我们抓包工具的CA证书了,这个证书与域名所有者向权威机构申请的证书不同,他是根证书。
因为域名的CA证书的验证过程也是非对称加密验证,也就说,CA证书的验证是由根证书里的公钥来解密验证的。通常操作系统里已经默认信任了一批权威机构的根证书。
所以,当我们把我们自己的根证书添加到操作系统中时,相当于我们自己“开”了一家权威CA机构,这样便可以解决了之前的难题。
借一张网图:
源自:图解 HTTPS:Charles 捕获 HTTPS 的原理
结语
别看上边方法好像挺简单的,实际操作起来却挺繁琐,网络上的方法大多抄来吵去且时效性很差,导致在操作过程中也走了许多弯路,许多东西还是自己实验之后才知道。看似简单的东西,其实写起来可学习的东西还是很多的,以前自己在学习的时候没有注意的点,现在看起来也是可以细细研究的。不骄不躁,Stay Hungry, Stay Foolish.
参考
● 通过 HTTPS 和 SSL 确保安全|Android开发者文档
https://developer.android.com/training/articles/security-ssl
● VirtualXposed插件开发-Xposed hook 之入门案例
http://jackzhang.info/2018/04/09/VirtualXposed/
● JustTrustMe原理分析
https://bbs.pediy.com/thread-214012.htm
● 图解 HTTPS:Charles 捕获 HTTPS 的原理
https://github.com/youngwind/blog/issues/108
网友评论