基于Charles抓HTTPS包流程

1、问题描述

如果客户端中添加了证书白名单,此时使用Https进行网络通信,使用charles就会出现Connect错误,导致无法抓包。错误图示如下。
HTTPS抓包Connect错误图
本文通过增加客户端中资源文件中内置的证书白名单的方式实现了对这种情况的抓包。
注意:由于客户端的内置证书路径不一定能找到,并且找到之后也不一定是明文或者格式也不一定能正确分析,所以这个方案的通用性存在问题,请谨慎参考。
本文会先分析Charles的抓包原理,然后从原理中尝试解决方案,最后对结果进行展示。

2、Charles抓包原理

2.1 HTTP通信抓包原理

如果客户端和服务器使用HTTP进行通信,由于请求和应答数据本身没有加密,所以请求和应答能够直接在Charles中展现。

2.2 HTTPS通信抓包原理

如果客户端和服务器使用HTTPS进行通信,HTTPS的请求和应答内容经过了加密,所以Charles需要对请求和应答内容进行相应的处理才能正确展现相关内容。Charles的做法就是对客户端把自己伪装成“服务器”,对服务端把自己伪装成“客户端”。
交互流程如下:
1、Charles拦截客户端的请求,伪装成客户端向服务器443端口发送证书请求;
2、服务器向“客户端”(实际上是Charles)返回服务器的CA证书(证书中包含公钥);
3、Charles拦截服务器的响应,获取服务器证书公钥,然后自己制作一张证书,将服务器证书替换后发送给客户端;(Charles此时获取了服务器证书的公钥)
4、客户端接收到“服务器”(实际上是Charles)的证书后,生成一个对称密钥,用Charles的公钥加密,发送给“服务器”(Charles);
5、Charles拦截客户端的响应,用自己的私钥解密对称密钥,然后用服务器证书公钥加密,发送给服务器;(Charles此时获取了对称密钥)
6、服务器用自己的私钥解密对称密钥,向“客户端”(Charles)发送响应;
7、Charles拦截服务器的响应,替换成自己的内容后发送给客户端;

其中有两个需要注意的点:
1、如果用户不选择信任安装Charles的CA证书,Charles也无法获取请求内容;(所以抓包过程中需要安装Charles的证书)
2、如果客户端内置了自身的CA证书或者证书白名单,此时如果Charles把自己的证书发送给客户端,客户端会发现与客户端内的证书不一致,会出现上图中的Connect错误,导致Charles无法获取信息的;(本文主要解决这个问题)

3、解决方案

对客户端进行解包和重新打包,详细流程见自己2015年写的的一篇博客(https://blog.csdn.net/liushaofang/article/details/50381902),由于当时使用apktool的版本比较老,导致部分资源会解析失败,所以在新的资源中将apktool更新为2.3.4版本,目前能够正常自己分析的一个apk,对应的资源链接为(https://download.csdn.net/download/liushaofang/12473744
主要注意的点是解包命令和打包命令需要进行更新(需要用-p命令指定framepath,需要加上-r命令,命令含义可以参考apktool的help document),签名命令保持不变。

3.1 解包

java -jar apktool.jar d -r -o targetdir -p framepath -f target.apk

3.2 增加证书白名单(重点)

此时需要分析客户端的结构,找到内置证书的白名单,并将Charles分发给客户端的证书添加到客户端中,这一步不具备通用性,需要依据实际情况进行分析,有一条值得借鉴的经验就是从res资源目录中去找。

3.3 重新打包

java -jar apktool.jar b -o updatetarget.apk -p framepath targetdir

3.4 签名

此步骤和以前一致,需要在Auto-sign目录中执行

java -jar signapk.jar testkey.x509.pem testkey.pk8 updatetarget.apk updatetarget-signed.apk

4、结论

重新使用Charles抓包,能够正常抓取所有的通信数据包。

猜你喜欢

转载自blog.csdn.net/liushaofang/article/details/106421834