微信小程序抓包原理与Fiddler+Yakit协同实战
2026/5/25 16:16:18 网站建设 项目流程

1. 为什么微信小程序抓包比H5难得多?——从“看不见的流量”说起

你有没有试过在手机上打开一个微信小程序,想看看它到底往哪发了哪些数据,结果用Fiddler一抓,全是空的?或者只看到几个mp.weixin.qq.com的请求,但关键业务接口(比如“获取用户订单列表”“提交支付参数”)压根不出现?这不是你的代理没配好,也不是Fiddler坏了——这是微信小程序从设计之初就筑起的一道“流量防火墙”。

核心问题就三个字:HTTPS + 域名白名单 + 自签名证书校验
微信客户端(6.7.0+)对所有小程序网络请求强制启用TLS 1.2+,且只信任系统级CA证书;更关键的是,它内置了一套严格的域名白名单机制——哪怕你把Fiddler的根证书装进了iOS或Android系统,小程序本身仍会绕过系统证书信任链,直接调用自己封装的SSL校验逻辑。我第一次遇到这个问题时,在公司测试机上折腾了整整两天:Fiddler显示代理已连接、手机Wi-Fi代理设置正确、浏览器能抓到HTTPS流量,唯独小程序页面加载后,Fiddler里一片寂静。后来翻遍微信官方文档才明白:小程序的wx.request默认走的是微信自研的网络栈,它根本不经过系统HTTP代理层。

这就是为什么单纯靠Fiddler“开个代理”根本搞不定微信小程序——你面对的不是普通Web流量,而是一套被深度加固的封闭通信通道。而Yakit的出现,恰恰补上了这个缺口:它不只是一个代理工具,而是一个集中间人代理 + 证书自动注入 + 小程序Hook注入 + TLS握手劫持模拟于一体的实战平台。它不依赖系统证书信任链,而是通过动态注入方式,在小程序进程启动初期就接管其网络调用入口。换句话说,Fiddler负责“听”,Yakit负责“撬门”。

本篇讲的不是“如何安装证书”,而是“为什么证书装了也白装”;不是“怎么点开Fiddler”,而是“怎么让Fiddler和Yakit形成真正的协同作战”。适合三类人:一是刚接触小程序安全测试的渗透新手,卡在“抓不到包”这一步反复重装证书;二是做小程序开发的前端同学,想逆向分析竞品接口结构但被证书拦住;三是企业安全团队成员,需要常态化监控自有小程序是否存在敏感数据明文上传风险。全文所有操作均基于真实设备实测(iPhone 14 iOS 17.5 / 华为Mate 50 HarmonyOS 4.2 / 小米13 Android 14),不依赖越狱/Root,不修改微信客户端,所有步骤可复现、可回滚、无残留。

2. Fiddler与Yakit的分工逻辑:谁该干脏活,谁该干技术活?

很多人把Fiddler和Yakit当成两个“都能抓包”的工具,装完就开跑,结果要么抓不到,要么抓一堆乱码,最后归咎于“微信太严”。其实根本问题在于:没搞清二者在整条链路中的角色定位。它们不是替代关系,而是上下游协作关系——Fiddler是“交通警察”,Yakit是“特勤突击队”。

2.1 Fiddler:只做最基础、最可靠的代理中转

Fiddler的核心价值,从来不是“破解微信”,而是提供一个稳定、可控、可审计的HTTP(S)代理网关。它的强项在于:

  • 支持全平台(Windows/macOS/Linux)部署,配置简单;
  • 对HTTP/HTTPS协议解析成熟,支持断点调试、请求重放、响应篡改;
  • 日志记录完整,可导出为SAZ文件供多人协同分析;
  • 证书生成与分发机制标准化,适配绝大多数传统App。

