目标网站
aHR0cHM6Ly93d3cuZXB3ay5jb20vbG9naW4uaHRtbA==
抓包分析
先抓一个登陆的包,payload里面没有需要分析的数据
需要分析的数据在请求头里面,我们的目标是分析这个Signature
Signature 分析
直接搜索这个关键字,可以找到两个位置,第二个是小写的,跟我们要分析的字段没什么关系
断下以后,这个函数就是我们需要的signature字段,那么就需要分析这个函数
Object(f.a)(U, M, l.j ? l.g : l.c)
分析参数U
函数里面传入了U作为第一个参数
这里我们需要先搞定参数U的这些字段是怎么来的
向上找U的来源
var U = {
"App-Ver": "",
"Os-Ver": "",
"Device-Ver": "",
Imei: "",
"Access-Token": "",
Timestemp: D,
NonceStr: "".concat(D).concat(Object(h.e)()),
"App-Id": l.j ? l.f : l.b,
"Device-Os": "web"
};
U的字段如上,这里面App-Id
和NonceStr
都是需要分析的,其他都是固定的
NonceStr: "".concat(D).concat(Object(h.e)())
这个NonceStr
字段就是Timestemp
和h.e()
函数结果的拼接
d = function() {
var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : 5;
return Math.random().toString(36).substring(3, 3 + e)
通过执行结果和函数原型,就可以知道NonceStr
字段其实就是时间戳加上五个随机字符的拼接,既然是随机的我们就可以直接写死。
接着再来看App-Id
"App-Id": l.j ? l.f : l.b
对于App-Id
这个字段,我们需要分析l的来源
这里l.j
的值是false,所以App-Id
的值是l.b
找到l.b
的来源,这里返回了一个f
f来源于这个位置
f = (e.env.NUXR_XWZN_DOMAIN,"4ac490420ac63db4")
这里是一个逗号表达式,所以App-Id
的值实际上就是固定的。
var U = {
"App-Ver": "",
"Os-Ver": "",
"Device-Ver": "",
Imei: "",
"Access-Token": "",
Timestemp: D,
NonceStr: "".concat(D).concat(Object(h.e)()),
"App-Id": "4ac490420ac63db4",
"Device-Os": "web"
};
到这里参数U我们就分析完了,整理成JS代码如下:
D = parseInt((new Date).getTime() / 1e3);
var U = {
"App-Ver": "",
"Os-Ver": "",
"Device-Ver": "",
"Imei": "",
"Access-Token": "",
"Timestemp": D,
"NonceStr": "".concat(D).concat("v6j3u"),
"App-Id": "4ac490420ac63db4",
"Device-Os": "web"
};
分析参数P
U.Signature = Object(f.a)(U, M, l.j ? l.g : l.c);
这里的第一个参数U我们已经分析完了,接下来分析参数M 。
参数M就是我们填写的登陆信息,账号密码加上图形验证码。
分析参数l.j
接下来分析参数l.j
l.j
的值是false,所以我们要看l.c
的值
l.c
来源于m
而m也是一个固定值,所以第三个参数我们也分析完了
分析函数f.a
U.Signature = Object(f.a)(U, M, l.j ? l.g : l.c);
接着再来分析调用的函数f.a
h = function(t) {
var data = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}
, e = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : "a75846eb4ac490420ac63db46d2a03bf"
, n = e + f(data) + f(t) + e;
return n = d(n),
n = v(n)
}
这里直接把函数拿下来,补齐缺失的代码,放到JS代码里调用就可以了
signature代码实现
const Crypto=require("crypto-js")
D = parseInt((new Date).getTime() / 1e3);
var U = {
"App-Ver": "",
"Os-Ver": "",
"Device-Ver": "",
"Imei": "",
"Access-Token": "",
"Timestemp": D,
"NonceStr": "".concat(D).concat("v6j3u"),
"App-Id": "4ac490420ac63db4",
"Device-Os": "web"
};
var M={'username': '17688888888', 'password': '123456', 'code': 'rtck', 'hdn_refer': ''};
third="a75846eb4ac490420ac63db46d2a03bf";
f = function(t) {
var e = "";
return Object.keys(t).sort().forEach((function(n) {
e += n + ("object" === typeof t[n] ? JSON.stringify(t[n], (function(t, e) {
return "number" == typeof e && (e = String(e)),
e
}
)).replace(/\//g, "\\/") : t[n])
}
)), e
}
d = function(data) {
return Crypto.MD5(data).toString();
}
l = {
key: Crypto.enc.Utf8.parse("fX@VyCQVvpdj8RCa"),
iv: Crypto.enc.Utf8.parse(function (t) {
for (var e = "", i = 0; i < t.length - 1; i += 2) {
var n = parseInt(t[i] + "" + t[i + 1], 16);
e += String.fromCharCode(n)
}
return e
}("00000000000000000000000000000000"))
}
v = function(data) {
return function(data) {
return Crypto.AES.encrypt(data, l.key, {
iv: l.iv,
mode: Crypto.mode.CBC,
padding: Crypto.pad.Pkcs7
}).toString()
}(data)
}
h = function(t) {
var data = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}
, e = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : "a75846eb4ac490420ac63db46d2a03bf"
, n = e + f(data) + f(t) + e;
return n = d(n),
n = v(n)
}
console.log(h(U, M, third));
把所需要的所有的代码全部抠下来,然后尝试运行
此时,我们已经拿到了signature字段的值了。