【小程序逆向专栏】某润选房小程序逆向分析
字数 1269 2025-08-19 12:41:58
某润选房小程序逆向分析教学文档
1. 前言
本文详细讲解某润选房小程序的逆向分析过程,重点分析两个关键加密参数ssdp和saleSignature的生成算法。通过本教程,你将学习到微信小程序逆向的基本流程、常见加密算法的识别与逆向方法。
2. 准备工作
2.1 微信开发者工具注入
- 下载微信开发者工具注入程序(WechatOpenDevTools.exe)
- 确保微信版本为3.9.10.19_x64,小程序版本为8555
- 删除微信缓存文件夹:
AppData\Roaming\Tencent\WeChat\XPlugin\PluginsAppData\Roaming\Tencent\WeChat\web\WeChatApp
- 执行注入命令:
WechatOpenDevTools.exe -all
2.2 抓包分析
- 打开开发者工具(DevTools)
- 观察网络请求,发现关键接口
/ssdp - 识别出两个加密参数:
- URL中的
ssed参数 - 请求头中的
saleSignature参数
- URL中的
3. ssdp参数逆向分析
3.1 定位加密位置
- 全局搜索
ssdp,定位到d5c5.js文件 - 在相关位置下断点,观察参数生成过程
3.2 参数生成流程
var u = this,
_ = Date.now(),
S = this,
D = this.getTimeDate(),
f = e + "&Api_Version=1.0&App_ID=".concat(this.globalData.appid, "&App_Sub_ID=").concat(this.globalData.getSsdpApp_Sub_ID, "&App_Token=").concat(this.globalData.App_Token_code, "&App_Version=1.0&Divice_ID=").concat(wx.getStorageSync("user_flag"), "&Divice_Version=wxapp&OS_Version=8.0.6&Partner_ID=").concat(this.globalData.getSsdpPartner_ID);
"post" == n && (f += "&REQUEST_DATA=".concat(JSON.stringify(s), "&Time_Stamp=").concat(D, "&User_Token=&").concat(this.globalData.getSsdpApp_key)),
"post" != n && (f += "&Time_Stamp=".concat(D, "&User_Token=&").concat(this.globalData.getSsdpApp_key));
var A = c(f).toUpperCase(),
b = this.base64_encode(e + "&Api_Version=1.0&App_ID=".concat(this.globalData.appid, "&App_Sub_ID=").concat(this.globalData.getSsdpApp_Sub_ID, "&App_Token=").concat(this.globalData.App_Token_code, "&App_Version=1.0&Divice_ID=").concat(wx.getStorageSync("user_flag"), "&Divice_Version=wxapp&OS_Version=8.0.6&Partner_ID=").concat(this.globalData.getSsdpPartner_ID, "&Time_Stamp=").concat(D, "&User_Token=&Sign=").concat(A))
3.3 复现代码
function md5Encrypt(data) {
const hash = crypto.createHash('md5');
hash.update(data);
return hash.digest('hex');
}
function get_url() {
Divice_ID = "设备号" // 从抓包获取
e = "Api_ID=crland.isale.nsc.searchProjectList";
D = getTimeDate();
f = e + "&Api_Version=1.0&App_ID=".concat("wx948ef9858f04f6e9", "&App_Sub_ID=").concat("0005000502QF", "&App_Token=").concat("2af3061a-fa3d-4ac2-8456-56546a8daaa9", "&App_Version=1.0&Divice_ID=").concat(Divice_ID, "&Divice_Version=wxapp&OS_Version=8.0.6&Partner_ID=").concat("00050000");
var A = md5Encrypt(f).toUpperCase()
b = btoa(e + "&Api_Version=1.0&App_ID=".concat("wx948ef9858f04f6e9", "&App_Sub_ID=").concat("0005000502QF", "&App_Token=").concat("2af3061a-fa3d-4ac2-8456-56546a8daaa9", "&App_Version=1.0&Divice_ID=").concat(Divice_ID, "&Divice_Version=wxapp&OS_Version=8.0.6&Partner_ID=").concat("00050000", "&Time_Stamp=").concat(D, "&User_Token=&Sign=").concat(A))
return b
}
4. saleSignature参数逆向分析
4.1 定位加密位置
- 全局搜索
saleSignature,定位到d5c5.js - 发现生成逻辑:
var k = r.doEncrypt(T, p, 1) T的生成:T = i(I.toUpperCase()),其中i是MD5函数
4.2 doEncrypt函数分析
doEncrypt是一个导出函数,属于webpack打包模块- 定位到
utils/sm-crypto.js模块 - 该模块实现了类似RSA的非对称加密算法
4.3 扣取算法
- 将整个加密模块复制到单独文件
- 修改为自执行函数
- 将分发器导出到全局
// 导出加密模块到全局
window.kk = function(t) {
return e[t]
};
4.4 算法复现
// 公钥
p = "04a337dc634bddbbfbcae9d30470663fb5e221feab40239f1675a0b2d9d42e46413a0adfa4868c963aebb39d7ec89073885eccd011e0f96d5fe434be98734d9993"
// 使用公钥生成临时密钥对
window.kk(3).doPublicKey(p)
// 加密
console.log(window.kk(3).doEncrypt("f5ef7eb5653944f8eef04891b195171b", p, 1))
4.5 调试技巧
- 与浏览器联调,比较中间变量
- 重点关注
o和i两个32位数组的生成 - 发现需要在加密前先调用
doPublicKey初始化密钥对
5. 完整逆向流程总结
- 环境准备:注入开发者工具,配置正确微信版本
- 抓包分析:识别关键接口和加密参数
- 定位加密:全局搜索关键参数,下断点调试
- 算法分析:
ssdp:参数拼接+MD5+Base64saleSignature:参数拼接+MD5+非对称加密
- 算法复现:
- 扣取关键JS代码
- 补全依赖环境
- 联调验证结果
- 结果验证:与浏览器生成结果比对,确保一致
6. 注意事项
- 本文仅供学习交流,严禁用于商业用途和非法用途
- 实际逆向时参数可能有所不同,需要根据具体情况调整
- 小程序更新可能导致逆向方法失效,需要持续跟进
- 逆向过程中可能遇到反调试,需要相应应对策略
通过本教程,你应该已经掌握了微信小程序逆向的基本方法和思路,特别是对常见加密算法的识别和逆向技巧。在实际应用中,需要根据具体场景灵活运用这些技术。