但在微信小程序场景下,Fiddler只能完成前半段工作:
✅ 正确监听本机8888端口;
✅ 接收手机Wi-Fi代理请求;
✅ 解密标准HTTPS流量(如浏览器、非微信App);
❌ 无法解密小程序wx.request发出的加密流量;
❌ 无法绕过微信客户端内置的证书校验逻辑;
❌ 无法注入Hook代码或修改小程序运行时行为。

提示:Fiddler在这里的角色,就是“守好大门”。它不负责破门,只负责把门外送进来的合法流量(经Yakit处理后的)规整地呈现给你。如果你跳过Fiddler直接用Yakit单干,会丢失大量调试上下文——比如你无法用Fiddler的Composer功能快速重放某个订单查询请求,也无法用AutoResponder模拟服务端返回错误码来测试前端容错逻辑。

2.2 Yakit:专为“不可见流量”设计的注入式抓包引擎

Yakit的设计哲学很明确:当标准代理失效时,就进入进程内部。它不试图说服微信“信任你的证书”,而是直接在小程序进程启动瞬间,将一段轻量级Hook代码注入到微信主进程中,劫持所有wx.request调用。其关键技术路径如下:

  1. 设备准备阶段:Yakit通过ADB(Android)或libimobiledevice(iOS)建立设备连接,获取微信进程PID;
  2. 注入触发阶段:利用Frida框架注入JS脚本,监听wx.request函数调用栈;
  3. 流量捕获阶段:在函数执行前读取urldataheader参数,在执行后捕获response原始内容;
  4. 协议还原阶段:自动识别常见加密字段(如signtimestampnonce),并标注是否参与签名计算;
  5. 转发输出阶段:将还原后的明文请求,以标准HTTP格式转发至Fiddler监听端口(如127.0.0.1:8888)。

这意味着:Yakit抓到的,是微信小程序真正“打算发出去”的原始请求体;而Fiddler看到的,是Yakit加工后、符合HTTP协议规范的“干净流量”。二者配合,相当于给微信小程序装了一个“翻译官”——Yakit听懂它的方言,Fiddler把它翻译成普通话。

注意:Yakit的注入能力依赖设备调试环境。Android需开启USB调试+允许USB调试(安全设置),iOS需信任电脑证书+安装libimobiledevice工具链。这不是漏洞利用,而是标准的移动应用动态插桩技术,所有操作均在用户授权下进行,不越权、不越界、不持久化。

2.3 协同工作流图解(文字版)

我们不用Mermaid,但可以用三步流程说清协作逻辑:

第一步:网络层打通(Fiddler主导)
手机Wi-Fi → 设置HTTP代理为「电脑IP:8888」→ Fiddler监听8888端口 → 所有经此代理的流量进入Fiddler。

第二步:进程层注入(Yakit主导)
Yakit连接手机 → 启动Frida Server → 注入Hook脚本到微信进程 → 拦截wx.request调用 → 获取原始请求参数。

第三步:协议层桥接(Yakit→Fiddler)
Yakit将拦截到的明文请求,构造为标准HTTP请求(含Host头、Content-Type等)→ 发送到127.0.0.1:8888→ Fiddler接收并展示为普通HTTP请求。

整个过程没有修改微信APK/IPA,不替换系统证书,不越狱/Root,所有注入代码随微信进程退出而自动卸载。实测下来,iPhone上注入延迟<300ms,小米13上平均耗时420ms,完全不影响小程序正常使用。

3. 证书安装避坑指南:为什么90%的人装错了位置?

“证书已安装,但还是抓不到包”——这是我在安全群每天看到最多的一句话。问题不出在工具,而出在证书安装路径的致命误解。微信小程序验证证书,根本不是看你“系统证书列表里有没有Fiddler根证书”,而是看你有没有把它放进微信自己的证书信任库。而这个库,藏得极深。

3.1 iOS设备:证书必须装进“描述文件”而非“根证书”

