案例-一品威客
网址: https://www.epwk.com/
输入错误的账号密码,点击发送,可以得到请求:

下面的NonceStr需要关注一下,大概率是需要逆向的

还有下面这两个:大概率也是需要逆向

选取一个关键字全局搜索:发现有两个JS文件都有

在第一个JS文件打上断点:

第二个JS文件中:看到是一个小写的,大概率不太像。

回到我们断点的地方:刷新运行,然后观察输出结果:

对比参数的值,发现是一致的。

这里iv是一个大坑:'0000000000000000' 是一个字符串

正确的iv是: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

而 x00 是空字符:

Python代码:
import subprocess
from functools import partial
subprocess.Popen = partial(subprocess.Popen, encoding="utf-8")
import execjs
import requests
import json
f = open("一品威客.js", mode='r', encoding="utf-8")
js_code = f.read()
f.close()
js = execjs.compile(js_code)
data = {
"code": "",
"hdn_refer": "",
"password": "123456",
"username": "13211134154",
}
url = "https://www.epwk.com/api/epwk/v1/user/login"
session = requests.session()
session.headers = js.call("fn", data) # js代码调整成了. 最方便调用的样子.
session.headers["User-Agent"] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36"
resp = session.post(url, data=data)
print(resp.text)
一品威客.js
var crypto = require("crypto");
var CryptoJS = require("crypto-js");
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;
n = d(n);
n = v(n);
return n;
}
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(e){
return crypto.createHash("md5").update(e).digest('hex');
}
l = {
key: CryptoJS.enc.Utf8.parse("fX@VyCQVvpdj8RCa"),
iv: CryptoJS.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"))
// 这里iv是一个大坑....
// 这个iv可不是'0000000000000000'
// 正确的iv是: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
}
v = function(data) {
return CryptoJS.AES.encrypt(data, l.key, {
iv: l.iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
}).toString()
}
function fn(P){
let D = parseInt((new Date).getTime() / 1e3)
var U = {
"App-Ver": "",
"Os-Ver": "",
"Device-Ver": "",
"Imei": "",
"Access-Token": "",
"Timestemp": D+"",
"NonceStr": "".concat(D).concat('u1gq2'),
"App-Id": "4ac490420ac63db4",
"Device-Os": "web",
};
U['Signature'] = h(U,P, "a75846eb4ac490420ac63db46d2a03bf")
return U;
}
浙公网安备 33010602011771号