声明
本文仅供学习交流使用, 如侵立删!
目标网址
aHR0cHM6Ly93d3cucHJpY2VsaW5lLmNvbS5hdS8=
逆向目标
成功获取cookie reese84
即逆向成功
查看网站cookie reese84信息
发现cookie reese84无HttpOnly标识
无HttpOnly标识的Cookie = 服务器或JS生成 + JS可操作
HttpOnly标识的Cookie = 仅服务器生成下发 + JS不可读/写
所以可以使用Hook
定位cookie reese84生成赋值位置
Hook代码:
(function () {
'use strict';
const obj_attr_descriptor = Object.getOwnPropertyDescriptor(Document.prototype, 'cookie');
Object.defineProperty(document, 'cookie', {
get: function () {
return obj_attr_descriptor.get.call(this);
},
set: function (val) {
if (val.startsWith('reese84=')) {
debugger;
}
obj_attr_descriptor.set.call(this, val);
}
});
})();
使用油猴插件进行Hook
找到赋值cookie reese84的js文件
再对cookie reese84的值进行搜索
即可发现
cookie reese84的值 = POST请求的返回值token
也就是说
本地实现POST请求
即可获取cookie reese84的值
而实现POST请求
需要还原加密参数p
因此本地复现加密参数p的生成逻辑
进行POST请求
即可成功获取cookie reese84
动态JS
每次请求下发的加密JS
标识符都会发生改变
甚至加密函数逻辑也会发生改变
在动态JS中
还有多个绑定参数(与JS相互绑定)
如 st、sr 等
加密函数
对加密JS文件进行反混淆
再使用抓包工具进行匹配替换
在反混淆的JS中
使用字符串"p"进行搜索
很容易就定位到加密参数p的赋值
根据定位代码处
对加密逻辑进行分析
在加密参数p赋值的函数中
也就是加密函数
基于随机种子
生成两个伪随机数组
一个用于处理参数对象
一个用于处理指纹对象
基于伪随机数组(不同的JS, 伪随机数组长度也不同)
对基于参数对象转换的字符串得到的Unicode数组
进行加密
这些加密包括但不限于
置换、异和模运算
将加密后的结果使用base64编码
编码后的结果添加到指纹对象中
然后指纹对象的处理方式与参数对象一致
对基于指纹对象转换的字符串得到的Unicode数组
进行加密
将加密后的结果字符串使用base64编码
编码后的结果赋值给加密参数p
将加密函数逻辑重构到本地
// 随机种子
// var SC = window["Math"]["random"]() * 1073741824 | 0;
var SC = 422158151;
// 参数对象
let WP = {"b": 0, "h": null, "t": 0, "r": 0, "i": null, "e": null}
// 指纹对象
let Yq = {}
function GM(FZ, CV) {
var ls = "[depth limit]";
if (CV < 2) {
var JI = "string cast failed";
var fO = "no Error.message";
var Z1 = "JSON.stringify exception";
try {
Z1 = JSON["stringify"](FZ) + "";
} catch (XW) {
}
try {
JI = "string cast: " + FZ;
} catch (Nd) {
}
var km = "no Error.name";
try {
if (typeof FZ["name"] === "string") {
km = FZ["name"];
}
} catch (nR) {
}
try {
if (typeof FZ["message"] === "string") {
fO = FZ["message"];
}
} catch (rT) {
}
var dp = "no Error.stack";
var Sn = "no Error.cause";
try {
if (typeof FZ["stack"] === "string") {
dp = FZ["stack"];
}
} catch (Pk) {
}
try {
if (FZ["cause"]) {
Sn = GM(FZ["cause"], CV + 1);
}
} catch (V6) {
}
ls = JI + " ;; " + Z1 + " ;; " + km + " ;; " + fO + " ;; " + dp + " ;; " + Sn;
}
return ls;
}
function S_(Vi, qZ) {
var FV = Vi;
var Lg = qZ;
returnfunction () {
var sG = FV;
sG ^= sG << 23;
var Cd = Lg;
sG ^= sG >> 17;
sG ^= Cd;
sG ^= Cd >> 26;
FV = Cd;
Lg = sG;
return (FV + Lg) % 4294967296;
};
}
function JE(w7) {
return"\\u" + ("0000" + w7.charCodeAt(0).toString(16)).substr(-4);
}
var mi = newRegExp("[\\u007F-\\uFFFF]", "g");
if (WP["e"]) {
WP["e"] = GM(WP["e"], 0);
}
var cD = S_(290410654, SC);
var fhG = [];
var FEZ = 0;
while (FEZ < 45) {
fhG.push(cD() & 255);
FEZ += 1;
}
var uD = fhG;
var H1Q = uD;
var ft = JSON.stringify(WP, function (DX, X8i) {
return X8i === undefined ? null : X8i;
});
var xN = ft.replace(mi, JE);
var Q_ = [];
var hX2 = 0;
while (hX2 < xN.length) {
Q_.push(xN.charCodeAt(hX2));
hX2 += 1;
}
var WB = Q_;
var d2k = WB;
var hw = d2k.length;
var zr = [];
var aQt = 0;
while (aQt < hw) {
zr.push(d2k[(aQt + H1Q[0]) % hw]);
aQt += 1;
}
var Zt = zr;
var kq = Zt.length;
var ST = H1Q["slice"](1, 22).length;
var j_ = [];
var t_ = 113;
var hq = 0;
while (hq < kq) {
var jY = Zt[hq];
var fGm = H1Q["slice"](1, 22)[hq % ST];
var p2k = jY ^ fGm ^ t_;
j_.push(p2k);
t_ = p2k;
hq += 1;
}
var fcH = j_;
var QHB = fcH.length;
var iWP = H1Q["slice"](22, 44).length;
var hMM = [];
var jF = 0;
while (jF < QHB) {
var NL = fcH[jF];
var vXt = H1Q["slice"](22, 44)[jF % iWP] & 127;
hMM.push((NL + vXt) % 256 ^ 128);
jF += 1;
}
var Xdc = hMM;
var Li = [];
for (var D8l in Xdc) {
var IrE = Xdc[D8l];
if (Xdc.hasOwnProperty(D8l)) {
var Jw = String.fromCharCode(IrE);
Li.push(Jw);
}
}
var p5v = btoa(Li.join(""));
Yq["OOw!Lrd-t!Iz,q/Tt$ozQK/XuyC&(DmZtXU="] = p5v;
var oPg = {};
var AXv = S_(1740574759, SC);
var Oj = [];
var SH = 0;
while (SH < 19) {
Oj.push(AXv() & 255);
SH += 1;
}
var pV = Oj;
var FDT = pV;
var dzy = JSON.stringify(Yq, function (Fu, tZ) {
return tZ === undefined ? null : tZ;
});
var WGn = dzy.replace(mi, JE);
var Ni = [];
var XX = 0;
while (XX < WGn.length) {
Ni.push(WGn.charCodeAt(XX));
XX += 1;
}
var v4j = Ni;
var tbo = v4j;
var K50 = tbo.length;
var Fl = FDT["slice"](0, 16).length;
var ba = [];
var nmj = 0;
while (nmj < K50) {
ba.push(tbo[nmj]);
ba.push(FDT["slice"](0, 16)[nmj % Fl]);
nmj += 1;
}
var KvN = ba;
var JK = KvN.length;
var q49 = FDT[16] % 7 + 1;
var yP4 = [];
var ciD = 0;
while (ciD < JK) {
yP4.push((KvN[ciD] << q49 | KvN[ciD] >> 8 - q49) & 255);
ciD += 1;
}
var gKj = yP4;
var L9 = [];
for (var hGR in gKj) {
var Bz0 = gKj[hGR];
if (gKj.hasOwnProperty(hGR)) {
L9.push(Bz0);
}
}
var uo = L9;
var fy = uo;
var Op = fy.length;
var l2 = 0;
while (l2 + 1 < Op) {
var EZ = fy[l2];
fy[l2] = fy[l2 + 1];
fy[l2 + 1] = EZ;
l2 += 2;
}
var Gc = fy;
var UT4 = Gc.length;
var cMW = FDT[17] % 7 + 1;
var c6 = [];
var ew = 0;
while (ew < UT4) {
c6.push((Gc[ew] << cMW | Gc[ew] >> 8 - cMW) & 255);
ew += 1;
}
var gD6 = c6;
var O3A = [];
for (var Zs in gD6) {
var dfQ = gD6[Zs];
if (gD6.hasOwnProperty(Zs)) {
var asu = String.fromCharCode(dfQ);
O3A.push(asu);
}
}
var BZ = btoa(O3A.join(""));
console.log(BZ)
因为是动态JS
不同的JS
加密函数的逻辑也不同
特别是加密过程
需要特别注意
加密函数样本2
加密函数样本3
所以在不同的JS的加密函数中
相同输入
不同输出
算法流程总结
指纹对象创建
指纹生成数组创建
数组使用push方法添加23个函数
遍历数组
执行数组中的每个函数
在这23个函数中
将环境特征值、环境值、事件信息
以及这些信息的加密值
添加到指纹对象中
对指纹对象进行加密
将加密后的结果使用base64进行编码
最终得到加密参数p的值
指纹对象
指纹对象是请求参数p生成的关键
指纹对象的键值是由环境特征值、环境值、事件信息
以及这些信息的加密值组成
由于是动态JS
指纹对象键名和指纹对象键值相关加密函数与JS相互绑定
随着JS的改变而改变
但是指纹对象的键值对数量不变(63个键值对)
指纹对象中的环境特征值、环境值、事件信息生成逻辑不变
但是对这些信息进行加密的函数的加密逻辑
随着JS的改变而改变
不同JS
指纹对象添加相应键值对的顺序相同
指纹对象事件信息加密值
以指纹对象第0个键值对为例
对移动端和PC端
进行相应的事件绑定
以PC端为例
创建一个PC事件加密信息数组
遍历PC端相关事件
document使用addEventListener方法
监听当前遍历的事件
事件监听器是一个加密函数
在这个加密函数中
收集事件信息
type、timeStamp、clientX、clientY、screenX、screenY
将这些事件信息集成到一个对象中
利用随机种子生成伪随机数组
根据伪随机数组
对事件信息对象进行加密
将加密结果进行base64编码
编码后的结果添加到PC事件加密信息数组中
当事件触发数量达到5个时
运行事件移除函数
在事件移除函数中
doucument使用removeEventListener方法
移除PC端事件列表中
所有的事件绑定
已经触发的5个事件加密结果
都添加到了PC事件加密信息数组中
这个PC事件加密信息数组
就是指纹对象第0个键值对的值的一部分
还一部分是移动端事件信息加密(PC端一般为默认值, 不触发)
提取代码:
var H7 = [];
var qo = window["document"];
var SC = window["Math"]["random"]() * 1073741824 | 0;
var QV = 5;
var Sc = 10;
var HR = {};
var Vu = 0;
HR["tuy&Lrp-uZKy,q/Tslo(QLLXNyA-(LmZ"] = [];
zA = {};
function JE(w7) {
return"\\u" + ("0000" + w7.charCodeAt(0).toString(16)).substr(-4);
}
var mi = newRegExp("[\\u007F-\\uFFFF]", "g");
function S_(Vi, qZ) {
var FV = Vi;
var Lg = qZ;
returnfunction () {
var sG = FV;
sG ^= sG << 23;
var Cd = Lg;
sG ^= sG >> 17;
sG ^= Cd;
sG ^= Cd >> 26;
FV = Cd;
Lg = sG;
return (FV + Lg) % 4294967296;
};
}
var Wc = function (nh) {
(function (UI, AA) {
var jQ = {};
if (!UI) {
UI = {};
}
(function (tj) {
if (tj !== undefined) {
jQ["Ouy)Ljh-spI="] = tj;
}
})(UI["type"]);
(function (Qz) {
if (Qz !== undefined) {
jQ["Ouy_LrZ-spKv,rnTOlqwQLbXOCA="] = Qz;
}
})(UI["timeStamp"]);
(function (ZA) {
if (ZA !== undefined) {
jQ["sew[LrR-spI&,jrTr$o)QA=="] = ZA;
}
})(UI["clientX"]);
(function (zy) {
if (zy !== undefined) {
jQ["sew[LrR-spI&,jrTr$q)QA=="] = zy;
}
})(UI["clientY"]);
(function (uO) {
if (uO !== undefined) {
jQ["ueyxLjl-spKy,jfTr$o)QA=="] = uO;
}
})(UI["screenX"]);
(function (ks) {
if (ks !== undefined) {
jQ["ueyxLjl-spKy,jfTr$q)QA=="] = ks;
}
})(UI["screenY"]);
var kb = S_(1650762707, SC);
var Dg = [];
var xe = 0;
while (xe < 60) {
Dg.push(kb() & 255);
xe += 1;
}
var ng = Dg;
var yK = ng;
var ae = window.JSON.stringify(jQ, function (ox, O0) {
return O0 === undefined ? null : O0;
});
var T9 = ae.replace(mi, JE);
var x_ = [];
var sW = 0;
while (sW < T9.length) {
x_.push(T9.charCodeAt(sW));
sW += 1;
}
var Pi = x_;
var e0 = Pi;
var g0 = e0.length;
var kD = [];
var Qi = g0 - 1;
while (Qi >= 0) {
kD.push(e0[Qi]);
Qi -= 1;
}
var dT = kD;
var Qp = dT.length;
var hC = yK["slice"](0, 29).length;
var Qa = [];
var gb = 0;
while (gb < Qp) {
Qa.push(dT[gb]);
Qa.push(yK["slice"](0, 29)[gb % hC]);
gb += 1;
}
var Wm = Qa;
var l3 = Wm.length;
var hs = yK["slice"](29, 58).length;
var c4 = [];
var Y4 = 113;
var ZM = 0;
while (ZM < l3) {
var D4 = Wm[ZM];
var XA = yK["slice"](29, 58)[ZM % hs];
var n2 = D4 ^ XA ^ Y4;
c4.push(n2);
Y4 = n2;
ZM += 1;
}
var eC = c4;
var Ur = eC.length;
var e3 = [];
var My = 0;
while (My < Ur) {
e3.push(eC[(My + yK[58]) % Ur]);
My += 1;
}
var nv = e3;
var PY = [];
for (var Nj in nv) {
var j5 = nv[Nj];
if (nv.hasOwnProperty(Nj)) {
var Ay = window.String.fromCharCode(j5);
PY.push(Ay);
}
}
var ud = window.btoa(PY.join(""));
var q1 = ud;
HR["tuy&Lrp-uZKy,q/Tslo(QLLXNyA-(LmZ"]["push"](q1);
Vu += 1;
if (Vu >= QV) {
AA["abort"]();
}
})(nh, zA);
};
for (var eq in ["dblclick", "mousedown", "mouseenter", "mouseleave", "mousemove", "mouseout", "mouseover", "mouseup"]) {
var dg = ["dblclick", "mousedown", "mouseenter", "mouseleave", "mousemove", "mouseout", "mouseover", "mouseup"][eq];
if (["dblclick", "mousedown", "mouseenter", "mouseleave", "mousemove", "mouseout", "mouseover", "mouseup"].hasOwnProperty(eq)) {
H7["push"](function (Pe) {
qo["addEventListener"](Pe, Wc);
}(dg));
}
}
zA["abort"] = function () {
console.log(HR);
var rz = [];
for (var ir in ["dblclick", "mousedown", "mouseenter", "mouseleave", "mousemove", "mouseout", "mouseover", "mouseup"]) {
var rg = ["dblclick", "mousedown", "mouseenter", "mouseleave", "mousemove", "mouseout", "mouseover", "mouseup"][ir];
if (["dblclick", "mousedown", "mouseenter", "mouseleave", "mousemove", "mouseout", "mouseover", "mouseup"].hasOwnProperty(ir)) {
rz["push"](function (gl) {
qo["removeEventListener"](gl, Wc);
}(rg));
}
}
};
由于是动态JS
不同的JS
其事件加密函数的加密逻辑也不同
指纹对象环境特征值加密值
以指纹对象第1个键值对为例
音频指纹生成并收集
利用随机种子生成伪随机数组
根据伪随机数组
对音频指纹信息进行加密
将加密结果进行base64编码
编码后的结果
即是第1个键值对的值
提取代码:
var SC = window["Math"]["random"]() * 1073741824 | 0;
var ma = newwindow["Date"]()["getTime"]();
var poa = "[\"triangle\",-74,7,16,0.7992663,0.47047582]"
var vO3 = {
hash: function(p81) {
p81 = unescape(encodeURIComponent(p81));
var vA3 = [1518500249, 1859775393, 2400959708, 3395469782];
var v59 = (p81 += String.fromCharCode(128)).length / 4 + 2;
for (var v60 = Math.ceil(v59 / 16), v61 = newArray(v60), vLN09 = 0; vLN09 < v60; vLN09++) {
v61[vLN09] = newArray(16);
for (var vLN010 = 0; vLN010 < 16; vLN010++) {
v61[vLN09][vLN010] = p81.charCodeAt(vLN09 * 64 + vLN010 * 4) << 24 | p81.charCodeAt(vLN09 * 64 + vLN010 * 4 + 1) << 16 | p81.charCodeAt(vLN09 * 64 + vLN010 * 4 + 2) << 8 | p81.charCodeAt(vLN09 * 64 + vLN010 * 4 + 3);
}
}
v61[v60 - 1][14] = (p81.length - 1) * 8 / Math.pow(2, 32);
v61[v60 - 1][14] = Math.floor(v61[v60 - 1][14]);
v61[v60 - 1][15] = (p81.length - 1) * 8 & -1;
var v62;
var v63;
var v64;
var v65;
var v66;
var vLN17325841932 = 1732584193;
var vLN4023233417 = 4023233417;
var vLN2562383102 = 2562383102;
var vLN2717338782 = 271733878;
var vLN3285377520 = 3285377520;
var v67 = newArray(80);
for (vLN09 = 0; vLN09 < v60; vLN09++) {
for (var vLN011 = 0; vLN011 < 16; vLN011++) {
v67[vLN011] = v61[vLN09][vLN011];
}
for (vLN011 = 16; vLN011 < 80; vLN011++) {
v67[vLN011] = vO3.ROTL(v67[vLN011 - 3] ^ v67[vLN011 - 8] ^ v67[vLN011 - 14] ^ v67[vLN011 - 16], 1);
}
v62 = vLN17325841932;
v63 = vLN4023233417;
v64 = vLN2562383102;
v65 = vLN2717338782;
v66 = vLN3285377520;
for (vLN011 = 0; vLN011 < 80; vLN011++) {
var v68 = Math.floor(vLN011 / 20);
var v69 = vO3.ROTL(v62, 5) + vO3.f(v68, v63, v64, v65) + v66 + vA3[v68] + v67[vLN011] & -1;
v66 = v65;
v65 = v64;
v64 = vO3.ROTL(v63, 30);
v63 = v62;
v62 = v69;
}
vLN17325841932 = vLN17325841932 + v62 & -1;
vLN4023233417 = vLN4023233417 + v63 & -1;
vLN2562383102 = vLN2562383102 + v64 & -1;
vLN2717338782 = vLN2717338782 + v65 & -1;
vLN3285377520 = vLN3285377520 + v66 & -1;
}
return vO3.toHexStr(vLN17325841932) + vO3.toHexStr(vLN4023233417) + vO3.toHexStr(vLN2562383102) + vO3.toHexStr(vLN2717338782) + vO3.toHexStr(vLN3285377520);
},
f: function(p82, p83, p84, p85) {
switch (p82) {
case0:
return p83 & p84 ^ ~p83 & p85;
case1:
case3:
return p83 ^ p84 ^ p85;
case2:
return p83 & p84 ^ p83 & p85 ^ p84 & p85;
}
},
ROTL: function(p86, p87) {
return p86 << p87 | p86 >>> 32 - p87;
},
toHexStr: function(p88) {
var vLS2 = "";
for (var vLN7 = 7; vLN7 >= 0; vLN7--) {
vLS2 += (p88 >>> vLN7 * 4 & 15).toString(16);
}
return vLS2;
}
}
// SHA1
var tm = vO3['hash']
function JE(w7) {
return"\\u" + ("0000" + w7.charCodeAt(0).toString(16)).substr(-4);
}
var mi = newRegExp("[\\u007F-\\uFFFF]","g");
function S_(Vi, qZ) {
var FV = Vi;
var Lg = qZ;
returnfunction() {
var sG = FV;
sG ^= sG << 23;
var Cd = Lg;
sG ^= sG >> 17;
sG ^= Cd;
sG ^= Cd >> 26;
FV = Cd;
Lg = sG;
return (FV + Lg) % 4294967296;
}
}
function A8() {
var y9 = {};
function m9(L4) {
returnnewwindow["Promise"](function(d9, wN) {
L4["oncomplete"] = function(TH) {
d9(TH["renderedBuffer"]);
}
;
var R2 = 3;
function mB() {
L4["startRendering"]();
if (L4["state"] === "suspended" && !qo["hidden"]) {
if (--R2 > 0) {
window["setTimeout"](mB, 20);
} else {
wN(newwindow["Error"]("suspended"));
}
} else {
window["setTimeout"](function() {
wN(newwindow["Error"]("timeout"));
}, 60);
}
}
L4["startRendering"]();
if (L4["state"] === "suspended" && !qo["hidden"]) {
if (--R2 > 0) {
window["setTimeout"](mB, 20);
} else {
wN(newwindow["Error"]("suspended"));
}
} else {
window["setTimeout"](function() {
wN(newwindow["Error"]("timeout"));
}, 60);
}
}
);
}
function xa(d0) {
return d0["reduce"](function(DG, Ll) {
return DG + window["Math"]["abs"](Ll);
}, 0);
}
function X5(eU) {
var xv = undefined;
if (eU["length"] >= 2) {
var M_ = eU["length"];
var ev = eU["reduce"](function(gu, Fz) {
return gu + Fz;
}) / M_;
var D9 = eU["map"](function(xO) {
return (xO - ev) * (xO - ev);
})["reduce"](function(bB, E2) {
return bB + E2;
}, 0) / (M_ - 1);
xv = window["Math"]["sqrt"](D9);
}
return xv;
}
var zR = undefined;
var rj = window["JSON"]["parse"](poa);
var eL = window["OfflineAudioContext"] || window["webkitOfflineAudioContext"];
var CR = new eL(1,765,44100);
var x2 = SC + ma;
var J_ = tm(x2);
var XJ = window["parseInt"](J_["substring"](0, 3), 16);
var gz = XJ >>> 2;
var ZB = window["Math"]["floor"](gz / 1024 * 11458) + 440;
var UZ = CR["createOscillator"]();
UZ["type"] = rj[0];
UZ["frequency"]["value"] = ZB;
var zx = CR["createDynamicsCompressor"]();
zx["threshold"]["setValueAtTime"](rj[1], CR["currentTime"]);
zx["knee"]["setValueAtTime"](rj[2], CR["currentTime"]);
zx["ratio"]["setValueAtTime"](rj[3], CR["currentTime"]);
zx["attack"]["setValueAtTime"](rj[4], CR["currentTime"]);
zx["release"]["setValueAtTime"](rj[5], CR["currentTime"]);
UZ["connect"](zx);
zx["connect"](CR["destination"]);
UZ["start"](0);
zR = m9(CR)["then"](function(CS) {
var po = CS["getChannelData"](0)["subarray"](265, 765);
var Fd = X5(po);
var xt = xa(po);
var Zv = window["Math"]["min"]["apply"](window["Math"], po);
var jH = window["Math"]["max"]["apply"](window["Math"], po);
var RA = window["Object"]["values"](po["subarray"](300, 306));
y9["uew-LjJ-r!Iy,rLTO$o="] = Fd;
y9["uey-LrZ-"] = xt;
y9["ueywLrZ-OJI[,rLT"] = RA;
y9["tuy_Ljd-"] = Zv;
y9["tuywLjx-"] = jH;
return y9;
})["catch"](function(PP) {
y9["suw!Ljl-t!I!,g=="] = PP["toString"]();
return y9;
})["finally"](function(SV) {
UZ["disconnect"]();
zx["disconnect"]();
return SV;
});
return zR;
}
var pL = A8()["then"](function(Ug) {
var HQ = S_(3440687145, SC);
var hk = [];
var Cx = 0;
while (Cx < 54) {
hk.push(HQ() & 255);
Cx += 1;
}
var PH = hk;
var Em = PH;
var Bj = window.JSON.stringify(Ug, function(Bu, AQ) {
return AQ === undefined ? null : AQ;
});
var yC = Bj.replace(mi, JE);
var Av = [];
var mN = 0;
while (mN < yC.length) {
Av.push(yC.charCodeAt(mN));
mN += 1;
}
var Hx = Av;
var lB = Hx;
var s4 = lB.length;
var Cg = Em[0] % 7 + 1;
var St = [];
var to = 0;
while (to < s4) {
St.push((lB[to] << Cg | lB[to] >> 8 - Cg) & 255);
to += 1;
}
var Vb = St;
var ki = Vb.length;
var gS = Em["slice"](1, 24).length;
var gV = [];
var Tt = 0;
while (Tt < ki) {
var yS = Vb[Tt];
var lv = Em["slice"](1, 24)[Tt % gS] & 127;
gV.push((yS + lv) % 256 ^ 128);
Tt += 1;
}
var Xh = gV;
var eD = Xh.length;
var ix = Em["slice"](24, 53).length;
var Vv = [];
var o4 = 0;
while (o4 < eD) {
Vv.push(Xh[o4]);
Vv.push(Em["slice"](24, 53)[o4 % ix]);
o4 += 1;
}
var ku = Vv;
var Ci = ku.length;
var Uv = [];
var qQ = Ci - 1;
while (qQ >= 0) {
Uv.push(ku[qQ]);
qQ -= 1;
}
var qr = Uv;
var sN = [];
for (var Yl in qr) {
var Gu = qr[Yl];
if (qr.hasOwnProperty(Yl)) {
var wh = window.String.fromCharCode(Gu);
sN.push(wh);
}
}
var bM = window.btoa(sN.join(""));
console.log(bM)
});
poa的值是音频指纹的配置参数
不同的JS
poa的值也不同(可通过关键字poa进行搜索定位)
其音频指纹加密函数的加密逻辑也不同
后续
如何在本地还原构造指纹对象的生成
保证指纹对象的正确性和唯一性
再加上动态JS的解决方案
是绕过风控的重点
如果是直接扣代码构造请求
就算请求通过
也是远远不够的
如何绕过风控
实现并发才是重点