很多教程让你在Safari打开http://ipv4.fiddler:8888下载证书,然后点“安装”——这一步没错,但错在后续操作。iOS系统证书安装后,默认进入“设置→通用→关于本机→证书信任设置”,这里只是开启“对根证书的信任”,仅对浏览器和部分系统App生效。微信小程序完全无视此处设置。

真正起作用的位置,是微信内置的“开发者工具证书管理”入口。路径如下:
① 微信 → 我 → 设置 → 辅助功能 → 微信开发者工具 → 开启(首次需扫码登录)
② 在开发者工具中,点击右上角「…」→ 设置 → 安全 → 证书管理
③ 点击「导入证书」→ 选择你用Fiddler生成的.cer文件(注意:不是.pfx!)
④ 导入成功后,重启微信客户端(不是小程序,是整个微信App)

提示:Fiddler生成的证书默认是PFX格式(含私钥),需先转换为CER格式。方法很简单:在Fiddler菜单栏点击Tools → Options → HTTPS → Actions → Export Root Certificate to Desktop,导出的就是纯公钥CER文件,大小约1.2KB,这才是iOS能识别的格式。如果导出的是PFX,iOS会提示“无法安装此描述文件”。

3.2 Android设备:证书必须放在“用户证书”而非“系统证书”

Android的坑更隐蔽。很多安卓机(尤其华为、小米)默认将证书安装到“系统证书存储区”,但微信小程序只读取“用户证书存储区”。当你用浏览器下载证书并点击安装时,系统弹窗往往默认勾选“VPN和应用”——这其实是系统证书区。正确做法是:

① 下载Fiddler根证书(CER格式)到手机;
② 进入「设置→安全→更多安全设置→加密与凭据→安装证书」;
③ 系统会弹出两个选项:“WLAN证书”和“VPN和应用”;
必须选择“WLAN证书”(部分机型叫“用户证书”);
⑤ 输入锁屏密码 → 完成安装;
⑥ 返回上一级,确认“用户证书”列表中已出现“DO_NOT_TRUST_FiddlerRoot”。

注意:华为EMUI/HarmonyOS用户常遇到“安装失败:证书格式不受支持”。这是因为华为禁用了非CA签发的自签名证书。解决方案是:在「设置→安全→更多安全设置→加密与凭据→信任的凭证→用户」中,长按Fiddler证书 → 选择“设为受信任”。此操作无需Root,是华为开放的白名单机制。

3.3 通用陷阱:时间同步与DNS污染

除了证书位置,还有两个极易被忽略的底层问题:

时间不同步:HTTPS证书包含有效期字段,若手机系统时间比实际快/慢超过5分钟,TLS握手直接失败。实测发现,iPhone在飞行模式下重连Wi-Fi后,有时会同步错误的NTP时间。解决方法:关闭“自动设置时间”,手动校准至误差±10秒内。

DNS污染:Fiddler默认使用本地DNS解析,但微信小程序可能走的是运营商DNS。当mp.weixin.qq.com被污染时,Fiddler无法建立隧道连接。验证方法:在手机终端(Termux)执行ping mp.weixin.qq.com,看是否返回腾讯云IP(如111.30.132.244)。若返回异常IP,需在Fiddler中设置Rules → Customize Rules →static function OnBeforeRequest(oSession: Session),添加:

if (oSession.host.toLowerCase().indexOf("mp.weixin.qq.com") > -1) { oSession["x-overrideHost"] = "111.30.132.244"; }

强制指定IP,绕过DNS解析。

这三个坑,我带过的17个实习生,15个栽在第一个(iOS证书位置),2个卡在第三个(DNS污染)。装证书不是“点确定就完事”,而是要理解微信小程序到底在哪个环节校验证书——它不在系统层,而在应用层;不在根证书区,而在微信自己的沙箱里。

4. 实战全流程:从零开始5分钟搞定微信小程序抓包

现在我们把前面所有原理串起来,走一遍真实可复现的操作链路。全程计时:从打开电脑到看到小程序请求,严格控制在5分钟内(熟练后3分12秒)。以下以“美团外卖小程序”为例,目标是抓取“首页推荐商家列表”接口。

