Akamai 混淆解密

akamai 混淆是怎么运行的

'\x34': wp()[CS(KW)](SQ, zk) 为例子, 这里CS(KW)rt SQ 值为25, zk 值为1409

wp()[CS(KW)](SQ, zk) => wp()['rt'](25,1409)

image-20250102134823850

image-20250102134841352

image-20250108160716740

这里 LTI 有个 vt 属性,后面会用到

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
xrI -= Rw;
for (var TsI = xW; qW(TsI, wrI.length); ++TsI) {
wp()[wrI[TsI]] = hD(hc(TsI, FK)) ? function() {
return jr.apply(this, [M9, arguments]);
}
: function() {
var NBI = wrI[TsI];
return function(zBI, PLI) {
var lsI = LTI.call(null, zBI, PLI);
wp()[NBI] = function() {
return lsI;
}
;
return lsI;
}
;
}();
}

image-20250102135157188

image-20250102140010380

上面可以看到 LTI.call(null, zBI, PLI); 返回了结果之后赋值给了 lsI,wp['rt'] 这个函数又被重新赋值成了 返回 lsI 值的函数,也就是 wp['rt']() 运行的时候可以直接返回这个函数本来要返回值的,不用再传入实参。

往下跟栈,可以看到 mKI 这个函数, 这里的 XI 是一个控制数,

image-20250108161141103

image-20250102140549191

这里 S71 是 mKi 的第二个参数,也就是上面的 arguments 参数

往下面跟栈,可以看到这个参数值和这个最终运算出来的数据

image-20250102141722155

image-20250102142317383

再往下跟栈可以看到返回了 kTI 这个值

到这里整理下这个运行逻辑

1
2
3
4
5
6
7
8
9
10
11
wp()['rt'](25,1409) => 
LTI.call(null, zBI, PLI) =>
LTI = function(vKI, S3I) {
return mKI.apply(this, [xI, arguments]);
} =>
function mKI (){
case xI:
计算出kTI 的值
case jp:
return kTI
}

计算 kTI 的值,最后用到了 jp 函数

image-20250102142620025

image-20250102171208026

函数 jp 控制数 w1 的函数逻辑为以下代码

1
2
3
function jp(x) {
return String.fromCharCode(x[0])
}

以下为整个加密的代码整理 var rs = function mKI(xrI, S7I) {} 第一个值为 switch 控制数,不同的 xrI 实际值会有不同的分支,S7I 为实际传入的参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
var rs = function mKI(xrI, S7I) {
switch (xrI) {
case xI: {
var TDI = S7I[Dg];
var ASI = S7I[C1];
xrI = jg;
var kTI = vs([], []);
var GcI = MT(hc(ASI, Sp[hc(Sp.length, nK)]), xv);
var UcI = rCI[TDI];
for (var bTI = xW; qW(bTI, UcI.length); bTI++) {
var LLI = BcI(UcI, bTI);
var VsI = BcI(LTI.vt, GcI++);
kTI += jp(w1, [xL(VrI(LXI(LLI), LXI(VsI)), VrI(LLI, VsI))]);
}
}
break;
case jg: {
xrI = E;
return kTI;
}
break;

}

}

精简运算

xL(VrI(LXI(LLI), LXI(VsI)), VrI(LLI, VsI)) => (~LLI| ~VsI)&(LLI| VsI)

image-20250108164453808

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
function jp(x) {
return String.fromCharCode(x[0])
}

