公司动态
Charles抓包进阶:断点与重写实战,掌握HTTP/HTTPS流量拦截与修改
1. 项目概述从“看”到“改”的抓包进阶做移动开发或者接口测试的朋友对抓包工具肯定不陌生。我们常用它来查看App和服务器之间到底在“聊”些什么排查问题、分析数据流。但很多时候仅仅是“看”已经不能满足需求了。比如你想测试一个支付回调接口但总不能真的一直花钱去触发吧或者你想模拟服务器返回一个特定的错误码来验证客户端的容错逻辑又或者你想绕过客户端的某些限制临时修改请求参数。这时候就需要从“观察者”升级为“参与者”也就是对网络请求进行拦截和修改。“Charles拦截抓包修改包里面内容”这个标题指向的就是这个核心进阶技能。它不再是简单的流量镜像而是一种主动的、干预式的调试和测试手段。Charles作为一款老牌且强大的HTTP/HTTPS代理工具其“断点”Breakpoints和“重写”Rewrite功能正是实现这一目标的利器。掌握它意味着你可以在不修改客户端和服务端任何代码的情况下动态地改变网络交互的行为这为开发调试、安全测试、数据模拟打开了新世界的大门。无论是前端开发者想模拟后端接口返回还是测试工程师需要构造异常场景亦或是安全研究员分析应用逻辑这都是必须掌握的实操技能。2. 核心原理与工具准备Charles如何成为“中间人”在深入实操之前我们必须先搞清楚Charles凭什么能拦截和修改我们的数据包。这一切都基于一个经典的网络模型“中间人”Man-in-the-Middle MITM代理。2.1 “中间人”代理的工作原理想象一下客户端比如你的手机App和服务器比如api.example.com想要直接通信。Charles介入后就变成了这样客户端不再直接连接服务器而是连接CharlesCharles再以自己的身份去连接服务器。于是客户端与Charles之间建立了一个连接Charles与服务器之间建立了另一个连接。对于客户端来说Charles“伪装”成了服务器对于服务器来说Charles“伪装”成了客户端。所有流经的数据都会在Charles这里做一个“中转”。正因为Charles是流量的必经之路它才有机会在数据“路过”时将其截停下来Breakpoint让你查看和修改然后再放行。注意正是因为这种“中间人”特性在使用Charles抓取HTTPS流量时需要在其和客户端之间建立一种特殊的信任关系即安装Charles的根证书到客户端设备上。否则客户端会检测到证书不匹配从而中断连接这也是抓取HTTPS包的必要前提步骤。2.2 Charles核心功能模块解析要实现拦截修改主要依赖Charles的两个核心功能模块它们适用于不同的场景断点Breakpoints这是一种“实时、手动”的拦截方式。你可以为特定的网络请求通过URL匹配规则设置设置断点。当请求命中规则时Charles会立即暂停请求或响应的传输弹出一个编辑窗口等待你手动修改其中的任何内容如URL、请求头、请求体、响应状态码、响应体等。修改确认后再继续执行。这种方式非常灵活适合临时性的、交互式的调试。重写Rewrite这是一种“自动、批量”的修改方式。你可以定义一系列规则例如“将所有发送至api.demo.com的请求头中的User-Agent修改为MyCustomClient”或者“将所有来自service.test.com的响应体中的字符串”success”: false替换为”success”: true”。规则设置好后Charles会在后台自动执行所有匹配的请求和响应无需人工干预。这种方式适合需要长期、批量修改的场景比如自动化测试。2.3 环境配置与证书安装工欲善其事必先利其器。在开始拦截修改前必须完成基础配置尤其是HTTPS抓包配置这是很多新手卡住的第一步。在电脑端Charles运行端启动Charles首次启动会请求授予代理权限允许即可。确保Proxy - Proxy Settings…中的HTTP代理端口默认8888是开启的。最关键的一步安装Charles根证书到你的计算机“受信任的根证书颁发机构”存储中。通过Help - SSL Proxying - Install Charles Root Certificate完成。安装后请务必打开系统的证书管理器找到该证书并手动将其设置为“信任”。在移动设备端如iPhone/Android确保手机和电脑在同一局域网连接同一个Wi-Fi。在手机Wi-Fi设置中配置代理服务器为电脑的IP地址端口为Charles的代理端口默认8888。在手机浏览器中访问chls.pro/ssl这个链接会引导你下载并安装Charles的根证书。对于iOS安装描述文件后还需进入设置 - 通用 - 关于本机 - 证书信任设置找到Charles Proxy证书并完全信任。对于Android安装证书后可能还需要在系统设置中为已安装的证书设置凭据用途部分机型需要。完成以上步骤后在Charles中开启Proxy - SSL Proxying Settings…添加一个通用的SSL代理设置Host为*Port为*。这表示对任何域名的HTTPS流量都进行解密代理。此时你应该能在Charles中看到明文的HTTPS请求了。3. 实战演练使用断点功能手动修改请求与响应断点功能是最直观、最常用的拦截修改方式。我们来通过两个典型场景一步步走通整个流程。3.1 场景一修改请求参数模拟用户提交假设我们正在测试一个商品搜索接口GET https://api.shop.com/search?keyword手机page1我们想测试当关键词keyword参数为空或超长时服务器的处理情况。操作步骤定位请求在Charles左侧的Structure视图中找到并选中你想要拦截的域名api.shop.com或具体的请求路径/search。设置断点右键点击该域名或请求选择Breakpoints。你也可以通过Proxy - Breakpoint Settings…来更精细地管理断点规则列表。在这里你可以添加规则通过URL支持通配符*来匹配请求。触发请求在手机App或浏览器中执行触发该搜索请求的操作。拦截与修改请求发出后Charles会立即弹出 “Breakpoint Request for [请求URL]” 窗口。这个窗口分为两部分请求视图这里展示了即将发送给服务器的所有信息。你可以直接修改Query标签页下的keyword参数值比如清空它或者输入一串很长的字符。执行操作修改完毕后点击底部的Execute按钮。Charles会将你修改后的请求发送给服务器。拦截响应可选如果你在Breakpoint设置中也勾选了响应拦截那么在服务器返回数据后Charles会再次弹出 “Breakpoint Response for [请求URL]” 窗口。在这里你可以修改服务器返回的JSON数据、状态码等然后点击Execute将修改后的响应返回给客户端。实操心得设置断点时尽量使用具体的URL路径而不是整个域名否则该域名下的所有请求都会被拦截导致操作繁琐且影响其他请求。对于修改请求体如POST的JSON在请求视图的JSON Text标签页下修改非常方便Charles会自动格式化JSON。3.2 场景二修改响应内容构造特定测试数据假设我们需要测试App在收到一个特定的错误响应如{“code”: 500, “msg”: “Internal Server Error”}时的UI展示和逻辑处理。操作步骤清除请求断点为了避免重复修改请求我们可以在Breakpoint Settings中编辑规则取消Request的勾选只保留Response。这样只会拦截响应。触发正常请求在客户端进行一次正常的搜索操作。拦截并篡改响应当Charles弹出响应断点窗口时切换到JSON Text视图。将原本正常的响应体完全替换为我们的错误数据{“code”: 500, “msg”: “Internal Server Error”}。同时你还可以在Status区域将HTTP状态码从200改为500。执行并观察点击Execute。客户端App收到的将是你构造的错误响应你可以立即观察到App的界面变化、弹窗提示、日志输出等从而验证其错误处理机制是否健全。这个功能在测试边界条件和异常流程时无比强大你无需等待后端配合部署错误代码就能独立完成客户端健壮性测试。4. 高效自动化使用重写规则批量修改流量断点虽好但每次都需要手动点击不适合需要重复执行或批量修改的场景。这时“重写”Rewrite功能就是你的自动化脚本。4.1 重写规则的核心组成一个重写规则集Rewrite Set包含多个规则Rule每个规则由四个核心部分组成位置Location定义规则作用于请求Request还是响应Response。匹配条件Match通过协议、主机、端口、路径、查询参数等来筛选目标流量。支持使用正则表达式进行复杂匹配。操作Action定义要执行的具体修改动作如修改头Header、修改查询参数Query、替换正文Body等。值Value指定操作的目标值可以是固定字符串也可以是包含正则表达式分组的变量如$1。4.2 实战案例全局修改User-Agent与特定接口数据替换案例A为所有请求添加一个自定义标记头假设我们想标记所有经过Charles的流量以便在服务器日志中区分。打开Tools - Rewrite…创建一个新的重写规则集比如命名为 “Add Custom Header”。点击Add新建一条规则。位置选择Request。匹配条件为了匹配所有请求可以将Host留空或者填写*。Path也留空。操作选择Add Header。值Name:X-Debug-SourceValue:Charles-Rewrite保存并启用该规则集。此后所有从客户端发出的请求都会自动带上X-Debug-Source: Charles-Rewrite这个头信息。案例B将某个接口的响应数据中的价格单位“元”改为“美元”假设接口https://api.shop.com/product/123返回的JSON中有一个字段”price”: “100元”我们需要在测试时模拟国际化展示。在Rewrite设置中新建规则集 “Currency Replace”。Add新规则。位置Response。匹配条件Host:api.shop.comPath:/product/123(也可以使用/product/*匹配所有商品)操作选择Body-Replace。值这里需要使用正则表达式。Find:(\d)(元)(这个正则匹配数字“元”并将数字和“元”分别放入分组$1和$2)Replace:$$$1美元(这里$$表示输出一个$符号$1引用第一个分组即数字后接“美元”)注意在Charles的Replace框中$符号有特殊含义引用分组所以如果要输出字面值$需要转义为$$。保存启用。之后所有匹配的响应返回的”100元”都会被自动替换为”$100美元”。重写规则的强大之处在于其“设置一次自动运行”的能力非常适合在集成测试、性能测试或安全测试中构造持续的、特定的流量环境。5. 本地映射与远程映射更彻底的流量接管除了动态修改Charles还提供了静态映射功能可以将请求直接指向本地文件或另一个远程地址实现更彻底的流量“调包”。5.1 本地映射Map Local这个功能允许你将某个特定的网络请求直接映射到本地计算机上的一个文件。服务器根本不会收到这个请求客户端拿到的是你本地文件的内容。典型场景接口尚未开发完成前端需要静态数据进行UI开发和联调。让后端提供一份完整的、符合接口规范的JSON数据文件。在Charles中选中该请求右键选择Save Response…将响应体保存为一个本地.json文件。再次右键选中该请求选择Map Local…。在设置窗口中选择你刚才保存的本地JSON文件。点击OK。之后所有对该URL的请求Charles都会直接返回本地文件的内容而不会去访问真正的服务器。注意事项使用Map Local时响应的HTTP状态码会固定为200OK。如果你需要测试非200状态码如404, 500Map Local无法直接实现这时应使用断点Breakpoints功能来修改状态码或者使用远程映射Map Remote映射到一个能返回错误码的测试服务器。5.2 远程映射Map Remote这个功能可以将请求从一个地址重定向到另一个地址。比如将指向生产环境的请求临时重定向到测试环境。典型场景在测试环境中使用生产环境的App安装包进行测试避免打包。打开Tools - Map Remote…。启用Enable Map Remote。点击Add添加一条映射规则。匹配Map FromProtocol:httpsHost:api.product.com(生产环境主机)Path:/v1/user/login(可选可以只映射特定路径)重定向到Map ToProtocol:httpsHost:api.test.com(测试环境主机)Path:/v1/user/login(路径可以保持不变也可以修改)保存后所有原本发往api.product.com/v1/user/login的请求都会被Charles透明地转发到api.test.com/v1/user/login。这对于进行全链路测试、灰度发布验证非常有用。6. 常见问题排查与实战技巧在实际使用中你肯定会遇到各种“坑”。下面是一些高频问题和我积累的实战技巧。6.1 HTTPS抓包失败或显示乱码这是最常见的问题根本原因在于SSL证书信任链未正确建立。现象HTTPS请求显示为unknown或SSL Proxying not enabled for this host或者能看到请求但内容是乱码。排查清单电脑证书是否已信任这是最容易被忽略的一步。在电脑上安装Charles根证书后必须手动打开系统钥匙串访问Mac或证书管理器Windows找到Charles Proxy CA或类似名称的证书双击打开在“信任”设置中将“使用此证书时”设置为“始终信任”。手机证书是否已安装并信任确保手机通过chls.pro/ssl安装了证书且iOS在“证书信任设置”中已启用完全信任。SSL代理设置是否包含目标域名在Proxy - SSL Proxying Settings…中检查是否添加了*:*的通配规则或者至少添加了你需要抓取的特定主机和端口如*.yourdomain.com:443。App是否启用了证书锁定SSL Pinning一些安全性要求高的App如银行、支付类会内置服务器证书只信任固定的证书从而防止中间人攻击。这种情况下Charles的通用根证书无效。解决方案通常需要反编译App并绕过证书锁定这涉及更复杂的技术且可能违反用户协议需谨慎评估。6.2 断点或重写规则不生效检查规则是否启用在Breakpoint Settings或Rewrite设置中确保顶部的Enable Breakpoints或Enable Rewrite复选框是勾选的并且对应的规则集也是勾选状态。检查匹配条件URL匹配是否准确注意大小写和路径。对于重写规则检查Host和Path是否填写正确特别是当Path有查询参数时匹配的是路径部分不包含?之后的内容。清除缓存Charles和客户端浏览器/App都可能缓存了旧的请求。尝试在Charles中清除当前会话Charles - Clear Session并在客户端上拉刷新或重启App。规则执行顺序如果有多条重写规则它们会按列表顺序执行。后执行的规则可能会覆盖前面规则的效果。检查规则顺序是否符合你的预期。6.3 修改复杂JSON或二进制数据JSON格式化在断点编辑窗口或重写规则的Body替换中如果原始数据是格式化的JSON修改起来很方便。如果是压缩过的一行可以点击视图下方的{}按钮进行格式化。二进制数据对于图片、音视频等二进制响应在断点窗口中可能显示为十六进制码。直接修改二进制数据非常困难通常的用途是“替换”整个响应体。这时使用Map Local功能直接映射到一个本地的二进制文件如图片是更合适的选择。6.4 性能影响与使用建议开启断点会显著减慢网络请求速度因为每个匹配的请求都需要等待人工操作。在不需要时应及时关闭断点功能。重写规则对性能影响较小但复杂的正则表达式匹配也可能带来开销。一个高效的工作流是使用断点进行探索性调试和一次性修改找到规律后将固定的修改模式提炼成重写规则实现自动化。对于固定的Mock数据则使用本地映射。将三者结合使用能让你在网络调试和测试中游刃有余。最后记住Charles是一个强大的工具但能力越大责任越大。请仅在自己的开发、测试环境或已获得明确授权的设备上使用拦截修改功能切勿用于干扰或窥探他人的网络通信这是基本的职业操守和技术伦理。