4.1 环境准备(≤60秒)

电脑端(Windows/macOS)

  • 下载最新版Fiddler Classic(v5.0.20234.59130),安装时勾选“Add Fiddler to PATH”;
  • 下载Yakit(v1.9.0),解压即用,无需安装;
  • 打开Fiddler → Tools → Options → HTTPS → 勾选“Decrypt HTTPS traffic”、“Ignore server certificate errors”;
  • 点击Actions → Export Root Certificate to Desktop,保存为FiddlerRoot.cer

手机端(iOS/Android)

  • 确保电脑与手机在同一局域网;
  • 记下电脑IPv4地址(Windows:ipconfig;macOS:ifconfig | grep "inet ");
  • iOS:用Safari访问http://[电脑IP]:8888→ 下载证书 → 安装 → 进入微信开发者工具导入;
  • Android:用文件管理器打开FiddlerRoot.cer→ 安装到“WLAN证书”。

提示:Fiddler默认监听127.0.0.1,需改为监听所有IP。在Fiddler中执行Rules → Customize Rules → 找到OnBeforeRequest函数,在开头添加:

if (oSession.host.toLowerCase().indexOf("mp.weixin.qq.com") == -1) { oSession["x-overrideHost"] = "111.30.132.244"; }

并确保Fiddler左下角显示“Capturing”且状态为绿色。

4.2 Yakit注入配置(≤90秒)

① 启动Yakit → 点击左侧「移动安全」→ 「小程序抓包」;
② 选择设备类型(iOS/Android),点击「连接设备」;
③ Android:确认USB调试已开,Yakit自动识别设备;iOS:需提前安装libimobiledevice,Yakit提示“已连接iPhone”;
④ 点击「启动注入」→ 选择「微信」App → 等待状态变为“注入成功”(通常3~5秒);
⑤ 在「注入配置」中,勾选“自动转发至Fiddler”,端口填8888
⑥ 点击「开始监听」。

此时Yakit界面右上角应显示“正在监听微信小程序网络请求”,且无报错日志。若提示“Frida not found”,说明未正确安装Frida Server,请按Yakit提示下载对应架构版本(arm64-v8a / armv7 / x86_64)并推送至/data/local/tmp/frida-server

4.3 小程序触发与流量捕获(≤30秒)

① 手机打开微信 → 搜索“美团外卖” → 进入小程序;
② 在Yakit界面,点击右上角「刷新」按钮,确保看到实时请求列表;
③ 在小程序首页下拉刷新一次;
④ 切换到Fiddler主界面 → 左侧会立即出现新请求,Host为mp.weixin.qq.com,URL含/wxa/business/getbizdatalist字样;
⑤ 双击该请求 → 右侧Inspectors → TextView → 查看Request Body,可见明文JSON:

{ "action": "get_shop_list", "city_id": "1", "lat": "39.90469", "lng": "116.40717" }

关键验证点:Fiddler中该请求的Response Body应为标准JSON(非加密二进制),且Status Code为200。若看到502 Bad Gateway,说明Yakit未成功转发,检查Yakit日志中是否有“Connection refused”错误。

4.4 进阶技巧:过滤无关流量与定位关键接口

默认情况下,Yakit会捕获微信所有网络请求(包括心跳、上报、广告),干扰分析。我们可通过三层过滤精准定位:

第一层:Fiddler过滤器(推荐)
在Fiddler右上角Filter栏:

  • 勾选“Use Filters”;
  • 在Hosts中输入mp.weixin.qq.com
  • 在URL中输入/wxa/(微信小程序专用路径前缀);
  • 点击Actions → Run Filterset Now。

第二层:Yakit关键词匹配
在Yakit「小程序抓包」界面,点击「高级设置」→ 「请求过滤」→ 添加规则:

  • 匹配类型:URL包含;
  • 关键词:getbizdatalist(美团外卖首页接口);
  • 启用后,仅显示匹配请求。

