Charles抓包原理
基于前文对 HTTP、SSL/TLS 握手流程、数字证书以及信任链的详细解析,我们现在可以非常清晰地理解 Charles 这类抓包工具的工作原理及其局限性。
Charles 是一款应用层的网络代理(Proxy)工具。当设备(如手机或电脑浏览器)将其设置为网络代理后,设备所有的 HTTP/HTTPS 网络请求都会先经过 Charles,再由 Charles 转发给目标服务器。
一、 Charles 的工作原理:合法的“中间人攻击”
对于明文的 HTTP 请求,Charles 的工作原理非常简单:它作为一个代理服务器,直接读取明文数据,记录下来,再原样转发给目标服务器即可。
但对于 HTTPS 请求,前文提到 SSL/TLS 的核心目的就是防止中间人窃听。既然数据是加密的,且有数字证书保证服务器身份,Charles 是如何看到明文内容的呢?
答案是:Charles 利用了 SSL/TLS 协议中的“信任链”机制,实施了一次被用户授权的“中间人攻击(Man-in-the-Middle, MITM)”。
Charles 抓取 HTTPS 包的核心逻辑如下:
- 截获请求与伪造证书:当客户端(如手机 App)向服务器(如
https://api.example.com)发起 TLS 握手时,Charles 会拦截这个请求。同时,Charles 会利用自己内置的 Root CA(根证书),动态生成一张针对api.example.com的伪造服务器证书,并将其发送给客户端。 - 建立第一段加密连接(客户端 <-> Charles):如果客户端信任了 Charles 的 Root CA,它就会接受这张伪造证书,提取其中的公钥,并与 Charles 协商出一个对称密钥 K1。此时,客户端认为它已经安全地连接到了真实服务器。
- 建立第二段加密连接(Charles <-> 真实服务器):同时,Charles 作为代理,会自己伪装成客户端,向真实的
api.example.com发起 TLS 握手。服务器下发真实的证书,Charles 验证通过后,与真实服务器协商出另一个对称密钥 K2。 - 解密、记录与重新加密:
- 客户端发送加密数据(用 K1 加密)。
- Charles 拦截并用 K1 解密,得到明文数据(在此步骤记录下抓包内容)。
- Charles 将明文数据用 K2 加密,发送给真实服务器。
- 服务器返回数据时,流程反向进行。
二、 Charles 抓取 HTTPS 包的操作步骤与逻辑映射
为了让上述逻辑生效,需要进行特定配置。以下是一个典型的移动端(手机)抓取 HTTPS API 接口的具体例子及操作步骤。
具体场景:开发人员使用 Charles 抓取手机端 App 登录接口的 HTTPS 请求。
步骤 1:配置网络代理(实现流量拦截) * 操作:将手机的 Wi-Fi 代理设置为电脑(运行 Charles)的 IP 地址和端口(通常是 8888)。 * 逻辑说明:这一步使得手机所有的应用层网络流量不再直接发往路由器,而是强制先发给 Charles,为后续的“中间人”介入提供物理条件。
步骤 2:在手机端安装 Charles 的根证书(打破原始信任链)
* 操作:手机浏览器访问 chls.pro/ssl 下载 Charles 的 Root CA 证书,并在手机系统设置中手动安装并信任该证书。
* 逻辑说明:这是最关键的一步。前文提到,HTTPS 依靠系统内置的受信任 CA 列表来防范假证书。通过手动安装 Charles 的根证书,用户主动修改了手机的信任链,告诉操作系统:“只要是由 Charles 签发的证书,无论是哪个域名的,你都认为是合法的。” 这使得 Charles 伪造的服务器证书能够顺利通过客户端的验证。
步骤 3:在 Charles 中开启 SSL Proxying(启用动态伪造)
* 操作:在 Charles 菜单中配置 SSL Proxying Settings,添加需要抓包的域名(如 api.example.com:*)。
* 逻辑说明:Charles 默认只代理 HTTP。开启此设置后,Charles 才会针对指定的域名执行上述的“动态生成伪造证书并建立双向 TLS 连接”的复杂逻辑。
步骤 4:发起请求与查看明文 * 操作:在手机 App 中点击登录。此时在电脑端的 Charles 界面中,就可以清晰地看到包含账号密码的 HTTPS 报文内容(JSON 格式的明文)。 * 逻辑说明:App 实际上是与 Charles 进行加密通信,Charles 解密记录后再与真实服务器加密通信。
三、 Charles 的局限性与突破失败场景
虽然 Charles 非常强大,但由于其处于 OSI 模型中的应用层,并且依赖于特定的信任假设,它在以下三种情况下会抓包失败或无法工作:
1. 无法突破:双向 HTTPS 认证(Mutual TLS / mTLS)
前文提到,普通的 HTTPS 是单向认证(客户端验证服务器证书)。但在极高安全级别的场景(如银行网银接口、企业内部微服务通信)中,服务器会要求双向认证。
* 逻辑冲突:在 TLS 握手阶段,服务器不仅发送自己的证书,还会发送一个 CertificateRequest,要求客户端出示客户端证书,并要求客户端用对应的私钥对一段数据进行数字签名。
* 为何失败:Charles 拦截后向真实服务器发起连接时,真实服务器要求 Charles 出示客户端证书和私钥签名。由于 Charles 并没有保存在用户设备上的真实客户端私钥,它无法完成数字签名操作。TLS 握手立即失败,连接断开,Charles 无法抓到任何数据。
2. 逆向工程中的常见阻碍:证书锁定(SSL Pinning)
在移动端逆向工程中,经常遇到即便安装了 Charles 根证书也抓不到 HTTPS 包的情况(App 提示网络错误)。 * 逻辑冲突:某些高安全性的 App 开发者不再信任操作系统提供的全局 CA 证书列表。他们在 App 的代码内部硬编码(锁定)了真实服务器证书的哈希值或公钥(这就叫 SSL Pinning)。 * 为何失败:当 App 发起 TLS 握手时,收到 Charles 伪造的证书。虽然操作系统的信任链验证通过了,但 App 代码内部会将 Charles 证书的公钥与硬编码的真实公钥进行比对。发现不一致后,App 会主动识别出中间人攻击,并立即切断连接。 * (注:解决 SSL Pinning 通常需要使用 Frida/Xposed 等工具,直接修改 App 运行时的内存代码,强行绕过验证逻辑,这超出了 Charles 本身的功能范畴。)
3. OSI 协议栈限制:无法抓取传输层 / 网络层数据包
Charles 定位是一个 HTTP/HTTPS 代理工具(主要工作在应用层)。 * 逻辑冲突:它的工作前提是数据必须符合 HTTP 协议规范。它通过监听端口接收完整的 HTTP 报文。 * 为何失败: * TCP/UDP 底层协议:如果一个 App 不使用 HTTP,而是使用自己定义的基于 TCP/UDP 的私有二进制协议,或者你想观察底层的 TCP 三次握手(SYN, ACK 包)、丢包重传机制,Charles 是完全无能为力的,因为它根本不去解析这些传输层的报文结构。 * 网络层协议:Charles 无法抓取 ICMP(如 Ping 命令的数据包)或 ARP 协议。 * 替代方案:要分析传输层或网络层数据包,必须使用像 Wireshark 或 tcpdump 这样的网络嗅探工具。它们直接挂载在网卡驱动上,可以捕获流经网卡的每一个原始字节(Packet),无论是什么协议。但代价是,如果遇到 HTTPS 流量,Wireshark 只能看到加密的乱码,除非你提前把服务器的私钥导入 Wireshark 中。 *
参考文章
https://blog.csdn.net/weixin_43612602/article/details/135287720

浙公网安备 33010602011771号