在返回的doc类型的响应体中,某个JS链接会请求至少两次
由sensor_data为键组成的请求体

这里重点关注_abck,通常情况下其末尾出现||0||表示验证通过
通过特征分析,确定要解决的问题就是找到请求体中sensor_data的生成逻辑,通过第二次POST请求验证拿到正确的cookie
在浏览器中,通过第二次POST请求中的Initiator定位到发出请求的位置,追踪其中有关sensor_data的处理逻辑,

可以发现lCH就是sensor_data的值,wMH为拼接之后的请求体。
找到lCH第一次赋值的地方,

发现其由cKH格式化后得到,查看cKH对象的值。
可以看到cKH有很多键,需要分析的参数多也正是akamai的难点之一。
这时不要替换响应内容,试试重复多次请求,多保存几份cKH。
JS链接可能是动态变化的,变量名、调用方式等都可能会发生改变,下面都以cKH这版的JS为例。
多次对比,看看类似 cKH的对象包括其后面的处理流程会不会发生结构性改变或者哪些键的值有明显变化的,这将决定纯算法还原的方式可不可行,稳不稳定。
如果对象结构基本一致,里面的值的格式也差不多,JS的整体处理逻辑也差不多,就可以尝试算法还原,否则建议尝试补环境。当使用算法实现时,在用浏览器调试分析时,可以拦截引发动态变化的响应体替换成一份固定的响应体进行分析。针对处理逻辑也动态变化的JS,补环境时可能也要考虑在固定分析之后多尝试不同版本的JS逻辑来确定环境通用。
当全部算法还原之后发现还是过不了验证,如果确定不是算法还原出了问题,这时拿一份最新的cKH,和还原的算法生成出来的做一下对比,针对不同的地方再做进一步分析,包括分析后续对cKH的处理流程
同一版本的akamai算法中,类cKH的对象中的部分值的算法实现可能每周都会有变动,这里的变动周期相对来说比较长,不是每次请求都会变,所以纯算法实现也是可行的,甚至也可能找到变动的规律,减少我们自己算法实现的迭代频率。
接下来就是大致过一遍部分代码的逻辑,然后分析这些键的值是怎么来的,之后落地应用时可以尝试哪些键是不检测的。
大致过一部分代码逻辑,可以得到一些结论
当前JS算法版本标志,跟踪发现其由OCH得到

OCH的生成逻辑为
可以看到其中有很多形如CP()["E"].apply(null, [569, 86, 259, 81])这样的函数调用,其实多次记录发现这些值算出来都是固定的,这里的"E"也是通过某个类似XX(5)这样的函数算出来的,同理也是固定的,还原前面的部分,得到
这里就以FK()["qH"](1780, 58)举例说明这样形式的调用的值是怎么来的,定位到FK()["qH"],发现是赋值的形式

这里的setFuncKeyMap('FK', gHH, CQH);为hook的代码,找到这里的cUH和rHH的定义的地方,就是同switch下的case 49里定义的,

T9跟踪得到就是0,V1H就是这个switch case函数的第二个参数

追踪到Ud调用的地方

V1H就等于[n1H()],定义如下
也就是说最开始遍历赋值的时候,这些值都是每个JS固定的。
回到case 707,它会根据B0(J6(cUH, 6))这个条件来选择赋值哪个函数,以其中一种形式分析,

可以看到FK()["qH"](1780, 58)这样的调用就等价于Xk(1780, 58),接下来看Xk看了什么
又回到了Ud,走case 34

V1H这时候就是传过来的arguments,这里也就是[1780, 58],ph也是每个JS的固定值

由于w2是记录执行步骤的,所以RUH的结果主要受V1H影响,P0也是根据V1H去ph中取值,继续往下走


这里cn在刚刚的case 34中初始为"",只在case 281中进行赋值,GY也是一个switch case函数,其case 56如下

就是对cF执行了String.fromCharCode,注意如果走到下面这个条件就是不对的。回到Ud的逻辑来继续分析

可以看到最后cn就是FK()["qH"](1780, 58)的值,其实这里也可以倒推出既然某个位置这样的函数算出来的字符串是固定的,那这里的参数每个JS里也必然都是固定的
定位到与ajr相关的地方,可以看到ajr与AJH有关

搜索AJH,定位到AJH生成的地方,可以看到AJH由一个参数化数组经过Yc函数执行后,再由L3H函数生成。

