
1. 为什么地址栏带着锁TraceEagle 还能看到明文中间人解密链路如果你以前只用过浏览器自带的 DevTools 看网络请求第一次接触独立抓包工具时大概率会有一个困惑接口明明走的是 HTTPS地址栏上还有小锁凭什么一个本地工具能把请求体和响应体原样摆出来这不是破解了 HTTPS而是做了一次中间人重新握手。1.1 不是暴力解密而是重新协商一条 TLS 链路先说结论TraceEagle 并没有去破解 TLS 加密算法它只是让你和服务器之间多了一个翻译官。正常访问一个 HTTPS 页面时客户端和服务器之间直接做 TLS 握手协商出的会话密钥只有两端知道。抓包工具想旁听唯一的办法就是让自己也参与到这条链路里。具体做法是你在 TraceEagle 里开启 HTTPS 解密并启动本机代理监听端口默认一般是 8888。浏览器发出的请求不再直达目标服务器而是先发给本机代理。TraceEagle 收到客户端请求后用自己签发的一张动态证书向浏览器冒充目标服务器和你完成一次 TLS 握手。此时它已经能拿到你发出的明文 HTTP 请求。它再作为客户端向真正的服务器发起第二条 TLS 连接拿到响应。两条连接都握在它手上请求和响应自然是透明的。如果把这套流程类比成寄信就是你本想把一封加密信直接寄给朋友结果有个人提前等在邮局自称是你朋友让你把信加密给他。他转手再帮你送给真正的朋友。全程他都能看到信的内容。前提是你认出了他的脸——这就是根证书的作用。1.2 HTTP 与 HTTPS 在抓包工具视角下的差别很多刚接触抓包的人觉得HTTPS 抓不到包就是工具不行其实不是。区别只在于工具是否完成了上述的中间人握手。对比项HTTPHTTPS默认端口80443传输内容明文TLS 加密后密文直接抓包能无需额外配置只能看到 TLS 握手与 CONNECT 隧道查看应用层内容直接读需安装根证书并开启解密对浏览器的影响无提示未受信证书会提示不安全一句话不管 HTTP 还是 HTTPS抓包工具都能看到流量。差别是 HTTPS 需要你先信任它的根证书让它有资格冒充每个网站签发证书。证书这一步跳过去你就只能对着 CONNECT 隧道发呆。1.3 TraceEagle 的完整抓包链路以 TraceEagle 为例一次典型操作的过程是打开工具点击开始捕获它会在本机 8888 端口启动一个 HTTP 代理。勾选解密 HTTPS 流量此时它会检查根证书是否已经安装。开启系统代理让浏览器流量自动经过 8888 端口。浏览器访问目标站点时TraceEagle 拦截到请求动态生成一张由根证书签发的目标域名证书返回给浏览器。浏览器验证证书链通过和 TraceEagle 建立 SSL 会话。TraceEagle 再把请求转发给真实服务器同样完成 TLS 握手。响应原路返回Tool 界面里同步刷新出请求行、请求头、请求体、响应头和响应体。这里有个容易被忽略的细节你在浏览器的地址栏里看到的目标网站证书其实是 TraceEagle 现场签发的那张。正常情况下它和真实证书长得并不一样区别在颁发者一栏。所以抓包调试完之后如果不再需要代理记得关闭系统代理同时把根证书从系统信任库里移除避免日常浏览一直被别人隔着看。2. 环境准备把 TraceEagle 变成系统可信代理证书两步装对工欲善其事必先利其器。抓包环境最容易翻车的点不在功能而在环境要么代理没生效要么证书没装对。这一节我把完整流程拆开讲清楚。2.1 安装 TraceEagle 与界面基本布局从官方渠道下载对应平台的安装包即可。Windows 和 macOS 都有图形界面Linux 下也提供了发行包。安装完成后第一次启动界面一般分为三块左侧是会话列表每一行代表一个请求能看到 URL、Method、状态码、耗时、大小。右侧是详情区分为请求头、请求体、响应头、响应体几个标签页。顶部是工具栏开始/停止捕获、清空列表、过滤器、HTTPS 解密开关、系统代理开关。在正式开始之前我建议把过滤器先设置成只显示目标域名的请求。如果你不设过滤全系统的流量都会涌进来包括各种软件更新、系统遥测、浏览器预加载找不到重点。设置方法很直接在过滤器输入框写上目标域名的一部分比如api.example.com或者example.comTraceEagle 就只会留下匹配的会话。这个动作做不做直接决定你后面分析请求时是十分钟还是十秒钟找到关键接口。2.2 安装根证书为什么必须装在受信任的根证书颁发机构当你开启解密 HTTPS 流量时TraceEagle 第一件事就是检查根证书是否存在。如果没有会弹出提示让你安装。这里有两个容易搞混的点第一要装的是 TraceEagle 自己的根证书不是目标网站的证书。这个根证书的作用是签发后续所有动态证书。第二必须安装到受信任的根证书颁发机构存储区不是个人存储区。Windows 上导入向导会让你选择证书存储位置默认是当前用户存储区默认是个人。这里一定改成受信任的根证书颁发机构。否则浏览器不认。macOS 上操作路径不太一样双击证书文件后在钥匙串访问里找到它展开信任选项把使用此证书时改成始终信任。这一步很多人漏掉装完证书浏览器依然报错就是因为默认信任状态是系统默认没有手动放行。装完后可以在 TraceEagle 的 HTTPS 解密面板里点验证证书工具会提示证书是否有效。这一步验证通过后面才不会再出幺蛾子。2.3 开启系统代理与验证整个链路证书装好后接下来开系统代理。TraceEagle 的工具栏上一般有一个设置系统代理的按钮点击后它会自动把 Windows/macOS 系统代理指向127.0.0.1:8888。此时去浏览器访问一个普通 HTTPS 网站比如随便打开一个大网站首页然后切到 TraceEagle 看会话列表。如果一切正常你应该能看到会话列表里出现大量https://...的请求展开任意一条能看到完整的请求头和响应头URL 是明文而不是CONNECT隧道我建议再用一个外部站点做验证因为目标站点可能带有 HSTS 或证书固定的逻辑首次验证容易误判。拿一个内容不敏感、结构简单的站点来看确认工具整体链路是通的再去折腾目标页面。验证时要重点关注三个位置检查点正常现象异常提示系统代理设置代理地址显示 127.0.0.1:8888未生效或指向其他代理浏览器访问 HTTPS地址栏正常显示小锁无证书告警显示 NET::ERR_CERT_AUTHORITY_INVALIDTraceEagle 会话列表URL 全部可读全是 CONNECT 443 域名说明解密没开如果看到CONNECT开头的那类请求基本能定位是解密开关没打开或者证书没装到正确位置。重新检查两步解密开关、受信任根证书。这两个解决掉九成问题已经消失。3. 反调试 debugger 是怎么让开发者工具卡死的以及绕过思路HTTPS 环境搞定下一步就是标题里最有意思的部分网页的debugger反调试。先理解它是什么、为什么难缠再谈怎么绕。3.1 无限 debugger 的两种典型写法debugger语句是 JavaScript 里的一个调试指令只要代码执行到这一行而且浏览器开发者工具处于打开状态脚本就会暂停在当前位置。反调试的套路就是利用这个特性在代码里塞入大量的debugger语句让你一打开开发者工具就寸步难行。最常见的写法有两种。第一种是定时器驱动setInterval(function () { debugger; }, 50);这段代码让浏览器每 50 毫秒执行一次debugger你刚手动恢复了执行下一秒又断住了根本来不及去看别的文件。第二种是递归驱动(function loop() { debugger; requestAnimationFrame(loop); })();效果类似但用的是浏览器的帧回调频率更高卡得更死。还有一种更隐蔽的写法把debugger放到字符串里再用eval执行setInterval(debugger;, 30);为什么说它更隐蔽因为eval执行的代码是运行时动态生成的每次执行都可能是一个新的代码位置你在开发者工具里根本没法对它右键设置永不在此暂停。3.2 为什么手动关断点治标不治本很多人遇到无限 debugger 的第一反应是在 Sources 面板里找到那一行右键选择永不在此暂停或者按 CtrlF8 停用所有断点。这两种方法对付静态页面里的debugger有效但对定时器驱动的版本效果很差。原因很简单debugger语句不是断点它是代码执行流程中的一条指令。停用断点功能只是让 DevTools 忽略预先设置的断点并不能忽略代码里显式写出来的debugger。你手动在某一处设置永不在此暂停它只是记录了这个位置可eval每次生成的新位置你根本没机会记录。有经验的人会配合 DevTools 的脚本忽略列表功能把包含debugger的整个 JS 文件加进忽略列表。这招对静态 JS 文件有效但同样绕不过eval动态生成的情况。而且有些页面的反调试不止debugger一处还会在检测到开发者工具打开时跳转到空白页、清空控制台输出、篡改窗口尺寸单纯靠 DevTools 本身的设置很难干净利落地解决。3.3 四种绕过思路从临时到彻底针对反调试的强度我通常按四层思路处理第一层临时跳过。在 DevTools 里按 CtrlF8 停用断点配合忽略列表。适合只调试一两分钟的场景。第二层条件断点。在某一处debugger行上设置条件断点条件是false。这样当执行到这一行时条件为假不会暂停。不过这个方法同样只针对静态源码里的固定位置。第三层禁用 JavaScript 后刷新。页面脚本全部不执行也就不会触发debugger。但代价是页面逻辑也没了接口请求多半不会自动发出。适合用来发现静态资源和接口路径不适合做完整流程分析。第四层响应替换。也是最推荐的方式。用 TraceEagle 把包含debugger语句的 JS 文件拦截下来下载到本地删掉所有debugger指令再让 TraceEagle 把这个本地版本返回给浏览器。浏览器拿到的是干净代码从头到尾不会触发反调试。第四层之所以最推荐是因为它对eval版本也有效只要在源文件层面把debugger字符串清掉动态生成出来的代码自然也不含debugger。绕过了最底层后续怎么抓包都顺畅。4. 实战用响应替换干掉无限 debugger再抓接口、改请求重放理论讲完下面进入完整实战。我假设你已经装好了 TraceEagle证书也已经安装到位。整个流程分成三步先让页面不再卡死再看请求最后重放验证参数。4.1 Step 1用 TraceEagle 把有 debugger 的 JS替换成本地干净版本首先清空 TraceEagle 的会话列表设置过滤器为你要调试的目标域名然后打开开发者工具观察页面是否卡在断点上。如果卡住先不要忙着在 DevTools 里折腾直接刷新页面让页面在所有脚本执行前尽量把资源加载出来。接下来在 TraceEagle 的会话列表里按资源类型筛选出 JavaScript 文件。如果页面脚本很多可以逐个点开看响应内容也可以直接搜索响应体里的关键词debugger。找到包含debugger的脚本后操作步骤是选中该条会话在右侧响应体标签页里把原文保存到本地命名为app.debug.js。用编辑器打开搜索debugger的所有出现位置。删除格式独立的debugger;语句。我常用的正则表达式是^\s*debugger\s*;\s*$匹配整行只有debugger的语句逐行删除。保存为app.clean.js。在 TraceEagle 中右键刚才那条会话找到映射本地文件不同版本菜单名可能略有差异类似 Map Local 或 Rewrite选择app.clean.js。保存规则后清空浏览器缓存刷新页面。此时再打开开发者工具页面应当不再被断点卡住可以正常查看 Network 面板和代码逻辑。这里要提醒一句删除debugger时不要用简单的全局替换因为有些代码里会把debugger作为字符串拼进日志比如console.log(debugger paused)这种不该删。逐行匹配只是最快速的做法如果你对正则熟悉用debugger\s*;配合上下文判断也行。总之原则是只删语句不误伤字符串。4.2 Step 2在 TraceEagle 会话列表里定位真正的接口请求页面恢复正常后重新回到 TraceEagle清空一次会话列表然后在页面里去点那些会触发接口交互的按钮比如登录、查询列表、提交表单。过滤器的价值在这一步完全体现出来。如果你的过滤器只保留了目标域名会话列表里剩下的就是这一站点的全部请求。接下来按请求类型排序优先看 XHR 和 Fetch请求行里的 Method 是 POST 还是 GETURL 路径是否直接暴露操作意图比如/api/login、/v1/order/list请求头里的Content-Type是否为application/json请求体内容是否为明文 JSON如果页面接口正常返回TraceEagle 的响应体会以格式化后的 JSON 呈现。这一下接口地址、入参、出参全在眼前省去了在 DevTools 里翻来翻去还时刻担心被反调试打断的折磨。我还习惯在响应体里搜索几个关键词比如code、data、success快速判断这条响应是正常业务响应还是错误反馈。如果某个接口返回了 4xx 的状态码直接在响应头里看错误原因很多是参数校验失败比盲猜快得多。4.3 Step 3用重放功能验证签名和参数逻辑抓到接口只是第一步真正有价值的是验证请求能不能被重放、参数是怎么参与计算的。在 TraceEagle 中选中一条请求右键选择重放或复制为 cURL 命令。如果选择重放工具会弹出一个编辑窗口里面就是该请求的完整副本URL、请求头、请求体都能改。我拿一个典型的登录接口举例。假设原始请求是POST https://example.com/api/login Content-Type: application/json {username:tester,password:123456,timestamp:1735000000000,sign:a1b2c3d4e5}第一次重放时不做任何修改确认接口返回结果是否和原始一致。如果一致说明服务端没有做重放次数限制。然后再改掉timestamp后端返回签名错误就能确定这个字段参与了签名计算。继续改sign的值如果后端不再校验签名说明这个接口的鉴权防线很弱。这种逐步修改、逐个看反应的做法是分析接口参数逻辑最有效的手段。做自己产品的接口测试时我能把前端到底传了哪些参数、哪些参数被服务端信任摸得清清楚楚。如果做的是授权测试这套方式也能帮你快速梳理接口的暴露面。重放请求本身有两类常见问题顺带排查现象可能原因处理方式重放提示签名错误请求参数参与了签名计算修改参数后重新生成签名字段重放返回 401/403请求头缺失 Cookie 或 Authorization从原始请求里复制对应请求头重放成功但数据为空请求体内字段冗余导致服务端解析异常尝试精简请求体保留最小字段5. 抓包翻车现场证书、断点、乱码、长连接四个高频坑不管准备得再充分实际抓包时总会撞上一些看起来是在报错、其实原因很隐蔽的问题。我把这几年用 TraceEagle 以及同类工具时遇到的高频坑集中梳理一遍。5.1 证书装好了目标站还是提示不安全最常见的原因是 HSTS。目标站点如果开启了严格传输安全协议浏览器会强制使用 HTTPS并且拒绝跳过证书警告。第一次通过代理访问时如果证书链路没完全打通浏览器可能把这个站点的 HSTS 缓存下来之后就算证书装好了浏览器依然拦着。解决办法是换一个隐身窗口测试或者在浏览器设置里清除该站点的 HSTS 状态。Chrome 可以访问chrome://net-internals/#hsts在 Delete domain 里输入目标域名删除。这也是为什么我在最开始建议先访问一个无关站点验证链路把HSTS 留下的坏印象和证书安装问题区分开。另外代理监听端口如果同时支持 IPv4 和 IPv6而系统代理只配置了 IPv4某些优先走 IPv6 的流量会绕开代理。遇到部分域名抓不到的情况可以在 TraceEagle 的监听设置里关闭 IPv6只保留 IPv4再试一次。5.2 替换了脚本debugger 还是反复出现明明已经把app.js映射到了本地干净版结果刷新后 DevTools 还是被卡住。这时候不要怀疑替换规则没生效先确认页面里到底加载了几个脚本。有些页面会把业务代码拆成多个文件比如vendor.js、app.js、config.js反调试逻辑可能分散在其中多个文件里甚至藏在一个看起来名字完全无关的异步加载脚本中。你只替换了其中一个剩下的还在继续执行debugger。处理办法是在 TraceEagle 的会话列表里按脚本大小排序把所有 JS 都检查一遍。如果脚本数量太多可以先让页面在反调试卡住的情况下尽量加载完所有资源然后搜索所有 JS 会话响应体里的debugger连eval(debugger)这种字符串也一起搜出来一并替换。另外留意一种情况页面运行过程中主动拉取了一段包含反调试逻辑的文本再通过eval执行。这种请求在 TraceEagle 里表现为 XHR 或 Fetch 请求响应体是一段 JS 代码。对它做映射替换同样有效只是你要多找一步先定位哪个接口返回了这段代码。5.3 响应体是一堆乱码或者显示出二进制内容如果请求和响应都已经解密但响应体看起来像天书十有八九是压缩格式的问题。常见的编码是Content-Encoding: gzip、brBrotli。TraceEagle 一般会自动解压如果某个响应没有自动解压检查右侧响应体区域有没有解码选项点击触发一次手动解压。还有一种是字符编码问题。接口返回的Content-Type里如果没有明确charset浏览器按默认规则可能是 UTF-8但某些老接口实际上是 GBK。这时候在响应体显示区域手动切换编码。遇到特别大的 JSON 响应时原始文本视图很难读。直接切换到 JSON 格式化视图TraceEagle 会帮你缩进、着色字段层级一目了然。哪怕嵌套很深也能快速定位某个字段。5.4 WebSocket 和 SSE 长连接抓不到内容普通的 HTTP 请求好抓长连接就不一样了。如果你的目标页面里有实时行情、在线聊天或者消息推送这些数据往往走 WebSocket而不是普通 XHR。TraceEagle 里查看 WebSocket 帧的方式是在会话列表中找到目标域名的websocket条目点开后能看到客户端发送的帧和服务端返回的帧。每一帧都会显示时间戳、方向和内容内容是文本的话直接可读二进制帧需要逐个查看。这里要注意WebSocket 的握手阶段也是 HTTPS需要证书信任。如果握手失败先排查证书如果握手成功但看不到帧检查 WebSocket 解码开关是否打开。SSEServer-Sent Events则比较特殊它以普通 HTTP 流的方式存在响应体会被持续推送。在 TraceEagle 里要留意状态码和响应头Content-Type: text/event-stream就是 SSE。这类连接不需要额外开关但你在页面上操作时SSE 频道可能一直在刷新会话列表里会出现大量持续跳动的条目过滤时要留意。6. 这套流程背后的一点使用原则与收尾习惯文章最后我想说几句看着像废话、但实际吃了亏才懂的原则。抓包和绕过反调试本身是中性的调试技能。拿它来干嘛决定它的性质。我自己常用 TraceEagle 的场景一是调试自己的前端项目看看打包后的代码到底向服务器发了什么二是做授权测试时捋接口参数三是在接手别人遗留的项目时快速搞清楚页面和服务端之间的真实数据流。不管哪种场景都有一个共同前提这个页面或者接口是你自己拥有的或者你拿到了明确的测试授权。不要拿这套流程去采集未授权数据也不要绕过别人反调试机制之后去批量调用接口。技术上做得到不代表行为上应该做。一旦越界抓包工具从调试利器变成风险源头真的没必要。从操作习惯上说我建议给抓包单独准备一个浏览器配置目录或者干脆用隐身窗口做测试。不要把抓包代理和日常浏览混在一起不然你会发现自己看个视频网站流量也全部从 TraceEagle 过一遍又慢又乱。调试结束后记得顺手关掉 TraceEagle 里的系统代理开关再考虑要不要卸载根证书。长期保留根证书会让本机所有 HTTPS 流量都被这个工具信任一旦工具被植入恶意逻辑等于给自己埋了一颗雷。替换文件多留几份版本也是个值当的习惯。碰到代码更新直接复用之前的本地脚本拿新版本和旧版本做 diff一眼就能看出对方加了哪些新逻辑。这一步做多了你对前端反调试手法的识别速度会快很多。抓包这门手艺底层逻辑不复杂理解流量怎么走理解证书怎么被信任理解代码怎么被执行。能做到这三点不管是 HTTPS、debugger 还是别的花活都只是纸老虎。先把 TraceEagle 的证书和环境跑通再找一个小页面练手整条流程走一遍之后你的调试工具箱里就又多了一把趁手的家伙。