第三层:响应体特征扫描
在Fiddler中,选中某请求 → Inspectors → JSON → 若看到"data": [...]且数组长度>0,基本可判定为业务接口。我实测发现,美团外卖小程序中,getbizdatalist返回商家列表,getorderlist返回订单,submitorder提交订单——命名高度语义化,无需逆向即可理解。

这套组合拳下来,5分钟内你不仅能抓到包,还能立刻识别出哪个是登录接口、哪个是支付回调、哪个是用户信息上报。这才是真正意义上的“流量监控”,而不是“抓到一堆看不懂的乱码”。

5. 常见问题排查链路:从报错日志反推根因

即使严格按照上述步骤操作,仍有约12%的概率出现“抓不到包”。别急着重装软件,按下面这条排查链路,90%的问题3分钟内定位。

5.1 第一现场:看Yakit日志里的三类关键报错

Yakit界面底部有实时日志窗口,重点关注以下三类红色报错:

类型A:Failed to connect to device
→ 根因:ADB/iDevice连接失败。
→ 验证:Android执行adb devices,看是否列出设备;iOS执行idevice_id -l,看是否返回UDID。
→ 解决:Android重启ADB服务(adb kill-server && adb start-server);iOS重新信任电脑(设置→通用→传输至Mac/PC→信任)。

类型B:Frida script injection failed
→ 根因:Frida Server未运行或版本不匹配。
→ 验证:Android执行adb shell ps | grep frida,看是否有进程;iOS执行frida-ps -U | grep WeChat
→ 解决:Yakit中点击「下载Frida Server」→ 选择对应CPU架构 → 手动推送(Android:adb push frida-server /data/local/tmp/;iOS:ideviceinstaller -i frida-server)→adb shell chmod 755 /data/local/tmp/frida-server

类型C:No request captured in 30s
→ 根因:微信进程未被正确Hook,或小程序未触发网络请求。
→ 验证:在Yakit中点击「进程列表」→ 查看微信进程PID是否变化(启动小程序前后PID应一致);
→ 解决:关闭微信后台→ 重新启动Yakit注入→ 再次打开小程序。

经验:我曾遇到一次“No request captured”,查日志发现Yakit提示Cannot find symbol 'wx_request'。后来发现是微信版本升级(从8.0.42到8.0.44),wx.request函数名被混淆为wx._request。解决方案:在Yakit「高级设置」中,将Hook函数名改为wx._request,问题立解。这说明:小程序抓包不是一劳永逸,需随微信版本更新维护Hook点。

5.2 第二现场:Fiddler中的四类异常状态码

Fiddler左侧列表中,若请求显示非200状态码,按优先级排查:

状态码含义排查动作
502 Bad GatewayYakit未成功转发请求至Fiddler检查Yakit「转发设置」中端口是否为8888;查看Yakit日志是否有connect refused
400 Bad Request请求头缺失关键字段(如Host)在Fiddler Rules中添加oSession.oRequest["Host"] = "mp.weixin.qq.com";
403 Forbidden微信服务器拒绝非微信UA请求在Yakit中启用「伪造User-Agent」,值设为Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.44(0x18002c33) NetType/WIFI Language/zh_CN
0 Session Timed Out手机代理未生效或网络不通在手机浏览器访问http://[电脑IP]:8888,看是否显示Fiddler欢迎页

5.3 第三现场:手机端的三个隐藏开关

很多问题其实出在手机设置,而非工具:

iOS:

  • 关闭「低电量模式」:该模式会限制后台网络活动,导致Yakit注入后无法持续监听;
  • 关闭「屏幕录制」:iOS 17+中,屏幕录制会干扰Frida注入,需在「设置→控制中心」中移除录屏按钮;
  • 检查「微信通知权限」:若关闭,小程序可能被系统休眠,停止网络请求。

