T5 柳暗花明又一墙

一:抓包

F12查看请求,发现直接被断住,有无数个debugger

image-20260504133416205

本文直接使用本地替换的办法,直接将所有的debugger删除,删除后可以看到debugger已经过了,但是会提示检测到反调试

image-20260504133726189

image-20260504133754853

可以看到是检测debugger,直接将!_first50_check["includes"]("deb")修改为恒为false,不执行报错操作

image-20260504133909280image-20260504133937767

页面正常显示同时也看到了加密参数signature

二:加密参数分析

ob1_challenge.js搜索signature,可以看到实际const signature = O0o0O0O0()

image-20260504134116813

image-20260504134146211

调用也正常

三:扣代码

直接扣出并调用,发现报错

image-20260504140956259

结合网站能找到实际的函数

image-20260504141042132

image-20260504141119196

直接从var encode_arr全部扣下

如下结构

image-20260504141218457

image-20260504141312484

补上对应的缺少的环境

image-20260504141345955

image-20260504141400526image-20260504141422803

如果出现atob和btoa的报错,分别改成

1
2
Buffer.from(str, 'base64').toString('ascii')
Buffer.from(str, 'binary').toString('base64')

调用成功。

真的成功了吗?请求请求接口报错,显示签名验证失败,第一页成功的原因是没有检查,请求url为init

image-20260505174447163

image-20260505174500359

4、错误分析-补环境

遇到此种情况一般就是使用补环境的方式来解决了(浏览器生成的能行,python生成的不行)

加上环境检测代码

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
//观察框架
!(function () {
var console_log = console.log
watch = function (obj, name) {
return new Proxy(obj, {
get(target, p, receiver) {
// 过滤没用的信息,不进行打印
if (name !== 'contentWindow' && p === "Math" || p === "JSON" || p === "RegExp" || p === "atob" || p === "parseInt" || p === "String" || p === "Symbol" || p === "Proxy" || p === "Promise" || p === "Array" || p === "isNaN" || p === "encodeURI" || p === "Uint8Array" || p.toString().indexOf("Symbol(Symbol.") != -1 || p.toString().indexOf("Symbol(nodejs") != -1) {
var val = Reflect.get(...arguments);
return val
}
else {
var val = Reflect.get(...arguments);
if (typeof val === 'function') {
console_log(`取值: ${name}.${p} => function`);
} else {
console_log(`取值: ${name}.${p} => ${val}`);
}
return val
}
},
set(target, p, value, receiver) {
var val = Reflect.set(...arguments)
if (typeof value === 'function') {
console_log(`设置值: ${name}.${p} => function`,);
} else {
console_log(`设置值: ${name}.${p} => ${value}`);
}
return val
},
has(target, key) {
// 在检查属性存在性时输出一条消息
console_log(`检查属性存在性: ${name}.${key.toString()}`);
return key in target;
},
ownKeys(target) {
console_log(`获取自有属性:${name}`)
if (name === 'contentWindow_navigator') {
return watch([], 'contentWindow_navigator自有属性')
}
return Reflect.ownKeys(target)
}
})
}
})();

// 补环境框架
function getEnvs(proxyObjs) {
for (let i = 0; i < proxyObjs.length; i++) {
const handler = '{\n' +
' get: function(target, property, receiver) {\n' +
' console.log("方法:", "get ", "对象:", ' +
'"' + proxyObjs[i] + '" ,' +
'" 属性:", property, ' +
'" 属性类型:", ' + 'typeof property, ' +
// '" 属性值:", ' + 'target[property], ' +
'" 属性值类型:", typeof target[property]);\n' +
// 'if (typeof target[property] == "undefined"){debugger}' +
' return target[property];\n' +
' },\n' +
' set: function(target, property, value, receiver) {\n' +
' console.log("方法:", "set ", "对象:", ' +
'"' + proxyObjs[i] + '" ,' +
'" 属性:", property, ' +
'" 属性类型:", ' + 'typeof property, ' +
// '" 属性值:", ' + 'target[property], ' +
'" 属性值类型:", typeof target[property]);\n' +
' return Reflect.set(...arguments);\n' +
' }\n' +
'}';
eval(`try {
${proxyObjs[i]};
${proxyObjs[i]} = new Proxy(${proxyObjs[i]}, ${handler});
} catch (e) {
${proxyObjs[i]} = {};
${proxyObjs[i]} = new Proxy(${proxyObjs[i]}, ${handler});
}`);
}
}

proxyObjs = ['window', 'location', 'document', 'navigator', 'history', 'screen', 'localStorage']
getEnvs(proxyObjs);

加上后执行直接返回false

image-20260505175216916

删除掉document后执行又成功了

image-20260505175331801

image-20260505175339452

应该是检测了document,直接全局搜索document

image-20260505175525658

可以看到当前的位置比较可疑,直接本地和浏览器对比

浏览器执行的值为false

image-20260505175638222

本地执行值为true

image-20260505175842085

直接注释掉再次执行,能拿到值

image-20260505175941802

接下来就是补环境,搜索哪些是未定义的

image-20260505180034691

能看到是document的createElement,一点一点补,最后的补完是这样的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
document = {
createElement: function (args){
console.log("调用了createElement--->", args)
if (args === "canvas"){
return watch({
getContext: function (name){
console.log("调用了getContext", name)
if (name === "2d"){
if (this.canvas_name === '' || this.canvas_name === '2d') {
return watch({
fillRect: function (){},
fillText: function (){}
}, '2d')
}
}
},
canvas_name: ''
}, 'canvas')
}
}
}

image-20260505180258304

调用成功

更多内容也在公众号更新:码字的秃猴

tuhou