尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
微信小程序逆向实战:从抓包到定位接口签名算法的完整流程
微信小程序逆向这活儿圈里评价两极分化有人说客户端代码随手一扒就能看没难度也有人说既然能扒包接口签名早晚能绕所以数据都能抄。我的看法比较折中小程序逆向真正的价值在于理解一个前端产品怎么设计自己的安全边界以及哪些环节看似加密却存在明显漏洞。前阵子我接手了一个模拟项目X某内容社区小程序的接口签名参数研究从抓包、解密、反编译到定位签名生成逻辑走完了一整条链路过程里踩了很多次坑也总结出一套相对固定的打法。这篇文章就把完整流程和避坑思路整理出来适合安全测试人员、客户端开发、对小程序内部实现好奇的读者参考。先说清楚所有研究仅限已获授权的安全工作、漏洞测试或学习交流不讨论任何绕过权限、抓取用户隐私或薅羊毛的用途。工具链可以复现但请务必把合规放在第一位。1. 项目背景与研究思路拆解1.1 为什么盯上小程序接口签名移动端产品这几年大量往小程序迁移微信小程序包通过特殊格式下发到客户端很多团队以为App原生环境才需要做接口安全防护小程序里的请求常常只靠HTTPS加密。但实际上只要HTTPS被中间人代理截获请求参数就完全暴露了这时候如果接口只有ts、sign这类简单签名参数攻击者完全可以拿到全部请求结构伪造数据只是时间问题。签名的意义在于让服务端能校验请求是否来自真实客户端、参数是否被篡改。常见的签名方案是把所有请求参数按字典序拼接再混入密钥或时间戳做一次哈希或HMAC。研究这个签名的生成链路能帮你判断一个服务到底是在真正做防护还是只做了个心理安慰——很多小程序的签名算法并没有正确使用比如把密钥写死在JS里、签名参数没参与校验、或者签名可以重放。我之前接到的这个模拟项目X是一个带内容列表、文章详情、评论互动的小程序。它的大部分接口都带有sign参数这正是研究的好样本接口字段不算多签名逻辑藏在压缩后的JS里刚好可以用来梳理一套完整的逆向分析方法。这个研究不仅适用于目标对象也能迁移到任何微信小程序或者类似Hybrid应用上。1.2 整体研究路线规划整个链路拆成四步抓包拿样本、解包还原代码、从代码里定位签名函数、用动态验证确认逻辑。四步缺一不可顺序也不能乱。先说为什么先抓包再解包。很多人一上来就解包看代码但如果你不知道真实接口长什么样看代码时很难把变量名和实际请求对应起来。抓包先给你一组真实样本包含URL、请求头、query参数、body这样后面看JS时一搜sign、ts、nonce这些关键词就能立刻对号入座。再说解密。微信小程序的安装包是经过编码的从微信缓存目录拿到的wxapkg文件不能直接解压要先做二进制处理。解包本身通常只需要一个脚本输入输出都是文件级别难度不高难的是你要理解包内几个关键文件的职责这样才能第一时间锁定要看的文件而不是在一个几百KB的JS文件里大海捞针。动态验证是最后一步也是很多人偷懒跳过的一步。如果你只是在代码里找到了一段看起来像签名算法的函数然后觉得自己“研究完了”那结果大概率是错的。因为小程序JS里可能同时存在多个加密函数有的实际没被调用有的是旧版本的残留只有动手把代码跑起来对比输出结果和抓包抓到的真实签名是否一致才能确认定位准确。1.3 合规前提与适用范围开头已经提过这里展开强调这类逆向分析只适合用于授权范围内的安全测试、漏洞挖掘、学术研究、以及开发排查问题。如果你要分析一个小程序请先确认是否有书面授权或者这个程序本身就是你自己的。未经授权去逆向别人的线上产品可能涉及违反平台规则甚至法律风险。这个原则同样影响技术选型比如抓包时我建议只关注接口结构和参数本身不涉及批量导出用户数据、不伪造请求去做大规模遍历。研究签名算法是为了看懂防护逻辑而不是为了绕过它。文章里提到的所有验证手段止步于“证明接口签名可被分析”这个层面不会再往下延伸。2. 环境准备与工具选型2.1 抓包工具选型与配置抓包工具我用过不少Charles和Fiddler是最常见的两个。Fiddler上手门槛低配置简单但处理移动端HTTPS流量时有些微调界面没有Charles直观。Charles的SSL Proxying设置更清晰能按域名过滤响应体渲染也方便我一般优先选它。如果你习惯命令行也可以用mitmproxy它对脚本自动化更友好但日常交互调试不如Charles顺手。配置步骤其实很固定手机和电脑连同一个局域网手机代理指向电脑IP和端口电脑端开启SSL Proxying并安装根证书。需要注意微信客户端对证书校验比其他App严格Android 7以上如果App没配置信任用户证书默认是不认用户装的CA证书的。实际测试下来微信大多数场景会信任系统证书但低版本Android设备上经常出现“已连接但无法解密”的情况。我的建议是准备一台Android 6或更早版本的测试机或者用Root过的设备把用户证书移动到系统证书目录。iOS上流程相对顺一些但也要在设置里开启证书完全信任否则一样抓不到包。这一步是所有环节里最折腾的很多人卡了一两天都在配置上别急耐心一点。2.2 小程序包获取与解密思路抓包拿到接口样本后下一步是从微信本地缓存里拿小程序包。微信运行过的小程序包文件会缓存在设备的私有目录里。Android上通常位于/data/data/com.tencent.mm/MicroMsg/32位hash/appbrand/pkg/目录下iOS由于沙盒机制需要越狱或通过备份等方式获取难度更高。文章里我主要说Android路径也建议大家优先用Android做小程序逆向。这些缓存文件是.wxapkg后缀的文件。早期版本的wxapkg文件结构比较简单文件头有固定标识直接用解包工具解析就能得到源码。后来微信逐渐修改了文件的加密方式部分情况下文件会先经过一次异或处理再套用wxapkg容器格式。处理的关键是先判断文件头是否符合预期如果文件头格式不对就需要先解密再解包。解密这一步网上有很多脚本原理其实不复杂小程序的加密本质是保护静态资源不是强密码学很多版本用的是固定密钥或可逆异或。你可以用一个十六进制编辑器先打开wxapkg文件看文件头几个字节如果完全不像V1MMA0这类特征标识就要考虑先跑解密脚本。实际处理时我一般直接扔给支持自动解密的解包工具工具会检测并处理省去手动算密钥的麻烦。2.3 反编译与代码还原工具解包阶段我用过的工具里unveilr用得最多。它是命令行工具Node.js环境运行用法大概是unveilr -i input.wxapkg -o outputDir会自动解密并解包输出一个小程序源码目录。另一款经典工具wxappUnpacker的解析逻辑更早但更新频率低遇到新版本微信包格式时可能出现解析错误。两个工具可以互为代替一个不行就换另一个。解包之后生成的目录里核心文件通常有两个一个叫app-service.js包含小程序的逻辑层代码也就是Page、Component、工具函数等所有业务逻辑另一个叫app-config.json记录了页面路由和全局配置。签名算法基本都藏在app-service.js里少数可能独立成模块文件比如utils/crypto.js这要看具体项目结构。拿到app-service.js之后代码是压缩过的不具备可读性。我推荐用Prettier或者VS Code自带格式化来处理。用命令npx prettier --write app-service.js就能一键美化几万行的压缩代码变成带换行缩进的源码这时候搜索关键词才看得懂。有一点要注意格式化之后文件可能达到10MB以上直接打开偶尔会卡建议用VS Code的Large File支持或Sublime Text体验更顺滑。3. 实操过程从抓包到定位签名算法3.1 抓包获取接口请求样本我以模拟项目X的内容列表接口来演示。操作路径是这样的电脑端Charles开启SSL Proxying手机连代理后在微信里进入目标小程序点开内容列表并下拉刷新几次Charles里就会刷出一堆请求。此时在小程序里多切换几个页面确保把列表、详情、评论这些核心接口都抓到。列表接口长这样示例GET https://api.example.com/v1/article/list?catnewspage1size10ts1710000000nonce8f4a2b9csign3f9a4b7c2d8e5f1a6b3c4d5e6f7a8b9c0d1e2f3a把这几个字段记下来这是后面的对照基准。其中cat是业务参数page和size是分页参数ts是毫秒级时间戳nonce是随机字符串sign是签名结果。字段名是模拟出来的真实项目可能叫timestamp、random、sig但套路基本一致。我把抓包数据整理成一张表方便对照分析时使用参数名示例值说明catnews分类参数业务字段page1页码size10每页数量ts1710000000时间戳防重放nonce8f4a2b9c随机字符串sign3f9a4b7c...签名结果拿到这些样本后不要着急关抓包工具再把文章详情接口打开对比两个接口的签名参数差异。如果详情接口的参数顺序和列表接口不一样很可能签名拼接逻辑跟字段字典序有关这个细节会在后面定位代码时给到重要线索。3.2 解密解包还原源码抓包样本拿到之后开始本地文件分析。先把手机Root用adb把微信缓存目录下的wxapkg文件拉到电脑上。示例命令adb root adb pull /data/data/com.tencent.mm/MicroMsg/hash/appbrand/pkg/xxxx.wxapkg ./target/如果设备没有Root可以用Android备份机制或者微信自带的小程序调试功能但都不是通用方案最快的路子还是找一台Root过的Android测试机。市面上很多二手老设备都能满足要求没必要用主力机折腾。拿到wxapkg后先用unveilr解析npx unveilr -i xxxx.wxapkg -o ./unpacked如果工具提示文件头异常或解密失败说明包可能采用了新的加密方式。这时候建议换个工具或者检查是否为最新版本微信。实测下来同一份包用两个工具轮流解大概率能出一个正常目录。解包完成后进入输出目录看一下结构unpacked/ ├── app-service.js ├── app-config.json ├── pages/ └── components/app-config.json可以告诉你小程序有几个页面、每个页面对应哪个JS文件它相当于一份地图。app-service.js才是代码主体接下来要美化它并开始搜索。3.3 定位签名参数生成的完整链路美化代码之后先在VS Code里搜索sign。这一步会有大量结果不用慌优先过滤掉带.css、.wxss后缀的样式代码只看JS逻辑。常见做法是搜索sign或sign 、sign:这类赋值表达式。我的定位思路是倒着找先把之前的列表接口请求URL找出来在JS里搜索接口路径的关键词比如/article/list找到发起请求的地方然后看它构造参数时sign是怎么算出来的。举一个简化后的伪代码示例function getSign(params) { const keys Object.keys(params).sort(); const query keys.map(k ${k}${params[k]}).join(); const raw ${query}keyYOUR_SECRET_KEY; return CryptoJS.SHA1(raw).toString(); }这里params就是请求里的业务参数加ts和nonce先对key做排序再拼接value最后拼上一个密钥字符串做一次SHA1。这种写法在小程序里非常常见因为它逻辑简单、服务端也好复现。定位getSign函数之后还要追一下它的调用位置确认它确实被当前接口用了。有的小程序会写两套签名函数一套新的、一套旧的线上可能只在某种条件下调用新逻辑。此时按调用栈往上翻一层看哪里getSign()被调用、返回值怎么塞进了sign字段。追完整条链路后把以下信息记到笔记里含参与签名的字段名、字段排序规则、字段之间的拼接分隔符、最终哈希算法SHA1/MD5/HMAC-SHA256等、密钥是否硬编码在代码里。这些信息就是整个签名算法的完整描述有了它就能在本地复现签名。3.4 用动态验证确认签名逻辑只靠静态代码推演不够签名算法确认要靠动态验证。最简单的验证办法把找到的签名函数单独提取出来在Node.js里模拟执行。你需要把代码里依赖的CryptoJS等库一起引入然后手动构造一组和抓包数据相同的参数传给签名函数对比结果和真实抓包里的sign是否一致。我用一个简化示例const CryptoJS require(crypto-js); function getSign(params, secret) { const keys Object.keys(params).sort(); const raw keys.map(k ${k}${params[k]}).join() key${secret}; return CryptoJS.SHA1(raw).toString(); } const params { cat: news, page: 1, size: 10, ts: 1710000000, nonce: 8f4a2b9c }; console.log(getSign(params, YOUR_SECRET_KEY));如果输出的值和抓包里的sign一致说明你找对了函数和密钥如果不一致逐项排查参数值类型。比较常见的坑是page和size在代码里是数字类型toString之后是1而原始请求里的值也是1这通常没区别但如果有布尔值、嵌套对象拼接方式就可能有坑。另一种验证方式是用Hook工具动态运行小程序代码。比如在Root设备上用Frida注入到微信进程Hook住签名函数直接打印入参和返回值。这种方式能拿到真实环境里的参数不需要猜测参数类型准确率最高。缺点是Frida配置有门槛还要处理微信进程多开、小程序子进程等问题。我通常先用Node.js模拟验证卡住的时候再上Frida看真实调用。4. 典型问题与排查技巧实录4.1 抓包环节的证书校验问题微信对HTTPS证书的校验比普通浏览器严格经常有人卡在“能看到流量但解密不了”这一步。表现是Charles里显示一堆乱码或者纯加密协议无法查看明文请求。这一般是SSL Proxying没生效证书没被系统信任。我的经验是优先用Android 6及以下的Root设备把用户证书手动复制到系统证书目录。具体路径是/system/etc/security/cacerts/复制后用chmod 644设置权限。如果设备系统版本太新系统分区只读需要先挂载为可写。操作序列大概是这样adb root adb remount adb push cert.0 /system/etc/security/cacerts/ adb shell chmod 644 /system/etc/security/cacerts/cert.0 adb rebootiOS设备就简单多了只要安装描述文件后在“设置-通用-关于本机-证书信任设置”里开启完全信任基本都能解密。要留意的是微信本身可能对某些接口做了额外的证书固定这种就不是代理证书能解决的了通常需要配合Hook或者改包才行。4.2 反编译后代码混淆严重怎么办现在不少小程序上线前会做代码混淆解包出来的JS里变量名全是a、b、c函数名被重写成_0x1234这种形式。遇到这种情况别试图在命名层面理解代码要把重心放在API调用模式上。搜索关键词仍然有效因为字符串常量不会被混淆比如接口路径、sign、ts、CryptoJS这类方法名大概率还在。你先搜CryptoJS看哪里调用了SHA1或MD5或者搜接口路径定位到请求构造处再在断点附近展开代码。混淆后的逻辑只是变量名变了代码结构没有变靠API调用链照样能摸清签名流程。还有一个技巧不要用浏览器直接打开10MB的JS文件那会卡到怀疑人生。把文件拆成小块用grep或编辑器正则搜索。VS Code里同时打开多个大文件会吃内存建议关掉其他窗口只保留一个目标文件。4.3 签名参数定位的常见误判静态分析时最容易犯的错是把某个无关字符串当成签名。我看到过不少搜到sign关键词结果那只是接口返回数据里某个字段的展示逻辑跟请求签名毫无关系。区分方法很简单签名是在请求发起之前、在构造请求参数那一步生成的任何在请求响应处理阶段出现的sign赋值都不是我们要的东西。另一个容易误判的点是多个签名并存。有的小程序分sign和sign2或者业务参数签名和数据签名是两套算法。这时要先理清楚当前接口用的是哪个签名别把两套逻辑混在一起分析时只追当前接口的完整链路。第三类误判是把时间戳当随机数。有些项目的ts参数其实是非ce但很多代码直接从Date.now()获取验证时如果不考虑先后时序复现签名会算不对。这时候重点看签名拼接里是否含ts如果含模拟时务必要用和抓包时完全相同的ts值而不是重新取当前时间。这部分的排查策略我做成了速查表格现象可能原因排查方向搜索sign结果太多混淆代码里大量字符串用接口路径关键词二次过滤sign值对不上参数拼接顺序错误重点检查排序逻辑sign值对不上ts或nonce使用了新值复现时必须使用抓包时的原始值发现多个签名函数新旧版本共存确认当前接口实际调用链函数是React/WebView逻辑签名在另一个JS文件里查看app-config或独立模块4.4 快速定位的几个实战技巧搜不到关键词时先把目标代码缩小。你从抓包里已经知道接口路径直接把路径字符串在主代码里全文搜索。搜到后往上游多翻几层函数直到遇见一个包含请求参数构造和签名赋值的函数然后以这个函数为中心把调用它的所有路径都走一遍。如果代码经过webpack打包模块结构通常是一个巨大的define或者webpackJsonp数组源码里所有函数都被包在闭包里。这时候没法靠传统打断点方式定位建议用编辑器里的大纲功能看函数列表或者干脆把app-service.js转成Source Map之后在Chrome里调试。Source Map不一定存在但很多包构建时顺手保留了大半映射有机会白捡一个清晰源码。还有一个小经验本地存储和Storage里也可能存着签名逻辑。小程序代码里有时会把部分加密逻辑放在wx.setStorageSync里而密钥或盐值也存在本地存储里。分析时顺手搜一下setStorageSync的调用位置看看有没有额外暴露密钥信息这不算偏门实际项目里真的见过。4.5 关于接口重放与时间戳校验的补充观察研究签名算法时还要顺带看服务端对于ts的校验方式。有些服务端只比较ts与当前时间的差值允许正负几分钟的容差这属于正常设计有些服务端根本不校验ts那签名再复杂也是形同虚设。分析代码时你会看到请求参数里传了ts但服务端具体怎么校验需要用真实环境试探这一部分我点到为止不展开细说也请读者在自己的测试环境里谨慎操作。做这类研究我的最终建议是写一份签名分析报告把接口路径、参数表、签名算法描述、密钥位置、验证过程完整记录。报告本身就是安全价值的体现如果发现问题可以用它去推动研发补强服务端校验如果没发现问题它也能证明当前防护是可靠的。我做完模拟项目X之后整理了大概三页分析记录后续再看其他小程序基本都是同一套流程效率明显提升。至于工具脚本和细节参数每个项目都略有差异最重要的还是先把“抓包、解包、定位、验证”这条主线吃透。理解思路之后工具用什么都顺手。
RELATED