var DcI = function() {
return ["< \n\'", ",68_E+&=^82.\u0016XR/\b =\r", "[M\x3f!7A\x07!9", "\u0003><6\u00121,>;[}/$3\x40\u001d6(\u001e", "-7&k\t:9\vPE/", "R.7", "O\f4\u0003\u001aUN\r\u0011 2\r:$6y\x00R,1\b`\u00054:\u0017nq.\u000e\":\r1", ")\u0012*74\x07\n2/Fq#(7", ";+XE>:", "=B\u00058)\bTT,", ";", "\'66:S", "EN\f\u0013&>\u0017 +!+", "\"X", ",tc\u001b-\u0010770\u0011DG$67^\r%\u0003\u0012_G3", "1#<_L-;4U", "K\r#\u0015\u000fTL", "AM)\u0006&=\r\u0018\'9)BJ", "\rCQ>=\x3fi\u001a%3\tpG(\u0004=\u0015\v:!#\'YL\t3>\x40", "\u001cTU\u001f\u000e!\'", "1!Dg+1:", "SU3\x00", "!7X", "\u0010$.", ":=_\u001c9=\u0016T", "r", " =\u00151;\\\">", "A%<<I\v#", "\x40a", "=", "E~9\u000f", "Y#67Z\u000199[rN2\u0015*=\nt\u00062-D[:&;C\u0006w\u0011\u0014UT0\u0004", "Q:3<", ":e4", "\n;)\t", ":Yn%%7^+6/\u001e", "G,\u0015", "B623p", "nQ4\x00!\'\u00119", ")\u001e\u0012\u001d\u0004%/[G\u000f>7A\r9(", "u", "x1et", "!\v.6=Bu+&;^+82\u001dXS1", "6PU4", "\u0014<\u001c>\'4:\u0016r&\'5E\u0006\n", "$-> BG8\'\"", "_\u0018;5\u000f", "\x3f/R", "\x00\u0016;!<9WT/r\u0014\x40\t$4", "X\x07\u0004(\tXO;5.4", "EN)\u0002\'0\u001f:!2\"", "\u0018Y\x40.\" 7},*6^\u0001!9\tnD*\x00#&\u001f \'", "I\u001e22\u000f", "\'04*YA", "\r5\u0015\177", "!X\t%(/B", ")\u0017$!8*S", "\u001c", "$,\u0002_O9\u0013\u00102\u001a0+#\'YL+>\rFb0\u0014PE9\u0005", "(\';\\x40\f\x073\bEe=\u0015.", "\x3f\x00#0\v8##+pr", "_\u001c6.\u000feH1\u0004<\'\u001f92", "%\br\n", "\u0019 5", "iuX1\177", "$\u0017#", "\u001dAB", "\bXF2\x00# ", "\u0002 /wzKq\u0012=sBy>\177\u0015l$bu \u0014", "39\raH$\u0004#\u0001\u001f +8", "\x40,\u0013\u000e#*=/2<", "G2", "N+!&m\u0018%\u001d\u000eEN,\u000e<\'*\x07", "=\rPH0)*:\u0019<6", "8\u001e]U=;", ">\u0010\u0015 4%", "\u001fAV", "R#04t", "\'\'9*", ":3\u000eBD8\u000e8=", "O9\u001f3B\u0001\')\u0017PU5\u000e!\u0005\u001715$\vXC(>7H", "=\u0018RD0\u0004=2\n=-9", ".=3x\x00%3\u000fEM97.\x3f", "mG", "8WN\x3f7", "R8=&C\u001c.,\u001e", "0\u001650\u0016:", ">=tP+$7", "~\u0003\u0011\'2\u0010 -:/E", "H:\u0015", "33\u001e", "/\u0018CH,\u0015", "\u000ef~", "!_\x00", "F/$>", "\v\b!7\u0011#1w\u0003SF#3r|\u00046%\u001eC\u0001\f\r:4S=,w\nOL+\x3f;OH\u0015Z\u0001\u0010\b-!\u001f&;", "\u0015\r%I\n3.\u0012GD.\':=\u001d3\'5", "%\u0017606:S", "^", "3\u000f,\x3f\u00177)", "o])o##|N8)5%Pj=t[t-G\x40L5)[%5/", "\'!%+SL", "\u000e51#+", "z\x00\x07\u0012", "$)\u0019\\H(", "K.", "J\x07%1$BT>\f&\'", "\vPF98", "E:2/\u001eE", "Z\t;)\u001e~G", "\v2\n1", " \u001a1", "\x3f7FM>", "\u0005<:", ".\u001eVH/\u0015*!.&-#!UM&\u001a3B\f;9\t", "\u0018\x3f3\u0015T", "\u0011;\n 2m\u0012\u0019~e", "!\'+X\u0018", "h", "6(\u000fPB4$96\u0010 ", " \x07:6\x3f+EK9\u0001\"I\r443PR4", "\vb\u0010$\v", " 9\u000e", "\x0060"];
};
rCI = DcI()
let LTI = {}
LTI.vt = '!\\aOS~TBWN6"JRR,hW\\{1!\\aOS~TBWN6"JRR,hW\\{1!\\aOS~TBWN6"JRR,hW\\{1!\\aOS~TBWN6"JRR,hW\\{1'
var BcI = function (KVI, hVI) {
return KVI['charCodeAt'](hVI);
};


