
国博门票预约小程序逆向全纪实协议还原 TDID 设备指纹对抗建议收藏关键词国博小程序逆向、抢票协议还原、TDID 无痕验证、设备指纹对抗、XXTEA 算法还原、VX 小程序协议摘要本文完整拆解某国家级博物馆预约小程序的自动化下单链路从两段式登录协议还原到纯 Python 重写 TDID 设备指纹再到准点自动下单。全程干货无废话建议收藏后食用。一、前言为什么要逆向这套预约系统先摆一个现实热门场馆门票每日限量放票即秒空。人工抢票的瓶颈在哪不是手速是流程——点开小程序、等页面加载、填实名、提交订单。一套流程下来 10 秒起步票早就没了。所以核心目标只有一个跳过所有 UI直接请求协议接口把人从链路里踢出去。逆向成果完整还原预约小程序全部 HTTP 接口登录 / 查票 / 下单纯 Python 重写 TDID 无痕验证 SDK摆脱 node 依赖全链路自动化监控余票 → 下单7×24 无人值守本文针对有基础的技术人群抓包 / 小程序包反编译 / 密码学小白勿扰。二、环境准备工欲善其事先备工具工具用途抓包Reqable / 小黄鸟 / Charles还原接口、分析加密参数、盯准 jprx/1941小程序包反编译wxapkg 解包工具解出 app-service.js 等源码定位加密逻辑与接口路径在线加解密工具见 Step 2XXTEA / AES 算法验证钉死实现正确性Python 3.8算法落地、自动化主程序本地协议服务应用市场协议开源luotron/yyb_go提供真实登录会话见下文主程序开源仓库luotron/chmuseum-client全套源码可直接对照阅读。三、核心原理分析3.1 协议还原两段式登录绕不开的真实会话VX 小程序的登录有个硬门槛code、encryptedData、iv只能由真实的微信会话产生无法凭空构造。硬抠算法生成是死路。这里采用的方案是本地协议服务在本地跑一个应用市场协议服务WMPF 会话扫码录入真实账号它对外提供/wxapp/getCode、/wxapp/getPhoneNumber等接口脚本通过它换取真实登录凭据再走博物馆自己的登录接口完整链路本地协议服务 /wxapp/getCode │ code ▼ 博物馆 getWxminiSessioinInfo → openid / session_key / unionid │ 本地协议服务 /wxapp/getPhoneNumber │ encryptedData / iv ▼ 博物馆 miniAppLogin → apiToken后续所有请求的凭证关键点账号池落在本地 SQLite服务会定时刷新存活状态expired账号自动剔除。这一层单独开源在luotron/yyb_go感兴趣的可以直接读源码。3.2 TDID 设备指纹抓包里是哪个接口、哪个参数很多同学卡在这里知道有设备指纹但不知道抓包里看哪。直接给答案看jprx/1941这个请求。接口POST https://browsertdidticket.m.qq.com/jprx/1941鹅厂系无痕验证 SDK 上报接口指纹在哪请求体req.content——整个deviceObj设备指纹参数被 XXTEA 加密后塞在这个字段里成果在哪响应data.resp.msgBlock——这就是最终要的deviceToken下单时原样填进placeOrder请求体的deviceToken参数抓包里能看到两次jprx/1941对应两阶段第一次 req.type0 首包补全 → 响应 data.resp.token riskToken存起来 → 响应 data.resp.dfp.ticketID ticketID存起来 第二次 req.type1 带 riskToken 换最终凭证 → 响应 data.resp.msgBlock deviceToken ← 目标参数对照表脱敏建议截图收藏位置字段说明请求体req.content加密的 bizObjXXTEA 加密后的设备指纹deviceObj / statisticsInfo请求体req.tokenriskToken首包时用当日 0 点毫秒XXTEA 加密占位请求体req.type0/1阶段标记请求头X-WECHAT-HOSTSIGNhost_sign本地协议服务调 verifyPlugin 生成响应data.resp.msgBlockdeviceTokenplaceOrder的deviceToken参数响应data.resp.tokenriskToken按账号落盘复用响应data.resp.dfp.ticketIDticketID按账号落盘复用算法链明文 → XXTEA 加密 → Base64 密钥 ← MurmurHash2 / LCG 派生几个关键常量反编译 抓包双重验证# XXTEA 标准变体带长度头DELTA0x9E3779B9# deviceObj 关键字段脱敏示例# 101: OPENID 登录后由 openid 回填# 128: 本机局域网 IPwx.getLocalIPAddress 语义# 130: wx.pluginLogin 生成的临时凭证 code取 token 的 Python 落地逻辑defget_device_token(session):# 阶段一本地无 riskToken发 type0 首包补全r1session.post(JPRX_URL,json{req:{type:0,content:content,token:token}})resp1r1.json()[data][resp]risk_tokenresp1[token]# 存起来下次跳过首包ticket_idresp1[dfp][ticketID]# 存起来# 阶段二type1 换最终 msgBlock → deviceTokenr2session.post(JPRX_URL,json{req:{type:1,content:content,token:risk_token}})returnr2.json()[data][resp][msgBlock]# placeOrder 的 deviceToken落地时用纯 Python 实现了 XXTEA / MurmurHash2 / AES-128-ECB彻底去掉了原方案的 node 运行时依赖打包部署少一个坑。riskToken / ticketID 按账号写入cache/login/{openid}.json下次复用避免每次都走首包。3.3 风控头与参数加密除了 deviceToken下单请求还带两道保险# Host-Ip对出口 IP 做 AES-128-ECB Base64放在请求头# 非扫码场景 key AyrKJRXPO3nR5Abc# 扫码场景 key mjnkHYmu0jpURBTQ# X-WECHAT-HOSTSIGN本地协议服务调微信 verifyPlugin 生成# 内容 host_sign / noncestr / timestamp 三件套Host-Ip的明文是 鹅厂校时接口返回的公网出口 IP先用tool.lvtao.net/aes验证一把ECB/PKCS7再进代码一步到位。四、实操步骤Step 1抓包 定位先用抓包工具完整走一遍预约流程重点盯这几个请求登录getWxminiSessioinInfo/miniAppLogin查票gainAllSystemConfig风控jprx/1941TDID 设备指纹下单placeOrder携带 deviceToken对照抓到的参数用 wxapkg 解包工具反编译小程序包搜关键字如接口路径、encrypt、xxtea直接在app-service.js等前端源码里定位加密函数。Step 2加密算法在线验证小程序是纯 JS 逻辑不需要 hook 运行时。拿不准算法时先用两个在线工具把算法钉死XXTEA 验证https://tool.box3.cn/encrypt/xxtea.html支持 UTF-8 / 十六进制输入可勾选带长度头本项目是标准带长度头变体DELTA 0x9E3779B9操作抓包密文先 Base64 解出字节 → 填 key → 解密 → 与抓包明文逐字节比对AES 验证https://tool.lvtao.net/aes模式选 ECB、填充选 PKCS7key 填 16 字节字符串操作把抓包里的Host-Ip请求头密文做加密/解密互转验证验证闭环双向钉死抓包拿一组明文 密文样本如Host-Ip的明文是公网出口 IP在线工具用已知 key 加密输出与抓包密文一致 → 算法确认Python 实现同样输入输出必须与在线工具一致 → 代码确认两轮全对齐才允许接入主流程fromutils.aesimportaes_ecb_b64 plain198.18.0.1# 校时接口返回的公网出口 IPcipheraes_ecb_b64(plain,AyrKJRXPO3nR5Abc)print(cipher)# 复制到 tool.lvtao.net/aes 解密能还原出 plain → 实现正确Step 3Python 落地 联调XXTEA / AES / MurmurHash2 用纯 Python 实现与抓包样本逐字符比对登录态按账号落盘cache/login/{openid}.json避免重复登录主循环查票 → 锁场次 → 取 deviceToken → 下单 → 失败重试Step 4准点下单锁定目标场次后设置准点时间HH:MM:SS到点前先预热前置接口查票、校时、取 Host-Ip到点直接触发placeOrder把网络延迟压到最低。五、总结这套链路的价值一句话概括把看运气变成看脚本。毫秒级接口请求人工流程 10 秒脚本从监控到下单一秒内完成纯 Python 全链路Windows / Linux 都能跑可挂服务器 7×24 值守准点下单模式到点前预热接口卡秒提交最大化命中率能复用到哪同样的思路适用于演唱会/景区抢票、医院挂号、活动报名、限量商品秒杀——只要是协议 风控的结构方法论完全通用。六、安全合规提示本文所有内容仅用于技术研究与学习交流请勿用于商业牟利、破坏平台正常秩序或触碰任何违反法律法规的红线逆向成果的传播和使用责任自负七、项目开源地址本文所述完整实现已开源欢迎 Star / Fork / 交流https://github.com/luotron/chmuseum-client源码含协议封装、TDID 纯 Python 实现与自动化主程序配合luotron/yyb_go本地协议服务即可跑通全链路。