相关推荐

Loop Engineering:代码生成与验证闭环的工程化实践

Loop Engineering:代码生成与验证闭环的工程化实践

1. 从标题拆解 Loop Engineering 的真实含义第一次看到 "Loop Engineering: Optimizing Code Generation and Verification" 这个标题,我脑子里蹦出来的不是学术论文,而是一个很具体的画面:一个开发者盯着屏幕,代码生成…

📅 2026/10/20 15:23:14
RBF神经网络时间序列预测:原理、代码实现与避坑指南

RBF神经网络时间序列预测:原理、代码实现与避坑指南

做过时间序列预测的人多少会有这样一种体会:很多问题听着不复杂,数据也摆在眼前,可真要预测准,却经常在模型选择上栽跟头。我之前处理设备振动数据预测任务时,试过线性回归、也试过深层网络,前者欠拟合&…

📅 2026/10/20 15:23:14
AI代理营销技能库:从零搭建可复用可组合的营销能力体系

AI代理营销技能库:从零搭建可复用可组合的营销能力体系

1. 从零拆解一个 AI 代理营销技能库到底在解决什么问题第一次看到“AI 代理营销技能库”这个说法,很多人脑子里冒出来的画面可能是:给聊天机器人塞一堆营销话术模板,然后让它自动发广告。如果你也这么想,那基本就把这个项目理解偏…