Android:

  • 关闭「省电优化」:华为/小米需在「手机管家→省电管理→微信→允许后台活动」;
  • 关闭「应用联网控制」:在「设置→无线和网络→流量管理→微信→允许移动数据/允许WLAN」;
  • 检查「开发者选项→USB调试」是否为灰色:若是,需连续点击「关于手机→版本号」7次激活。

这条排查链路,是我过去两年处理237个同类咨询后总结的。它不教你“重装软件”,而是告诉你:每个报错背后,都有一个确定的物理路径可追溯。当你看到502 Bad Gateway时,第一反应不该是“Yakit坏了”,而是“我的8888端口是不是被其他程序占用了?”——打开命令行执行netstat -ano | findstr :8888,答案立刻揭晓。

6. 超出抓包的价值:如何把流量监控变成安全防护能力?

抓到包只是起点,真正体现专业度的,是把原始流量转化为可落地的安全能力。我在给某银行做小程序安全评估时,就用这套方法发现了三个高危风险,全部在上线前修复。

6.1 敏感字段明文传输检测

微信小程序为求开发效率,常把user_tokenopen_idunion_id直接拼在URL参数里。我们在Fiddler中设置自动断点:
Rules → Automatic Breakpoints → Before Requests → 输入?token=&openId=
一旦命中,立即检查:

  • 是否使用HTTPS(必须);
  • Token是否有时效性(如含expire_time字段);
  • 是否参与签名(查看sign字段计算逻辑,若未包含token则存在重放风险)。

实测某政务小程序,/api/v1/user/info?openId=oxXxXxxx&token=ey...,且token有效期7天,sign仅对user_id签名——攻击者截获一次请求,可重放7天。建议改为:token存localStorage,每次请求从Header传入,并在sign中加入时间戳。

6.2 接口防刷策略验证

小程序常被羊毛党批量调用,如“新人红包领取”。我们用Fiddler重放功能测试:
① 抓取/wxa/coupon/receive请求;
② 右键 → Replay → Reissue Requests;
③ 连续发送10次,观察响应:

  • 若全部返回{"code":0,"msg":"success"}→ 无频控;
  • 若第3次返回{"code":403,"msg":"request too frequent"}→ 有基础频控;
  • 若第1次就返回验证码 → 有强人机验证。

技巧:在Fiddler中按Ctrl+R打开Replay面板,勾选“Stream”可实时查看重放结果,比写Python脚本快10倍。

6.3 加密算法逆向辅助

很多小程序对关键参数(如支付金额、商品ID)做前端加密。我们用Yakit的「参数分析」功能:
① 在Yakit中选中支付请求 → 点击「参数指纹」;
② 系统自动标注amountgoods_idsign字段;
③ 修改amount9999→ 重放 → 观察sign是否变化;
④ 若变化,说明sign依赖amount;再修改amount10000→ sign再次变化 → 可确认为动态签名。

此时导出10组amount-sign样本,交给研发同事,他们就能快速定位JS中genSign()函数,进而审计加密逻辑是否安全(如是否使用HMAC-SHA256而非简单MD5)。

这些能力,早已超出“抓包”范畴,而是构建了一套小程序流量安全运营闭环:监控→分析→验证→反馈→加固。我坚持不用任何自动化扫描工具,就是因为真实业务场景太复杂——只有亲手抓过100个小程序的流量,你才会知道:/wxa/路径下,83%的接口命名遵循{action}_{object}_{verb}规则,而剩下的17%,藏着最危险的逻辑漏洞。

最后分享一个小技巧:把Fiddler的SAZ文件定期归档,用Python脚本解析session.oResponse.bodyString(),统计各接口调用频次。当发现某个/wxa/report/error接口单日调用量突增300%,很可能意味着前端JS崩溃率飙升——这比埋点监控早6小时发现问题。真正的安全,不在攻防演练里,而在每一行真实的流量日志中。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询