记一次难忘的android微信小程序https抓包之路

·  阅读 12779

背景

抓包是最方便最快速确定锅是否在前端的方法,但是由于前端很多应用可以在浏览器运行,因此直接通过chrome抓包最方便,但这也导致很多同学不会使用配置代理抓包。随着前端在客户端上的发展,越来越多的前端代码跑在非浏览器上,比如我最近碰到的微信小程序是没有办法通过浏览器运行抓包的,代理抓包成了必选项。本文记录了配置代理多次摔倒后的经验,以便借鉴更科学快速的解决问题。

写下这个标题,让我想起小学语文的作文题目,难忘的...,配置一个charles很难吗?写代码的人是绝对不会承认的。但是如果配置出来抓不到包,到底是哪里出了问题,那就一脸懵逼了。google一下,每个答案跟自己碰到的似是而非,一路试过去?是的,以前我就是一路试过去,最终问题没有解决,什么地方出了问题也不清楚,唯一知道的是这个答案试过了,也不行, 没有解决就觉得一定是自己的关键字不对。因为测试同学那边可以抓包,自己这里小程序就用开发工具,多次配置碰到困难半途而废。

但是最近一个跟第三方合作的项目联调,后端疯狂的追问,是不是你没有发请求?我也不确定呀,毕竟是第三方的代码。我只能默默打开微信开发工具,查查是哪个分支的代码,有时候自己的账号还不符合条件,要找一个合适的账号,给他授权微信开发者。一顿标准操作已经10分钟过去,才打开需要查的页面,我告诉后端不是前端问题。然而这个时候我也是没有底气的,毕竟微信开发工具里的一些配置跟线上不一定一样,代码也不一定是这个版本呀。费了半天心思还没个满意的结果。几次开开心心的写代码被粗暴的打断后,我忍无可忍,决定去跟charles死磕一把,然后劝后端同学自己抓包看看。

手机抓包原理

以charles为例,charles运行机制是在本机监听8888端口的http/https网络请求。对于Android/iOS移动设备,则需要将Wi-Fi代理设置为Fiddler所在主机ip和监听端口8888即可。因为公司内网要使用各种代理,内网还有好几个wifi,不同的wifi下数据包能不能正确的转发是首先要确认的问题,在我这次验证中,我通过两种方法验证手机与主机之间的连通性: 主机上开个简单的http server,在其他主机和手机上访问对应ip看是否能显示

客户端 or 服务器

接下来我很流畅的在网上找一篇文章,按上面的步骤配完了https抓包流程,忐忑的打开微信,看到charles弹出连接窗口,总算过了一关,仔细阅读完,没有实质内容,点了allow,看到界面有请求了,很开心,

再仔细一 看,这个域名是哪里请求的?跟我的小程序有关系吗?我也不认识呀。是charles配置问题?是证书配置问题?我只是个小小的开发,不是搞机狂魔,我不懂证书这么安装是不是成功了。怎么核对步骤都是对的,看现象connect是什么状态,不是http里的code呀。咱也不知道,不过,我们有万能的测试呀,我让测试用他可以代理的手机,安装我的证书试试。结果我看到了熟悉的域名,我再拿我的手机配置他的代理,跟配置我的主机代理现象一样。基本上我确定了,这是客户端的问题,是不是我的证书问题,手机问题,还是app问题呢,还需要后面的验证。

微信 or android app

根据抓包的基本原理,手机上的包要转发给代理的端口才行,所以我怀疑,微信是不是为了安全,没有走系统代理呢,为了验证这个想法,我打开手机上浏览器和简单搜索,进入页面就狂弹【证书不可信】,按照https加密原理,这才是通用的显示,而在微信里面,小程序一个接口都请求不到,微信文章能正常查看而没有证书问题,因此确定是微信,而且是微信小程序的问题。

现在我们已经把范围缩到很小了,google一下,不同内容的基本也就10来篇文章,所有文章指向同一个原因:

在Android7.0及以上的系统中,每个应用可以定义自己的可信CA集。默认情况下,应用只会信任系统预装的CA证书,而不会信任用户安装的CA证书。

