网址:https://www.qimai.cn/rank

解析流程

不难看出哪个参数需要解密,关键字搜索不到,直接打上xhr断点尝试

image-20230517214052870

再reques堆栈中发现axios拦截器,同时这个堆栈也是参数加密前的最后一个堆栈

image-20230517214553799

t当中有六个拦截器,两个为一组,猜测第一个拦截器是再请求之前做了处理,点进去查看一下

image-20230517215259785

这个拦截器中会进来很多个请求,找到我们需要的那个接口

image-20230517215214028

这一段代码重点是a和e,a是将请求体中的参数进行组合拼接,如:36cnfreeiphone,然后再进行base64加密,然后再加上请求体中的数据, e参数是先进行处理转字节组合,然后再进行base64加密,d参数固定

1
2
3
e = (0,i[jt])((0,i[qt])(a, d))
// 改写一下e
e = cv(oZ(a, "xyz517cda96abcd"));

直接扣代码处理

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
var window = global; // node的全局 ->  浏览器里面的window;

function o(n) {
// t = "",
// ['66', '72', '6f', '6d', '43', '68', '61', '72', '43', '6f', '64', '65']['forEach'](function(n) {
// t += window['unescape']("%u00" + n)
// });
// // 上面这一坨运行完. t里面是fromCharCode
// var t, e = t;
return String['fromCharCode'](n)
}


function cv(t) {
t = window['encodeURIComponent'](t)["replace"](/%([0-9A-F]{2})/g, function (n, t) {
return o("0x" + t) // 把百分号. 换成了0x
});
try {
// base64, 浏览器自带的btoa功能
return window.btoa(t)
} catch (n) {
// base64, nodejs的base64

return window['Buffer']["from"](t)["toString"]("base64");
}
}

function oZ(n, t) {
// t = t || u();
for (var e = (n = n["split"](""))['length'], r = t['length'], a = 'charCodeAt', i = 0; i < e; i++)
n[i] = o(n[i][a](0) ^ t[(i + 10) % r][a](0));
return n["join"]("");

}


// 规定:
// { url: "完整的url", }
//
function get_mm(url, params) {
// 加一点我自己的代码. 处理成它需要的那个样子
// 分离出. baseurl, url
// 借助URL的功能.
var t = {};
// var u = new URL(url);
// t['baseURL'] = u['origin']; // t里面就有的baseURL了
t['baseURL'] = 'https://api.qimai.cn'; // t里面就有的baseURL了
t['url'] = url
t['params'] = params

s = -1228;
var e, r = +new Date - (s || 0) - 1661224081041, a = [];

// void 0 === t[Zt] && (t[Zt] = {})
if (void 0 === t['params']) {
t['params'] = {}
}

Object['keys'](t["params"])["forEach"](function (n) {
if (n == "analysis")
return false;
t['params']['hasOwnProperty'](n) && a['push'](t['params'][n])
});// 把params里面的所有的值. 组装到a列表


a = a['sort']()["join"](""); // 排序. 拼接 结果就是一个字符串. 装着所有的数据
console.log(a)
a = cv(a); // 计算了一个base64, "MjIwMjItMTItMDIzNmFsbGNuaXBob25l@#/xxxx/xxxx@#时间@#3"
console.log(a)
a = (a += "@#" + t["url"]["replace"](t["baseURL"], "")) + ("@#" + r) + ("@#" + 3);
console.log(a)
console.log(oZ(a, "xyz517cda96abcd"))
e = cv(oZ(a, "xyz517cda96abcd"));
return e
}

console.log(get_mm('https://api.qimai.cn/rank/index', {
'brand': 'free',
'device': 'iphone',
'country': 'cn',
'genre': '36'
}))


function p(n, t) {
for (var e = (n = n["split"](""))['length'], r = t['length'], a = 'charCodeAt', i = 0; i < e; i++)
n[i] = o(n[i][a](0) ^ t[(i) % r][a](0));
return n["join"]("");

}

function get_qm_check() {
var n = {
"gpu": "ANGLE (Intel, Intel(R) UHD Graphics 770 Direct3D11 vs_5_0 ps_5_0, D3D11)",
"check": "0,0,0,0,0"
}

return cv(p(JSON.stringify(n), 'xyz57209048abcd'))
}

console.log(get_qm_check())