这里可以先不管后面的数据的内容是怎么生成的,直接看L3H干了什么,L3H定义如下
前面这段判断条件一定为true,不然也不会生成结果了,所以接下来重点看这个函数干了啥
p7H即为Yc(31, [...那段生成的内容,这里可以直接看到那段的作用就是将数组转换为了对象,且整个函数逻辑中只用到了对象的totVel属性,totVel一般也是0。
跟踪这里的jS()和Ib的函数逻辑
W1H就是将随机数及其相关的base64编码组合起来形成一个数组。
最后LlH就是我们要的AJH,也就是最终的ajr的值
追踪定位到din是由哪个变量赋值的,发现其对应O4H
其中上一步骤的AJH生成过程中的deviceData也和O4H有关
其生成逻辑是,O4H先转化为只包含对应键的值的数组,顺序和O4H保持一致,最后使用","join生成结果。

追踪到O4H,找到其生成方式
L0H中包含排版引擎,ua,随机数,屏幕尺寸等信息的获取及二次处理,分析其内部执行逻辑,定位其中的关键字段生成的地方
window.innerHeight
每个JS固定,由nj(61, [])生成
window.innerWidth
对应zzH,其生成逻辑为
window.screen.availHeight
window.screen.availWidth
由zIH函数生成, 格式为
这块基本可以写死,下面就简单看几个值的生成逻辑
cpen
i1
dm
对应skH的生成逻辑
window.screen.height
形式为do_en,dm_en,t_en
对应hJH,形式为
定位到生成处
进入函数查看细节
找到给mst赋值的地方,发现其对应MIH的值

追踪MIH,分析其中各参数的生成逻辑
追踪到dd2的值,即对应A2H的生成逻辑
由nj(53, [])生成,固定值
dvc参数涉及vmp的分析,留到之后的章节再讲
由函数EfH生成,形式为0,0,0,0,1,0,0,可写死,分析过程如下
可能为以下几个值中的一个
也可以为0
{
"ver": "Hp13OlgXJ5vsFiL18Vzagl7vDRHRUXBbGRTuAHeQS94=",
"fpt": "-1",
"fpc": "94",
"ajr": "MTQ5OTI3NDk4MA==|18970|79034",
"din": [{
"hz1": 430514
}, {
"dau": 0
}, {
"nap": "Gecko"
}, {
"wih": 932
}, {
"swi": 1920
}, {
"nps": "20030107"
}, {
"xag": 12147
}, {
"wiw": 786
}, {
"ucs": "8894"
}, {
"ran": "0.709011262354"
}, {
"tsd": 0
}, {
"wow": 1920
}, {
"ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0"
}, {
"ibr": 0
}, {
"pha": 0
}, {
"ash": 1040
}, {
"asw": 1920
}, {
"wdr": 0
}, {
"adp": "cpen:0,i1:0,dm:0,cwen:0,non:1,opc:0,fc:0,sc:0,wrc:1,isc:0,vib:1,bat:1,x11:0,x12:1"
}, {
"nal": "zh-CN"
}, {
"npl": 5
}, {
"hal": 874859680808
}, {
"she": 1080
}],
"eem": "do_en,dm_en,t_en",
"ffs": "0,0,0,0,4819,113,0;0,0,0,0,4648,113,0;0,0,0,0,4834,113,0;0,0,0,0,4970,113,0;",
"vev": "",
"inf": "0,0,0,0,4819,113,0;0,0,0,0,4648,113,0;0,0,0,0,4834,113,0;0,0,0,0,4970,113,0;",
"ajt": "0,0",
"kev": "",
"dme": "",
"mev": "",
"doe": "",
"pur": "085K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3g2^5j5h3#2H3L8r3g2Q4x3X3g2U0L8$3@1`.",
"pev": "",
"mst": [{
"kevl": 1
}, {
"mevl": 32
}, {
"tevl": 32
}, {
"devl": 0
}, {
"dmvl": 0
}, {
"pevl": 0
}, {
"tovl": 0
}, {
"delt": 2
}, {
"it": 0
}, {
"sts": 1749719361616
}, {
"fct": -999999
}, {
"dd2": 18718
}, {
"kc": 0
}, {
"mc": 0
}, {
"ww8": 0
}, {
"pc": 0
}, {
"tc": 0
}, {
"ssts": 2
}, {
"tst": 0
}, {
"rval": "-1"
}, {
"rcfp": "-1"
}, {
"nfas": 30261693
}, {
"jsrf": "PiZtE"
}, {
"jsrf1": 92717
}, {
"jsrf2": 74
}, {
"signals": "0"
}, {
"mwd": "0"
}, {
"hea": ""
}, {
"dvc": "adoirodrh7d7dqw7q1vx,13,i+j+e+d+k+h+a+l+c+"
}, {
"srd": "0"
}],
"o9": 0,
"tev": "",
"sde": "0,0,0,0,1,0,0",
"pmo": "",
"dpw": "",
"pac": "",
"per": "6",
"pde": "",
"oev": "",
"if": "",
"fwd": [{
"fmh": ""
}, {
"fmz": ""
}, {
"ssh": "edad0f7f58298c8f37589a10434df532b292237899a9c79d5a5db5d68fe46aeb"
}]
}
{
"ver": "Hp13OlgXJ5vsFiL18Vzagl7vDRHRUXBbGRTuAHeQS94=",
"fpt": "-1",
"fpc": "94",
"ajr": "MTQ5OTI3NDk4MA==|18970|79034",
"din": [{
"hz1": 430514
}, {
"dau": 0
}, {
"nap": "Gecko"
}, {
"wih": 932
}, {
"swi": 1920
}, {
"nps": "20030107"
}, {
"xag": 12147
}, {
"wiw": 786
}, {
"ucs": "8894"
}, {
"ran": "0.709011262354"
}, {
"tsd": 0
}, {
"wow": 1920
}, {
"ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0"
}, {
"ibr": 0
}, {
"pha": 0
}, {
"ash": 1040
}, {
"asw": 1920
}, {
"wdr": 0
}, {
"adp": "cpen:0,i1:0,dm:0,cwen:0,non:1,opc:0,fc:0,sc:0,wrc:1,isc:0,vib:1,bat:1,x11:0,x12:1"
}, {
"nal": "zh-CN"
}, {
"npl": 5
}, {
"hal": 874859680808
}, {
"she": 1080
}],
"eem": "do_en,dm_en,t_en",
"ffs": "0,0,0,0,4819,113,0;0,0,0,0,4648,113,0;0,0,0,0,4834,113,0;0,0,0,0,4970,113,0;",
"vev": "",
"inf": "0,0,0,0,4819,113,0;0,0,0,0,4648,113,0;0,0,0,0,4834,113,0;0,0,0,0,4970,113,0;",
"ajt": "0,0",
"kev": "",
"dme": "",
"mev": "",
"doe": "",
"pur": "5baK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3g2^5j5h3#2H3L8r3g2Q4x3X3g2U0L8$3@1`.",
"pev": "",
"mst": [{
"kevl": 1
}, {
"mevl": 32
}, {
"tevl": 32
}, {
"devl": 0
}, {
"dmvl": 0
}, {
"pevl": 0
}, {
"tovl": 0
}, {
"delt": 2
}, {
"it": 0
}, {
"sts": 1749719361616
}, {
"fct": -999999
}, {
"dd2": 18718
}, {
"kc": 0
}, {
"mc": 0
}, {
"ww8": 0
}, {
"pc": 0
}, {
"tc": 0
}, {
"ssts": 2
}, {
"tst": 0
}, {
"rval": "-1"
}, {
"rcfp": "-1"
}, {
"nfas": 30261693
}, {
"jsrf": "PiZtE"
}, {
"jsrf1": 92717
}, {
"jsrf2": 74
}, {
"signals": "0"
}, {
"mwd": "0"
}, {
"hea": ""
}, {
"dvc": "adoirodrh7d7dqw7q1vx,13,i+j+e+d+k+h+a+l+c+"
}, {
"srd": "0"
}],
"o9": 0,
"tev": "",
"sde": "0,0,0,0,1,0,0",
"pmo": "",
"dpw": "",
"pac": "",
"per": "6",
"pde": "",
"oev": "",
"if": "",
"fwd": [{
"fmh": ""
}, {
"fmz": ""
}, {
"ssh": "edad0f7f58298c8f37589a10434df532b292237899a9c79d5a5db5d68fe46aeb"
}]
}
var OCH = (ZI(typeof CP()["Fx"], "undefined") ? CP()["E"].apply(null, [569, 86, 259, 81]) : "")[ZI(typeof Sh()["mM"], 'undefined') ? Sh()["ls"](986, 119) : "concat"](FK()["qH"](1780, 58));
var OCH = (ZI(typeof CP()["Fx"], "undefined") ? CP()["E"].apply(null, [569, 86, 259, 81]) : "")[ZI(typeof Sh()["mM"], 'undefined') ? Sh()["ls"](986, 119) : "concat"](FK()["qH"](1780, 58));
var OCH = ""["concat"](FK()["qH"](1780, 58));
var OCH = ""["concat"](FK()["qH"](1780, 58));
function n1H() {
var LYH = ['N', 'mM', 'Z7', 'gx', 'XM', 'ls', 'XG', 'DL', 'gG', 'tC', 'Tl', 'EM', 'N5', 'ZM', 'NM', 'Ls', 'fC', 'E', 'U1', 'Os', 'j1', 'EV', 'Fx', 'Rs', 'Dl', 'UE', 'gL', 'Y', 'kG', 'C7', 'E5', 'Q', 'Gl', 'jx', 'IM', 'nV', 'Dx', 'U', 'W7', 'qH', 'nL', 'Z5', 'sl', 'nE', 'PG', 'AH', 'ZE', 'VC', 'Il', 'bG', 'z5', 'kU', 'Tx', 'k3', 'Wx', 'H', 'BE', 'ME', 'd7', 'fE', 'bs', 'Hx', 'O7', 'dE', 'JM', 'Y1', 'qE', 'lM', 'bx', 'jE', 'hG', 'Cs', 'cx', 'Gs', 'I5', 'hE', 'VM', 'B5', 'BR', 'lQ', 'Ox', 'vs', 'FE', 'V3', 'Ks', 'TM', 'pE', 'C3', 'WQ', 'z3', 'bU', 'RU', 'vU', 'HU', 'XU', 'bH', 'HC', 'Ns', 'Jl', 'J3', 'vC', 'xQ', 'S1', 'zH', 'EQ', 'X', 'LH', 'OE', 'U7', 'Js', 'SQ', 'QU', 'b5', 'E3', 'Bl', 'Zl', 'jR', 'YV', 'FC', 'Wl', 'pU', 'A7', 'VR', 'kH', 'SC', 'VV', 'NR', 'Ss', 'rE', 'XE', 'm1', 'cs', 'HL', 'rU', 'jV', 'AR', 'OG', 'SE', 'rl', 'hC', 'IE', 'GU', 'pl', 'LQ', 'Kx', 'FL', 'cL', 'XC', 'SL', 'FV', 'hV', 'LE', 'EE', 'Z', 'WV', 'VG', 'AV', 'rH', 'xR', 'l7', 'BC', 'kC', 'UH', 'DH', 'As', 'rQ', 'x5', 'T7', 'dM', 'hU', 'sL', 'U3', 'bM', 'BM', 'jG', 'fU', 'QG', 'PH', 'bL', 'sC', 'pV', 'LG', 'vH', 'BU', 'ss', 'W3', 'GM', 't3', 'kL', 'cE', 'qL', 'hs', 'BQ', 'hM', 's5', 'HM', 'gs', 'YC', 'OU', 'cH', 'zC', 'Zs', 'CM', 'AM', 'WL', 'v5', 'V7', 'mR', 'IG', 'v', 'LU', 'ZU', 'Ul', 'Ex', 'XQ', 'zV', 'VL', 'ks', 'gE', 'd5', 'TU', 'g7', 'CC', 'Y3', 'QR', 'PU', 'FU', 'm5'];
n1H = function () {
return LYH;
};
return LYH;
}
function n1H() {
var LYH = ['N', 'mM', 'Z7', 'gx', 'XM', 'ls', 'XG', 'DL', 'gG', 'tC', 'Tl', 'EM', 'N5', 'ZM', 'NM', 'Ls', 'fC', 'E', 'U1', 'Os', 'j1', 'EV', 'Fx', 'Rs', 'Dl', 'UE', 'gL', 'Y', 'kG', 'C7', 'E5', 'Q', 'Gl', 'jx', 'IM', 'nV', 'Dx', 'U', 'W7', 'qH', 'nL', 'Z5', 'sl', 'nE', 'PG', 'AH', 'ZE', 'VC', 'Il', 'bG', 'z5', 'kU', 'Tx', 'k3', 'Wx', 'H', 'BE', 'ME', 'd7', 'fE', 'bs', 'Hx', 'O7', 'dE', 'JM', 'Y1', 'qE', 'lM', 'bx', 'jE', 'hG', 'Cs', 'cx', 'Gs', 'I5', 'hE', 'VM', 'B5', 'BR', 'lQ', 'Ox', 'vs', 'FE', 'V3', 'Ks', 'TM', 'pE', 'C3', 'WQ', 'z3', 'bU', 'RU', 'vU', 'HU', 'XU', 'bH', 'HC', 'Ns', 'Jl', 'J3', 'vC', 'xQ', 'S1', 'zH', 'EQ', 'X', 'LH', 'OE', 'U7', 'Js', 'SQ', 'QU', 'b5', 'E3', 'Bl', 'Zl', 'jR', 'YV', 'FC', 'Wl', 'pU', 'A7', 'VR', 'kH', 'SC', 'VV', 'NR', 'Ss', 'rE', 'XE', 'm1', 'cs', 'HL', 'rU', 'jV', 'AR', 'OG', 'SE', 'rl', 'hC', 'IE', 'GU', 'pl', 'LQ', 'Kx', 'FL', 'cL', 'XC', 'SL', 'FV', 'hV', 'LE', 'EE', 'Z', 'WV', 'VG', 'AV', 'rH', 'xR', 'l7', 'BC', 'kC', 'UH', 'DH', 'As', 'rQ', 'x5', 'T7', 'dM', 'hU', 'sL', 'U3', 'bM', 'BM', 'jG', 'fU', 'QG', 'PH', 'bL', 'sC', 'pV', 'LG', 'vH', 'BU', 'ss', 'W3', 'GM', 't3', 'kL', 'cE', 'qL', 'hs', 'BQ', 'hM', 's5', 'HM', 'gs', 'YC', 'OU', 'cH', 'zC', 'Zs', 'CM', 'AM', 'WL', 'v5', 'V7', 'mR', 'IG', 'v', 'LU', 'ZU', 'Ul', 'Ex', 'XQ', 'zV', 'VL', 'ks', 'gE', 'd5', 'TU', 'g7', 'CC', 'Y3', 'QR', 'PU', 'FU', 'm5'];
n1H = function () {
return LYH;
};
return LYH;
}
Xk = function (xN, vT) {
return Ud.apply(this, [34, arguments]);
};
Xk = function (xN, vT) {
return Ud.apply(this, [34, arguments]);
};
var L3H = function () {
if (B0(1)) {} else if (B0({})) {} else if (B0([])) {} else if (B0([])) {} else if (B0(B0(0))) {} else if (B0([])) {} else if (B0(B0(0))) {} else if (B0(1)) {} else if (B0([])) {} else if (B0({})) {} else if (B0([])) {} else if (B0([])) {} else if (B0({})) {} else if (B0([])) {} else if (B0([])) {} else if (B0(B0(0))) {} else if (B0({})) {} else if (B0({})) {} else if (B0([])) {} else if (B0(1)) {} else if (B0({})) {} else if (B0([])) {} else if (B0(1)) {} else if (B0(B0([]))) {
return function Q3H(p7H) {
w2.push(941);
var RGH = p7H["totVel"] || jS();
var d3H = jS();
var W1H = [p5["btoa"](Ib(d3H, RGH)), d3H, RGH];
var LlH;
return LlH = W1H["join"]("|"),
w2.pop(),
LlH;
};
} else {}
};
var L3H = function () {
if (B0(1)) {} else if (B0({})) {} else if (B0([])) {} else if (B0([])) {} else if (B0(B0(0))) {} else if (B0([])) {} else if (B0(B0(0))) {} else if (B0(1)) {} else if (B0([])) {} else if (B0({})) {} else if (B0([])) {} else if (B0([])) {} else if (B0({})) {} else if (B0([])) {} else if (B0([])) {} else if (B0(B0(0))) {} else if (B0({})) {} else if (B0({})) {} else if (B0([])) {} else if (B0(1)) {} else if (B0({})) {} else if (B0([])) {} else if (B0(1)) {} else if (B0(B0([]))) {
return function Q3H(p7H) {
w2.push(941);
[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!
最后于 2025-8-1 09:46
被LotusRain编辑
,原因: 内容补充