今天我们来js逆向某品威客-参数signature,实现登录:
1.抓包:
很明显sign是加密过的:
通过搜索关键词:
2.分析:
确定这里就是加密逻辑:
U.Signature = Object(f.a)(U, L, l.j ? l.g : l.c);
//需要解决参数U,L,以及判断 l.j 是否存在
U的逆向:
U 是一个对象:
往上溯源查看 U 的生成:
“App-Id”:
看"App-Id":l.j ? l.f : l.b ,
l.j是:
溯源 o:
所以e是写死的:
同理确定 l.b 也是固定值:
这样就确定了"App-Id"是固定值 = l.b:
_的逆向:
溯源_:发现是时间戳:
剩下h.e():
NonceStr: "".concat(_).concat(Object(h.e)()),
进入发现random:也可以固定下来
U 的整合:
"App-Id":'4ac490420ac63db4'
_ = parseInt((new Date).getTime() / 1e3)
h.e = 'srdwe'
var U = {
"App-Ver": "",
"Os-Ver": "",
"Device-Ver": "",
Imei: "",
"Access-Token": "",
Timestemp: _,
NonceStr: "".concat(_).concat('srdwe'),
"App-Id": '4ac490420ac63db4'
"Device-Os": "web"
};
L 的逆向:
L 是请求参数:
code: ""
hdn_refer: "https://www.epwk.com/"
password: "123456789"
username: "15819658566"
l.j的逆向:
U.Signature = Object(f.a)(U, L, l.j ? l.g : l.c);
刚才已经逆向到l.j为false:那么结果就是l.c
进入l.c:发现也是固定值
f.a()
U.Signature = Object(f.a)(U, L, l.j ? l.g : l.c);
到这里我们已经解决了f.a函数需要的参数,接下来看看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)
}
return n = d(n),
n = v(n)
发现d函数是md5,v函数是aes加密。
除此之外,f.a函数用到了f函数:
f = function(t) {
var e = "";
return Object.keys(t).sort().forEach((function(n) {
e += n + ("object" === Object(r.a)(t[n]) ? JSON.stringify(t[n], (function(t, e) {
return "number" == typeof e && (e = String(e)),
e
}
)).replace(/\//g, "\\/") : t[n])
}
)),
e
}
f函数用到了r.a:
function(e) {
return typeof e
}
3.代码整合:
//一品威客.js:
var crypto = require("crypto");
var CryptoJS = require("crypto-js");
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"))
}
d = function(data) {
return function(data) {
return CryptoJS.AES.encrypt(data, l.key, {
iv: l.iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
}).toString()
}(data)
}
v = function(e){
return crypto.createHash("md5").update(e).digest('hex');
}
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)
}
f = function(t) {
var e = "";
return Object.keys(t).sort().forEach((function(n) {
e += n + ("object" === Object(r)(t[n]) ? JSON.stringify(t[n], (function(t, e) {
return "number" == typeof e && (e = String(e)),
e
}
)).replace(/\//g, "\\/") : t[n])
}
)),
e
}
function r(e) {
return typeof e
}
function fn(L){
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,l, "a75846eb4ac490420ac63db46d2a03bf")
return U;
}
// 传入参数:
// var L = {
// code: "",
// hdn_refer: "https://www.epwk.com/",
// password: "1234567899",
// username: "15819657566" }
// console.log(fn(L))
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)
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)