微信小程序逆向

摘抄自吾爱破解大佬文章:库迪小程序sign值加密算法分析 - 吾爱破解 - 52pojie.cn

一、环境准备

1、抓包环境:

这里采用ProxyPin进行抓包,下载地址:proxypin 发行版 - Gitee.com

2、小程序解包工具:

使用unveilr进行解包,解包操作见摘抄文章。

3、微信开发者工具

使用微信开发者工具进行反编译,以便查看源码。

二、抓包分析

1、首先抓包,找到一个post包,以/cotti-capi/shop/homePageGetShopDetail为例,编辑请求后,发现可以在响应体中看到app页面信息。

pA4SkqI.png

pA4SFsA.png

2、尝试修改时间戳(修改较大,将173改成172开头),发现提示如下,因此猜测后台对时间进行了校验,当请求包的时间与实际时间相差较大时会提示时间错误。

pA4SiMd.png

3、之后尝试修改sign值(将sign首位改成1),发现提示md5错误。

pA4SCxH.png

因为sign是32位,结合提示md5错误的信息,所以猜测程序的加密逻辑与时间戳有关,猜测sign是某个包含时间戳的字符串的md5值。

我们的目的是推导出md5值为41105C1F534237297E73C585080223AD的字符串。

4、微信开发者工具打开,搜索字符串sign:定位到关键代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
baseUrl: "https://gateway.cotticoffee.com",
sign: {
ak: "QbGDuwcCztkquMfyw4Q3hyiiDDa0NYTz",
sk: "k9k16jSJaXj46QLElEVT8uRme2uHrtee",
version: "1.0.0"
},


function h(t) {
var e = i.default.getConfig().sign,
n = e.ak,
r = e.sk,
a = (new Date).getTime(),
u = e.version,
c = {
timestamp: a,
path: t,
version: u
},
s = [];
return Object.keys(c).sort().forEach((function (t) {
var e = c[t];
e && s.push("".concat(t).concat(e))
})), s.push(r), {
timestamp: a,
appKey: n,
sign: o.default.hex_md5_32Upper(s.join("")),
version: u,
"api-version": i.default.getConfig().apiVer || "v1"
}
}

分析可知,sign是将timestamp,path,version的键值对以及sk键值对拼接后进行md5最后转大写得到。

三、算法还原

使用js还原加密逻辑:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//这里先使用源时间戳进行md5测试
var time = "1732614817002"
//var time = (new Date).getTime()
var version_ = "1.0.0"
var sk_ = "k9k16jSJaXj46QLElEVT8uRme2uHrtee"
var path_ = "/cotti-capi/shop/homePageGetShopDetail"

c = {
timestamp: time,
path: path_,
version: version_
}

var s = []
Object.keys(c).sort().forEach((function (t) {
var e = c[t];
e && s.push("".concat(t).concat(e))
}))

s.push(sk_)
var sign = s.join("")
console.log(sign)

'path/cotticapi/shop/homePageGetShopDetailtimestamp1732614817002version1.0.0k9k16jSJaXj46QLElEVT8uRme2uHrtee'

测试一下,发现md5结果与前边目标md5一致!

pA4S9Re.png

四、构造数据

因此,可以使用脚本生成当前时间以及相应sign值发送,发现正常获得响应页面。

pA4SEZt.png

图中标红的时间戳和sign值是用代码(new Date).getTime()生成的最新时间戳以及对应求出的sign值,直接修改在原先包上,也可以正常回显页面。