而我们抓包的过程,无论是fiddler还是Charles,想抓https,都必须手机安装对应的证书,通过fiddler/Charles安装的证书恰恰正属于用户安装的CA证书,因此会被视作不安全的证书。

而且还揭示了以下现象:

  • 安卓系统 7.0 以下版本,不管微信任意版本,都会信任系统提供的证书
  • 安卓系统 7.0 以上版本,微信 7.0 * 以下版本,微信会信任系统提供的证书
  • 安卓系统 7.0 以上版本,微信 7.0 以上版本,微信只信任它自己配置的证书列表

安装老版微信,试了果然能解析数据了。至此,问题已经很明确了

可怕的https

抓包是要看通信的内容,而https的保密性是要求别人不能看到内容,天然是冲突的,所幸最近看了些https保证安全及中间人攻击的文章,对代理抓包这个中间人有一定了解,简单说来https加密流程就是:

  • 客户端向服务器请求时,服务器先返回带公钥的证书。
  • 客户端验证服务器证书的合法性后,生成一个随机数通过公钥加密发给服务器
  • 后续客户端与服务器通过交换的随机数对数据进行对称加解密

更详细自己看一篇https的文章,比如 HTTP和HTTPS详解。想抓https包,必须手机安装对应的证书,这个证书是代理(fiddler或者Charles)生成的,代理通过此证书与客户端交换密钥进行加密连接,所以代理可以查看客户端的通信内容,其中几个关键点:

  • 证书谁都可以生成,但是只有权威机构给别人生成的证书可信的证书,因为浏览器或者客户端在出厂时就内置了一些可信的权威机构证书,在证书的有效性验证时,能匹配到这些机构的签名才是安全的证书
  • 代理使用了非权威机构生成的证书,验证有效性无法匹配到权威机构,认为通信不安全(确实如此),所以能弹出不可信提示。

可见https抓包时要能顺利交换数据必须做两件事:

  • 要有证书可以提取公钥
  • 要客户端应用知道证书不合法,还给机会完成对称密钥交换

了解到这里后,别人再对我说XXX可以抓包android上https包,我可以直奔主题去抓微信小程序,不再纠结是不是这个代理哪里有配置黑科技我还没有解锁,而一些号称可以在android7.0以上抓包的方案,只需要重点关注它是如何解决证书信任问题,不用再像捡到宝一样一个个试半天才发现不行。

解决方案

知道问题出在哪,如何避免就比较容易了,针对证书的问题,可以想办法在证书位置和微信版本解决。

  • 平行空间一类可以劫持应用行为的软件,拦截证书有效性验证,理论上是最优的,但是目前试下打不开微信。

  • root把代理证书放到系统证书里,经跟大佬请教,现在8.0以上的android已经不能root了,所以无解,谁有车牌可以指一下,不过听说root会被检测出来封号,还是不太安全。

  • 微信版本回退,网络很多地方可以下载老版本的微信,不过小程序的接口能力比较依赖微信版本,老版微信会有兼容问题。

  • 用苹果就行了

总结

最后想说,在google海量的数据面前,不了解原理就去试答案只是穷举。回想这个过程中,开始对https一知半解,出一点问题就毫无头绪,开始还怀疑自己不会安装证书,怀疑自己对charles不熟没有配正确。

了解原理,可以很确定的根据原理一步步缩小问题的范围,加上实践验证,才能得到靠谱的答案,每个问题出现时,大家对它的了解细节都是有限的,而原理是通用的。想想之前搜索的关键字 【mac charles 手机抓包】【charles https证书】...和现在很自信的搜索【android 微信7小程序不能抓包】。之前跟同事交流,据说whistle可以抓到手机上的包,我还请他帮我配置,没有成功也怀疑是配置问题,现在我可以很确定的告诉他:你也不能。

在问题面前,我还只是个小学生。但是这个问题让我长大了一点:google是穷举,要利用原理对穷举剪枝,算法不只运用在代码上,所有问题都可以

分类:
前端
标签:
收藏成功!
已添加到「」, 点击更改