📅 2026/10/20 15:23:14
MORE NEWS

更多资讯

📰

全栈液冷方案如何破解AIDC高密度散热与PUE难题

这个标题我盯了很久。去年我参与的一个数据中心改造项目,正好卡在从传统风冷向液冷切换的节骨眼上。当时客户一句话让我印象特别深:"我不管里面用什么技术,反正单柜功耗到120kW的时候,你不能再让我靠加大空调风量来解决问题。…

📰

AI协同工作流:从复制粘贴到技能调用的效率革命

CtrlC和CtrlV这对组合键,几乎是每个办公人的肌肉记忆。从Excel表格填进Word报告,从聊天记录整理成任务清单,从客户管理系统把线索同步到跟进表——很长一段时间里,所谓"会用电脑办公",本质上就是熟练地在不同…

📰

AI Agent全自动社交媒体运营:架构设计、实现细节与踩坑实录

AI Agent在社交媒体运营中的全自动流程,这个话题我过去半年一直在折腾。从最早的"用AI写个标题",到后来的"批量生成内容定时发布",再到现在这套覆盖选题、创作、审核、发布、互动、复盘的全自动链路,中间踩过…

📰

深度信念网络详解:从受限玻尔兹曼机到无监督预训练与微调

深度信念网络(DBN)这个名词,现在很多深度学习入门教程里已经不太常提了,但它仍然是理解整个深度学习演进路线上绕不过去的一站。经典教材往往会把这部分放在第12章这样的后半段位置,原因是前面得先把概率图模型、玻尔兹…

📰

逆向实战:破解发帖接口mouse_pwd参数与鼠标轨迹模拟生成

“某吧发帖接口的mouse_pwd到底怎么来的?”这是我第一次在抓包里看到这个参数时的第一反应。做过前端逆向的人应该都能理解那种状态:接口里明明没有输入框和这个字段相关的东西,但一旦少了它,请求就会被风控直接拦下来&#xff0c…

📰

全像素密集三维追踪:世界坐标系下的前馈式轨迹预测全解析

2. 从二维对应到三维轨迹:这个问题到底难在哪2.1 先分清三个概念做视觉感知的朋友,应该都有一种感觉:每隔一段时间,就会冒出一个新名词,把老问题重新包装一遍。光流、场景流、密集三维追踪,这三个概念经常被…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