由于本篇完整文章长达1.4w字,所以将分成三篇文章发布
上一篇:js逆向案例-cookie反爬之akamai_2.0-上
本篇:文章为目录五到目录八内容
3.0视频操作见b站时一十一姐
虽然大多数网站已经更新到3.0了,但是算法函数差不多,且存在2.0的cookie可以过3.0,那么我们先分析2.0的逆向流程,有时间再更新3.0的流程
本文仅供学习交流,选择了风控较低的网站逆向学习
五、60位数组-100附近之索引1研究
1、先研究wsT是怎么来的,其中var wsT = YNT(),我们多次执行,发现当中有随机值在变,其它参数在同一个浏览器下是一致的
2、YNT()函数,我进行了手动解混淆还原如下,大家看图理解这段函数代码的逻辑,图中代码concat的逗号漏了几个参数,具体看步骤7的代码补全了
return BLT = ""["concat"](ua, ',uaend,')["concat"](tU(mz, []), ",")['concat'](c9T, ",")["concat"](JdT, ",")["concat"](gMT, ",")["concat"]( w9T, ",")["concat"](ZMT, ",")["concat"](EvT, ",")["concat"](xUT, ",")["concat"](IvT, ",")["concat"](hIT, ",")["concat"]( TsT, ",")["concat"](L2T, ",")["concat"](qg, ",")["concat"](b7, ",")["concat"](NKT, ",")["concat"](gCT, ",")["concat"]( cXT, ",")["concat"](tU(HF, []), ',')["concat"](Q3, ",")["concat"](XMT, ",")["concat"](qFT, ",")["concat"](UCT, ',')['concat'](jPT, ",loc:"), BLT;
- 用户ua处理: useragent转换为数字
- 触摸支持检测:检测浏览器是否支持触摸事件
- 屏幕属性获取:获取与屏幕相关的各种属性,例如屏幕的可用宽度和高度、屏幕的宽度和高度、浏览器窗口的内部宽度和高度,以及文档元素的宽度和高度。如果无法获取这些值,则将它们设置为
-1
- 时间戳处理:页面加载开始的时间戳/2 , 以及其它随机数
- 自动化检测:如
_phantom
、webdriver
和domAutomation
,这些通常用于识别浏览器是否在自动化环境中运行
3、对YNT()函数进一步还原处理,大致逻辑如下,下面这段代码可以直接在控制台输出, 详细步骤大家可以参考这个代码扣逻辑
4、自定义一些可能变的初始指纹变量
5、YNT()函数则修改如下,有些写死的变量,是因为检测固定值,所以直接写死了
六、60位数组-105与-102附近之索引3
1、bnT怎么来的,bNT = AmT() 所以直接研究AmT()函数
2、AmT()函数手动解混淆如下,其中这个是取的标签参数window["document"]['getElementsByTagName']("input");
3、在console界面提取input_list标签
// 将HTMLCollection转换为数组
let inputs = Array.from(window["document"]["getElementsByTagName"]("input"));
// 创建一个空数组来保存input元素的所有属性
let inputListWithAttributes = [];
// 遍历input数组
inputs.forEach(function(input) {
// 创建一个对象来保存当前input的所有属性
let inputAttributes = {};
// 遍历input元素的所有属性
for (let i = 0; i < input.attributes.length; i++) {
// 获取属性名和属性值
let attrName = input.attributes[i].name;
let attrValue = input.attributes[i].value;
// 将属性名和属性值添加到inputAttributes对象中
inputAttributes[attrName] = attrValue;
}
// 将inputAttributes对象添加到inputListWithAttributes数组中
inputListWithAttributes.push(inputAttributes);
});
// 将inputListWithAttributes数组转换为JSON字符串
let inputListWithAttributesJSON = JSON.stringify(inputListWithAttributes, null, 2); // 使用2个空格缩进JSON字符串
// 打印出JSON字符串,以便可以在控制台中查看和复制
console.log(inputListWithAttributesJSON);
copy(inputListWithAttributesJSON)
4、验证输出结果一致、其中索引-105和-102附近结果一致
5、python代码这里改一下,提前获取input_list标签
七、60位数组-115附近研究
1、我们搜索到q3等于如下的代码
2、手动解混淆还原下, 是一个34位数组拼接而得,我们逐步研究这个34位数组
3、数组前7个是固定值,其余的对比了下也是固定值,也一同写死了,其它剩余的参数我们再继续研究下怎么来的
4、其中dPT是时间差
var dPT = v8() - Xm['window'].bmak['startTs'];
5、TzT也与时间相关
var qAT = VZ['SXEz5C']();
varIvT = window['parseInt'](window.bmak['startTs'] /( 2016 * 2016), 10);
varTzT = window['parseInt'](IvT/ 23, 10)
6、JfT也与时间相关
var JfT = window['parseInt'](TzT / 6, 10);
7、JPT也与时间相关
var JPT = v8() - window.bmak['startTs'];
8、pg传入的是abck的cookie值
9、k7还是与时间戳相关
var k7 = FO(window.bmak['startTs']);
10、至此q3研究完成
八、60位数组-90附近研究
1、如下是-90对应的值生成的位置
2、手动解混淆如下Dx()(vG(CP, ['startTimestamp',window.bmak['startTs'], 'deviceData' , k6S, 'mouseMoveData', N2S, 'totVel', mJS, 'deltaTimestamp', CES] )
// Dx()(vG(CP, [hp()[EY(wc)](rO, cb, BO, rL), Wm[EG()[pI(OV)](tT, qC)].bmak[EG()[pI(Q8)].apply(null, [lV, SC])], hc(typeof EG()[pI(TR)], 'undefined') ? EG()[pI(GZ)].apply(null, [gD, bB]) : EG()[pI(hC)].apply(null, [wZ, Dq]), k6S, EG()[pI(YG)](Tf, zc), N2S, hc(typeof jL()[TI(QY)], 'undefined') ? jL()[TI(hL)].apply(null, [Yp, tI]) : jL()[TI(NT)].apply(null, [Mr, r3]), mJS, hp()[EY(pG)].call(null, CB, Pp, vs, DC), CES]));// ['startTimestamp',window.bmak['startTs'], 'deviceData' , k6S, 'mouseMoveData', N2S, 'totVel', mJS, 'deltaTimestamp', CES]
3、而vG执行如下,其实就是CP函数
4、CP函数逻辑如下,其中传入的参数Dz是步骤2的那10个数组
5、步骤2的Dx函数手动解混淆如下
6、最终只需要如下即可,其中CES可以搜索得到是当前时间戳差值,
var CES = Ps(KL(), Wm[EG()[pI(OV)](tT, qC)].bmak[EG()[pI(Q8)].call(null, lV, SC)]);var CES = window["Date"]["now"]() - window.bmak['startTs']
原文始发于微信公众号(逆向OneByOne):js逆向案例-sensor_data反爬之akamai_2.0-中
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论