为什么你的Charles会抓包失败(二)

发表于:2021-8-12 09:43

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:卤蛋实验室    来源:网络

  HTTPS 代理配置
  HTTPS 本质上就是 HTTP 协议 + TLS 协议,从建立连接的角度看,主要是在 TCP 三次握手之后又加入了四次 TLS 握手,如下图所示,TLS 握手过程中会校验加密用的公钥证书,所以我们就要手动安装并信任 Charles 的证书,以达到抓取 HTTPS Packets 的目的。
TLS 1.2
  TLS 的加入,加强了网络的安全性的同时,也增加了抓包的复杂度,下一节我会详细解释,这里先做个证书安装的步骤演示。
  注:证书安装前要确保 HTTP 代理已经配置完毕
  1.电脑端安装证书
  电脑端安装证书是最简单的。首先点击 Charles -> Help -> SSL Proxying -> Install Charles Root Certificate 在电脑端安装证书,然后点击刚刚安装的证书,手动信任全部权限,最后输入密码保存修改就可。
  2.iOS 安装证书
  iOS 安装证书相对来说复杂一些。首先点击 Charles -> Help -> SSL Proxying -> Install Charles Root Certificate on a Mobile Derive,这时候会跳出一个弹窗,然后我们根据提示在手机端访问 chls.pro/ssl,下载安装 Charles CA 证书。
  安装好后还要手动开启权限。先要到 通用 -> 描述文件与设备管理 -> 信任 里安装刚刚下载的证书,然后到 通用 -> 关于本机 -> 证书信任设置 -> 针对根证书启用完全信任 里手动信任证书,这两个同意后 iOS 就安装证书成功了。
  3.Android 安装证书
  Android 安装证书的步骤不但麻烦,作用还不大。
  首先点击 Charles -> Help -> SSL Proxying -> Save Charles Root Certificate,把证书文件以 *.cer 格式保存。
  注:Charles 保存证书文件时,有两种格式可选:.pem 和 .cer。前者是一种证书容器格式,一般是对证书进行 base64 编码;后者一般是二进制格式的证书,Android 系统对二进制格式的证书兼容性更好一些,所以我们选择 .cer 文件。
  保存好文件后,我们再用 USB 或着其它方式把 CA 证书导入到 Android 内,最后点击证书安装就可。
  三、Charles 抓包失败案例分析
  本节其实是本文的重点,从 6 个方向分析 Charles 抓包失败的原因,从代理服务器到 TLS 证书,覆盖了计算机网络的各个知识点,非常值得收藏学习。
  1.关闭代理!关闭代理!关闭代理!
  作为一名程序员,为了顺畅的访问 GitHub 等网站,我们总会用些“辅助工具”。这些工具一般会自动开启 HTTP/HTTPS 代理从而抢占端口,导致 Charles 代理失败。
  解决这个问题也很简单,Charles 抓包前,把电脑和手机的辅助工具都关掉,这样就不会有代理冲突的问题了。我们可以查看电脑的 Wi-Fi 代理界面,开启 Charles 抓包前要保证下面的选项都没被勾选就好了。
  肯定也有人想过我们本地挂两个代理,报文先经过工具,然后经过 Charles 抓包,最后传输到客户端。首先这种方案是可行的,但是实际用下来会非常的卡,延迟也很高,所以并不建议这样使用。
  2.确定数据走的 HTTP 协议吗?
  本小节开始前我们先看一下官方是如何定义 Charles 的:
  Charles is an HTTP proxy / HTTP monitor / Reverse Proxy that enables a developer to view all of the HTTP and SSL / HTTPS traffic between their machine and the Internet.
  从介绍中我们可以看出 Charles 是一款专注于分析 HTTP 报文的网络工具,所以说对于其它协议支持是非常有限的。比如说现在的 IM 或音视频应用,出于性能和安全上的考虑,基本都是自己基于某一传输层协议自己封装的,这些数据 Charles 肯定是抓不到的。
  通过阅读 Charles 的官方文档和自己的测试,Charles 支持以下协议:
  · HTTP/1.1
  · HTTPS
  · HTTP/2
  · ws(WebSocket)
  · wss(WebSocket Secure,TLS 加密的 WebSocket)
  · SOCKS
  注:Charles 不支持 HTTP/3,但是大部分开启 HTTP/3 的网站都做了降级处理。例如用 Chrome 正常访问 Google 时,走的协议是 HTTP/3,连接 Charles 代理后,协议会降级到 HTTP/2
  上面列出的几个协议,其实已经覆盖日常业务开发 90% 的应用场景了,若想抓取其他协议的报文,还是老老实实用 Wireshark 吧。
  3.之前开了黑白名单,再次抓包忘记关了
  我想日常工作中,你或你的同事肯定遇到过这种场景:
  测试报上来一个 BUG,自己连上 Charles 打算分析一下 HTTP 报文想定位一下是前端问题还是后端问题,结果发现请求一直打不通,手忙脚乱半天,才发现自己开了黑白名单,请求都被 Block 掉了。
  上面案例的黑白名单只是一个统称,具体到 Charles 里,下面的几个配置都有可能造成误解:
  · Proxy Settings 的 Options 里过滤了一些网址
  · SSL Proxying Settings 没有匹配所有网址
  · Block List/Allow List 做了黑白名单设置
  · DNS Spoofing 做了 HOST 的映射
  · Map Remote 重定向了请求
  · Rewrite 重写了请求
  ......
  我写了几个高频的 Charles Tools,这些功能很有可能在你开启后就忘记关闭了,如果出了问题难道就要一一排查吗?
  其实 Charles 有一个很不起眼的功能,那就是它的 UI 界面右下角会展示 Charles 正在开启的功能,如果你怀疑你的 Charles 哪里做了接口限制,你就扫一眼右下角开启的功能,然后依次检查就可。
  4.Android 版本越高,HTTPS 报文越难抓
  在「Android 安装证书」那个小节里,我说这个步骤意义不大,根本原因在于:用户自己安装的 CA 证书没有 ROOT 权限。
  我们先看一张图,这个是 Android 的证书信任页面:
  从上图可以看出,Android 系统把证书信任分为两大块:
  · 系统 CA 证书:基本拥有所有权限
  · 用户 CA 证书:用户自行安装,权限很低
  我们自己安装的 Charles 证书都属于用户 CA 证书。除了证书的权限问题,Android 的不同版本对权限的处理规则也不一样:
  :Android 7.0 以下:信任用户 CA 证书,可以简单的理解为我们安装的证书直接获得 ROOT 权限
  :Android 7.0 以上, targetSdkVersion < 24:信任用户 CA 证书
  :Android 7.0 以上, targetSdkVersion >= 24:不信任用户 CA 证书
  通过以上的分析,我们可以得出几个让 Android 信任 Charles 证书的方案:
  1.ROOT
  直接 ROOT Android 手机,把 Charles 证书放到系统证书里,实现证书洗白。
  2.准备一个低于 Android 7.0 的手机
  Android 7.0 是 2016 年的系统,按照 Android 手机两年一换代一年一更新的速度算,这种手机很难找到了。
  3.准备一个 targetSdkVersion < 24 的 APP 安装包
  国内各大应用市场 2019 年统一要求 APP API 版本必须大于 28,这种安装包很难找到了,而且互联网产品迭代这么快,不一定能保证安装包可用。
  4.骚操作
  正常大道走不通,Android 小道还是有很多的。社区上有各种轮子可以绕开限制,但和 Charles 关系不大,我就不展开说了。喜欢折腾的同学可以研究一下。
  上面的几个方案都是针对其它 APP 的,如果你想抓包的应用是自己公司的,那就很简单了。
  Android 有个 res/xml/network_security_config.xml 文件,意如其名,这个配置文件是专门控制网络安全的。
  比如下面的配置,release 包只信任 system 级别的证书,debug 包同时信任 system 和 user 级别的证书,这样我们在 debug 环境下就可以开心的用 Charles 抓包了。当然安全配置肯定不止这一点内容,感兴趣的同学可以去 Android 开发者官网学习了解。
  <?xml version="1.0" encoding="utf-8"?>
  <network-security-config>
      <base-config cleartextTrafficPermitted="true">
          <trust-anchors>
              <certificates overridePins="true" src="system" />
          </trust-anchors>
      </base-config>
      <debug-overrides>
          <trust-anchors>
              <certificates overridePins="true" src="system" />
              <certificates overridePins="true" src="user" />
          </trust-anchors>
      </debug-overrides>
  </network-security-config>
  5.证书固定(Certificate Pinning)
  证书固定(Certificate Pinning) 是指客户端内置了服务端真正的公钥证书。
  在 HTTPS 请求时,服务端发给客户端的公钥证书必须和客户端内置的公钥证书一致才能请求成功。一般对安全比较重视的公司会采取这种操作。
  在这种情况下,利用 Charles 抓包时,Charles 的公钥证书和客户端的公钥证书不一样,伪造的请求就会被驳回,我们就抓包失败了。那么这种情况怎么解决?
  和前面介绍的一样,路其实还是有两条:
  · 一条是 Hack 之路,刷机 ROOT,借助工具移除 APP 中固定的公钥证书;
  · 另一条是正路,你拥有这个 APP 的开发权限,那么一般你也就拥有了公钥证书和随之配套的私钥,我们可以把证书和私钥导入到 Charles 中,解决证书固定引起的困扰。
  Charles 导入公钥证书和私钥比较简单,点击 Charles -> Proxy -> SSL Proxying Setting -> Root Certificate,然后导入 .pem 或 p12 文件即可。
  注:.p12 是一种文件格式,同时包含证书和密钥
  6.证书双向验证
  在绝大部分的情况下,TLS 都是客户端认证服务端的真实性的,但是在一些非常注重安全的场景下(例如匿名社交),部分 APP 会开启 TLS 的双向验证,也就是说服务端也要验证客户端的真实性。
  在这种情况,客户端必然内置了一套公钥证书和私钥。相对于服务端,APP 有很大的砸壳风险,所以公钥证书和私钥一般都是极其隐蔽的,比如说写到 .so 里,隐藏在一个混淆的妈都不认识的随机数算法函数里,从而增大破译难度。
  我不是安全专家对这个研究的不深,平常工作也没遇到这么刁难的问题。从功能面板看,Charles 应该也支持这种极限场景的抓包,但是个人没有具体实践过,大家可以尝试一下。
  四、总结
  Charles 抓包是一个很常见的职业技能,如果深入研究,你会发现它涉及到网络连接的五元组、报文转发的代理服务、密码学里的 MITM 和公钥证书知识。综合来看,只有掌握这些较为底层的基础知识,面对工作中各种奇奇怪怪得问题时,才能游刃有余的应对。

      本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号