0、工具下载链接
3、everything和fildder 搜索引擎搜一下都有
1、前序
最近临近暑期,想去海边玩.
想自驾游,无车呀,咋办,只能上某租车平台租车,打开一看价格不菲啊
当我准备租的时候,改了时间,发现价格居然变少了,灵机一变的我突发奇想,会不会改了一个取车网点会不会也很便宜了呢?
果不其然,价格变低了不少,也就是说【时间+地点】可能会决定价格的变动,那怎么样做最优解呢?
最暴力的方式就是循环时间并且循环地点获取最低价格,那么怎么样调用这个查询接口呢?
思路:通过抓包的方式抓取到接口,然后动态的修改参数去获取查询结果的列表即可
2、前置准备
- 抓包工具:fildder,以及配置好https证书,能抓到电脑小程序的请求,手机的也行配置好证书就行
- 微信小程序解密工具:UnpackMiniApp,用于解密微信小程序
- 微信小程序逆向工具:wxapkgconvertor,用于逆向微信小程序获取混淆的JavaScript代码
- 文件搜索工具:everything,用于快速搜索电脑系统文件
3、开始抓包接口
首先先打开某租车小程序,已经打开过的建议先删除小程序避免找不到.wxapkg文件
进入小程序之后随便点击一下,保证.wxapkg的存储
找到选车页面,选择时间和网点之后点击立即选车,点击的同时打开fildder进行抓包
通过抓包软件fildder可以看到响应数据找到对应的请求接口
4、模拟请求研究参数
4.1 Postman 请求
上一节中通过fildder抓到对应的包之后,复制请求的url到postman进行二次请求测试
4.2 入参研究
通过postman请求是ge请求,并且有四个参数,并且无需header的任何参数,那看起来应该是不难了
- cid:猜测是城市id
- q:不知道是什么,通过百分号看出来应该是encodeURIComponent过的参数
- sign:一看就是加密的签名密钥,这个估计是重点
- uid:未知的参数
做过爬虫的都知道有些参数不一定需要的,通过一个一个参数取消来判断哪些参数是不必要的,减少不必要的逆向工作
4.2.1 cid去除
发现不太行,cid为必要参数
4.2.2 q、sign、uid的分别去除
分别都报错了,说明四个参数都是必要的好了,现在该研究参数是怎么来的了
4.3 参数研究
4.3.1 q参数
之前发现q参数是一个类似encodeURIComponent过的参数,这里做一下校验,请求到在线UrlEncode的网站解析发现是一个合法是数值
{
"pickupCityId": "14",
"pickupTime": "2024-08-09 12:30",
"returnCityId": "14",
"returnTime": "2024-08-11 12:30",
"entrance": 1,
"holidaysWaitingFlag": 0,
"pickupDoorFlag": false,
"returnDoorFlag": false,
"exclusivenearby": true,
"pickupDeptId": "127248",
"returnDeptId": "127248",
"bucketIdList": [319, 991, 1138, 1187, 32, 2621, 137, 256, 270, 508, 522, 585, 1537, 2901, 2565, 2461, 2363, 2293, 3020, 1866, 2999, 1712, 1635, 1558, 1488, 1369, 928, 886, 389, 2663, 2698, 2852, 2915, 2992, 3048, 3069, 3195, 396, 1068, 1607, 1642, 1670, 1698, 1810, 1831, 2496, 2684, 2733, 2873, 2943, 3104, 3188, 2090, 298, 732, 1320]
}
见名知起义,可以大胆的先猜测它的含义,用于后续研究
- pickupCityId:应该是取车城市
- returnCityId:还车城市
- pickupDeptId:取车网点
- returnDeptId:还车网点
大胆假设一下,如果我修改了还车时间再编码一下发过去请求,会不会成功呢(校验sign的参数跟哪些参数有关,一般sign都是混合多个参数进行加密的)
修改还车时间为2024-08-30 12:30,然后再次发送请求看看结果
果然失败了,意料之中,剩下几个参数不用研究,直接去源码中查看
5、逆向解析
5.1、获取微信小程序加密包
首先先下载一个everything(快速搜索文件的软件)输入.wxapkg后缀名,然后点击修改时间倒叙排序(要提前删除小程序,重新进入登录,才能准确找到小程序加密包)
进入文件夹,打开UnpackMiniApp.exe文件,选择需要破解的微信小程序包
5.2、解析获取混淆源码
破解之后会有一个新的wxapkg文件,然后使用wxapkgconvertor转换为混淆过后的源码
在当面文件夹会生成一个解析后的源码
6、逆向解析
6.1、代码格式化
获取到的源码是混淆且去掉空格的,打开app-services.js进行反混淆,优先使用网上的混淆还原工具去格式化,因为编辑器的格式化不一定正确
6.2、寻找sign的加密方式
寻找参数的加密方式一般很简单一般搜索 "sign:"、"sign="、"sign"等关键字就行,毕竟是作为请求参数过来的
搜索了一下 "sign:"就出现两个结果,并且出现了cid、q、uid,看起来很像了,把方法拆出来看
function(e) {
var t = o.R.getState().baseInfo.bucketIdList,
n = e.data || {},
i = JSON.stringify((0, r.Z)((0, r.Z)({},
n), {},
{
bucketIdList: null != t ? t: void 0
})),
u = (0, c.uP)(),
l = {
cid: a.x,
q: i,
sign: (0, c.Ur)("cid=".concat(a.x, ";q=").concat(i).concat(u ? ";uid=".concat(u) : "").concat(a.$h))
};
return u && (l.uid = u),
l
}
貌似看不太懂,看不懂我们有gpt啊,问gpt,要善于借助chatgpt,比如 (0, c.Ur)这种是什么意思等
gpt的回答是调用了c.Ur方法,并且把参数concat起来作为参数调用它,得到sign,现在分开来看
- cid:取到的是a.x ,我们暂时用抓包到的cid,根据观察同一个城市是不变的
- q:取的是i,就是我们抓包到的一个参数反解析得到的对象,我们根据它进行修改时间、城市就可以了
- u:看起来是可以不传的, u ? ";uid=".concat(u) : "" 这句代码可以看出,暂时取抓包抓到的
- a.$h:这个不知道是什么,继续往下看
点击应用a.$h,查看引入的地方
返回的是a,再点击a,发现是一个常量对象,那就破解了$h
6.3、 加密函数推导
上一节已经把c.Ur的入参都搞定了就是用一个字符串concat起来就好了,现在就要做到c.Ur是什么函数了,同理点击找到定义
追踪下去是定义了一个方法
主要函数有Z、R函数,不确定是什么,继续点击Z、并且R函数传入了三个参数,e就是我们的拼接字符串,void 0和!0 ,不知道是什么意思,但是记住是三个参数
Z方法没有引入其他的方法了,直接复制下来,在看R方法
网上看发现n是这个函数的参数,n.n(m)也不知道是什么意思,看不懂,不过肯定是一个函数,那就直接先看m函数,传入了一个数字,搜索一下这个数字
发现它就是定义了一个函数,但是又臭又长,不知道是什么意思,老样子 问gpt吧
gpt真是厉害,没看到任何关于md5的字母,却分析出来了,并且告诉我c就是入口函数,而且刚好是三个参数,刚好跟之前调用R方法的的三个参数对应上,那我就大胆猜测就是直接调用了这个方法
到此所有的方法以及解析完成了,然后全部复制下来测试一遍看看
7、 本地js文件测试加密参数
7.1 本地方法
将拷贝的方法全部复制下来之后,组装一下,原来闭包的方式要改一下
完整代码
7.2 测试校验
结果是这个数字,是不是很眼熟,打开之前postman请求的参数看看,发现是一模一样
8、总结
本文的目的是为了学习抓包知识、js混淆知识等、以及代码分析,掌握安全开发意识无论是混淆和反混淆技能都是很有必要的,在调研一些市面上的功能的时候可以用到,只有会了反破解,你才懂的如何去防止别人反破解