function dec(S7I) {
var TDI = S7I[0];
var ASI = S7I[1];
var kTI = ''
var GcI = (ASI - 992) % 21
var UcI = rCI[TDI];
for (var bTI = 0; bTI <UcI.length; bTI++) {
var LLI = BcI(UcI, bTI);
var VsI = BcI(LTI.vt, GcI++);
kTI += jp( [(~LLI| ~VsI)&(LLI| VsI)]);
}
return kTI;
}


console.log(dec([25, 1409]));
// 输出结果为 "."

image-20250108164958314

只要带入参数的实际值,就可以计算出所有 wp() 开头的混淆,

以下代码 wp()[CS(KW)](25, 1409)LTI.call(null, 25, 1409) 实际值相等。

其他如 Yr() 等函数的解密类似,不过会有点不一样,除了列表和解密的 key 之外,还可能会有类似的这种结构里 var GcI = (ASI - 992) % 21 % 之后的数字不一样,或者是 jp 函数传入参数前的运算逻辑不一样。

以下是一个函数的解密

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
let vCI = {U7: "3YTotqYT{ |C6G3$JC3YTotqYT{ |C6G3$JC3YTotqYT{ |C6G3$JC3YTotqYT{ |C6G3$JC3YTotqYT{ |C6G3$JC3YTotqYT{ |C6G3$JC3YTotqYT{ |C6G3$JC3YTotqYT{ |C6G3$JC3YTotqYT{ |C6G3$JC3YTotqYT{ |C6G3$JC3YTotqYT{ |C6G3$JC3YTotqYT{ |C6G3$JC3YTotqYT{ |C6G3$JC3YTotqYT{ |C6G3$JC3YTotqYT{ |C6G3$JC3YTotqYT{ |C6G3$JC"};

function BcI(KVI, hVI) {
return KVI.charCodeAt(hVI);
}

function jp(x) {
return String.fromCharCode(x);
}

