首先先抓个包,分析他的参数,发现有一个h5st这样的参数
往下看还有一个x-api-eid-token
经过测试发现对其检测并不是很严格,重点还是这个h5st这个参数,废话不多说直接来分析吧
通过全局搜索关键词h5st,找到我们想要的接口位置打上断点进行页面刷新
这里我们找他的加密方法,发现他是由这个r方法进行加密这个h5st这个参数的
此时发现h5st已经生成了,向上跟栈查看哪里调用了该函数。
r是由这几个参数生成的
e是之前的对象做了处理,body已经知道是sha256后结果,中间一串固定,最后是一个当前时间戳。 r就是之前__genKey的结果。
接下来就是模拟生成算法了,这里我采用了纯算法,完全没必要扣js,毕竟一扣就是好几万行代码
CryptoJS = require('crypto-js'); const md5 = require('md5'); const _appId = "f961a", fingerprint = "ni6mz59tt9ggt5w9", _token = "tk03we9c31df518nK9QBfNOfZxyuMi7pYcPhmsaaoxSrIna8NGmEzCxxo71IQLNPqJsnfAWozsvQDZRFgVmlZzGiElFb", _version = "4.1", env = { "sua": "Windows NT 10.0; Win64; x64", "pp": { "p2": "jd_51517ab15e972" }, "extend": { "pm": 0, "wd": 0, "l": 0, "ls": 5, "wk": 0 }, "random": "j52LDo5u-C", "referer": "", "v": "v1.6.1", "fp": fingerprint }; function sha256(text) { return CryptoJS.SHA256(text).toString() } function collect() { let iv = CryptoJS.enc.Utf8.parse('0102030405060708'), key = CryptoJS.enc.Utf8.parse('HL4|FW#Chc3#q?0)'), data = CryptoJS.enc.Utf8.parse(JSON.stringify(env, null, 2)); // data aes = CryptoJS.AES.encrypt(data, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }); return aes.ciphertext.toString()//aes.toString() } function jd() { var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : Date.now() , t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : "yyyy-MM-dd" , r = new Date(e) , n = t , i = { "M+": r.getMonth() + 1, "d+": r.getDate(), "D+": r.getDate(), "h+": r.getHours(), "H+": r.getHours(), "m+": r.getMinutes(), "s+": r.getSeconds(), "w+": r.getDay(), "q+": Math.floor((r.getMonth() + 3) / 3), "S+": r.getMilliseconds() }; return /(y+)/i.test(n) && (n = n.replace(RegExp.$1, "".concat(r.getFullYear()).substr(4 - RegExp.$1.length))), Object.keys(i).forEach(function (e) { if (new RegExp("(".concat(e, ")")).test(n)) { var t = "S+" === e ? "000" : "00"; n = n.replace(RegExp.$1, 1 == RegExp.$1.length ? i[e] : "".concat(t).concat(i[e]).substr("".concat(i[e]).length)) } }), n }
function h5st(t, r) { let s = Date['now'](), h = _appId, p = fingerprint, l = jd(s, 'yyyyMMddhhmmssSSS'), ll = l + "04", d = _token; let o = CryptoJS.HmacMD5(`${d}${p}${ll}${h}b4v0JUR5Q4hw`, d).toString() console.log(o) // let o = sha256(`${d}${p}${ll}${h}b4v0JUR5Q4hw`) let join_text = "" t.forEach(function (element) { join_text = join_text + "&" + element.key + ":" + element.value }); // console.log(o + join_text.slice(1) + o) let A = md5(o + join_text.slice(1) + o) // let A = sha256('c142dab842b79943ebc623ee9b2bbe9459291a643c266631ec5f6656b155a1f1appid:jd-cphdeveloper-m&body:a4a9ad34ea9abb3c82748285b3c50adbdd1d33d429bbc815fc6a06afcc84cd2e&functionId:searchKeywordc142dab842b79943ebc623ee9b2bbe9459291a643c266631ec5f6656b155a1f1') let x = [""['concat'](l), ""['concat'](fingerprint), ""['concat'](_appId), ""['concat'](_token), "".concat(A), ""['concat'](_version), ""['concat'](s), ""['concat'](r)].join(";"); console.log(`x ---> ${x}`) return x // 'appid:jd-cphdeveloper-m&body:0e9c74a186d8a8d37f812f418aa221fe72c5a926c3d3b2093338276cf96ec345&functionId:m_search_promise_realtime' }
t = [
{
"key": "appid",
"value": "JDC_mall_cart"
},
{
"key": "body",
"value": body
},
{
"key": "client",
"value": "pc"
},
{
"key": "clientVersion",
"value": "1.0.0"
},
{
"key": "functionId",
"value": "pcCart_jc_getCurrentCart"
},
{
"key": "t",
"value": 1699339993250
}
]
r = collect()
h5st分别传两参数就是刚才分析的(e, r)
str = JSON.stringify({ "serInfo": { "area": "12_988_993_58088", "user-key": "6700b7d1-c4b6-42e3-aae9-0e79a85d471b" }, "cartExt": { "specialId": 1 } }) body = s ha256(str) 运行结果