let RCI = ["\t&\x00\u0019\u0018*1", "8\u0014A\u0018*X ", "7VV,,A45\u0001\u0017\u0014", ",%\x40", "P6:\u001c\x00\u0003,7\u000fO\u000e", "\u0003O\b", "G*0", "4GV#3c+;\u0017\r7+;\u0016e\u000e1Y5\x40", "8\"\u000e\u001d\u001d\u000e=\u001fT\u0014", "0S)Wi/0\x4083\n", "\u001d)b>CA\b*G45\u001c\u001f", "\u001f\u0001\u0003", "lxWYZGKSJ~uAv>,\177o>3SeXH&u58]", "* \u001c", "\fE\u001e(_3gA\'3\\+5\u001d\r\"-;\tAK%$_<t*\u0015\u0003-<[p\u00106QjZJ", "\u0011V88\x3f\u0018\u0010 1\t\x00*&D4ZK$cc5!\b\u001d\u001f", ".&Q\u0002KT", "\x3fE\u001a\"C+G\u0004\b1\\.\'\n\u0006Q\u00111\u0017P\u00191", "|\u001a\"G1\u0006\n\x07\u00045 ", "\"C)8\u00162\u000477", "K$\u000fZ71", "\x3f\u001eV", "D\u0011&", "\u0005d", "\u001d)B", "PH#&]-\u0003\u0006\u0010\u00051", "\u0014/1\u0015T0*[.Gf#,^< \u001d\u001d\u0012\u0018!\u000fO\f,E3", "5\u0003>!\u0016E\u00127E", "zJ<\"_00O\u0015\u0005-1\u0016P\bcB(\u0013\x40/0G+!\f\x00\u0004+1[N\u0013-A8\"Q51O\u001d\u001f* \u001aN\u001f&\u0018MzJj,A=1\u001dT\u00056t\u0019E\\*B\"AE(/Vut\u0001\u001b\001ft5\tR\u001d:\u0016(QN/ G*t\u0002\u0001\u0002-t\u0013A\n&\u0016&\u0013\177\u0019:^;;\u0003Z\u0018-1\tA\b,D\u001arj.V-<\x00\u0010_", "41\v\u001d\u0010\u001d1\rI\u001f&E", "\u001f,R\"cK#-G\u0018 ", "C\u000e&W3V", "\x40#0C55\u0016", "\bE\u000f0_(]w>,A83\n", "x\u0018W\u0019-\f", "\'\u001b\u0003<\u0003\u001eB+*R\"gV+ X0:\b1\t:1\vT\u0015,X", "C\u0018 i&WK\\8\'\u0001\u0012\u0010nb\vF\u001f\u0019z*PB&\u001cr+&\u000e\r", ":\!\u001d\u0006\u00147 (C\u000e*F3", "\u0018A\u00125W4", "\u0013-B(FG\"0G8&/8", "\f\u0006\u0014=1\u0015T\u0015\"Z4", ")5\bS", "\u0015\u0001)\u0019\u0012N\u00131`\"AW#,]", "\tA\u0012", "\r\u0006\u0010/1", "$\"C", "H\u001d1R0RV/\x00\\77\u001a\u0006\u0003<:\u0018Y", "5h%", "\u001d&Q\u0012=\u00187 \u001eG\u000e*S5GAj\u0013w\u001f", "W>\"A-\x00\u001d\u0015\u00122=\u0015G", "\u001eX\f,D3\x40", "W8 ", "hlF\'lT< 0\u0004\u0010+5\u0016SC7O7V\u0019", "7Y2PL\',E<", "\u0003\u001d\u0002-\u0012\u000eN\u001f7_(]W", "+.*1\u0017E\u0012*C*lQ$4A8$\u001f\u0011\u0015", "XA30", "\u000f/_$V", "$\u001eR\u001a\u0002B3A", "\u0019", "<:\u000e\u0016\u001d<0+L\t$_)", "\u0012", "41-;+R\u0015._3ZR/c^,\'\"\u0003< \u000eR\u0012cWgCV#.Z-=\u0019\u0011Q/5\u0017U\u0019m", "k", "\u001f&_+", "\u0018L\u0015 ]", "p%6P1\u0011\u0019\u0011\u001f-", "8$\u001f\u0011\u001f=\u0017\u0013I\u0010\'", "D<6B\u001e\u0002-;", ".", "#VB+6_-", "\u001aU\b,U(^T&&G<", "*\\Q9&~6\"\n0\u0010-5", "\u001c\u001403\u0013T", "*=\u0001E", "\u0001FJ)7Z6:", "\'\\vE\u001d(S5", "&%\u001a\u0004\u001eE\u000e\x00Y)]A)7Z6:", "^*\u001c\u0006\u0010\u0015<:", "4VG8&G", "u;\vCF", "+\u0002\u001aL", "G\u00197t&GP/1J", "\u001a6X$GM%-\u0013q3\n\x00Qpk\u0018O\u00127S)Gs#-W6#G(Y\u0005}R\x00 8\u001e\u00041pNpkO(*75\u000fI\n&\u0016$\\\\\x40/\u001fn\u0002\b\u0001T,\u0005)", "3\u001eT,\"D&^A>&A", " -", "+E8", ")7", "\u001de4Q\r", "%_+Vt+7[", "$7=\u000fY\\\u0013Z&JA8", "B\t7B(]", "W8!", "_8:\b\u0001\u0010>1", "%-^6!\u001c\u0011\u00156#\u0015", "\u0011\u00144", "5h$\u000f", "w", "6]", "9\u00017\u001953\u001et\u00053S", "^W\x07\"K\r;\u001a\u0017\u0019\t;\u0012N\b0", "Z", "\u0016\u000eF\u001a&D", "\x40", "\x07aE\"]W%1l=5\u0015Sc", "\u0014\"E\u0017AM<\"G<\x00\x00\u001f\u00147", "3\u001eT#7S+VI/7A ", "r/jC\v\u001egg(E$\v\u00102\u0006\u001c\u0017/", " Y)GA$7d0:\v\u0006", "\b9p\t"];


function meth(WVI) {
let hBI = WVI[1], G1I = WVI[2], dDI = '', VcI = (hBI - 379) % 18;
let MVI = RCI[G1I], gBI = 0;
while (gBI < MVI.length) {
let mCI = BcI(MVI, gBI), RTI = BcI(vCI.U7, VcI++);
dDI += jp(~(mCI & RTI) & (mCI | RTI));
gBI++;
}
return dDI;
}

console.log(meth([53, 990, 100])); // un
console.log(meth([53, 637, 43])); // pass
console.log(meth([53, 680, 81])); // secret
console.log(meth([0, 680, 81])); // secret

Akamai 混淆解密
https://kingjem.github.io/2025/01/02/akamai-混淆解密/
作者
Ruhai
发布于
2025年1月2日
许可协议