猿人学第9题js混淆-动态cookie2
@ -16,7 +16,7 @@ document[$b('\x30\x78\x31\x33\x31', '\x4d\x45\x47\x72') + $b('\x30\x78\x34\x37',
|
||||
|
||||
修改后
|
||||
```javascript
|
||||
document['cookie'] = 'm=' + '2' + res + '; path=/';
|
||||
document['cookie'] = 'm=' + (m - 1)['toString']() + res + '; path=/';
|
||||
```
|
||||
|
||||

|
||||
@ -28,14 +28,46 @@ document['cookie'] = 'm=' + '2' + res + '; path=/';
|
||||

|
||||
|
||||
```javascript
|
||||
res = f[$b('\x30\x78\x31\x33\x65', '\x25\x25\x41\x48') + '\x5a\x79'](f[$b('\x30\x78\x34\x32', '\x54\x35\x5b\x4f') + '\x41\x42'](decrypt, '1693274196'), '\x72');
|
||||
for (var m = 0x1; f[$b('\x30\x78\x31\x37\x36', '\x77\x39\x24\x39') + '\x69\x59'](m, 5); m++) {
|
||||
if (f['\x4e\x6c\x53' + '\x6e\x78'](f['\x64\x48\x6d' + '\x56\x6d'], f[$b('\x30\x78\x31\x30\x64', '\x62\x5a\x32\x76') + '\x56\x6d'])) {
|
||||
res = f[$b('\x30\x78\x31\x35\x61', '\x62\x5a\x32\x76') + '\x49\x71'](decrypt('1693299477'), '\x72');
|
||||
} else {
|
||||
var p = fn[$b('\x30\x78\x66\x61', '\x6c\x33\x5a\x57') + '\x6c\x79'](context, arguments);
|
||||
fn = null;
|
||||
return p;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
修改后
|
||||
```javascript
|
||||
res = decrypt('1693276453') + 'r';
|
||||
for (var m = 1; m <= 5; m++) {
|
||||
res = decrypt('1693276453') + 'r';
|
||||
}
|
||||
```
|
||||
|
||||
这里多刷新几次,你会发现for循环的次数是不固定的,通过后端返回,后期编写爬虫代码时就需要将`m`解析下来。
|
||||
|
||||
第一次返回的是5
|
||||
|
||||

|
||||
|
||||
第二次返回的是3
|
||||
|
||||

|
||||
|
||||
完整的cookie生成代码
|
||||
|
||||
```javascript
|
||||
for (var m = 1; m<=3; m++) {
|
||||
res = decrypt('1693300807') + 'r';
|
||||
}
|
||||
|
||||
document['cookie'] = 'm=' + (m - 1)['toString']() + res + '; path=/';
|
||||
```
|
||||
|
||||
## `decryp`是怎么来的
|
||||
|
||||
通过控制台可以看出函数`decrypt`是udc.js文件生成的。
|
||||
|
||||
继续进入,打上断点,可以看到这样一段代码
|
||||
@ -54,7 +86,7 @@ function _0x4f6d79(_0x50f9fa) {
|
||||
|
||||

|
||||
|
||||
目前还原后的代码就是
|
||||
还原后的代码就是
|
||||
```javascript
|
||||
function decrypt(_0x50f9fa) {
|
||||
const _0x506402 = 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5GVku07yXCndaMS1evPIPyWwhbdWMVRqL4qg4OsKbzyTGmV4YkG8H0hwwrFLuPhqC5tL136aaizuL/lN5DRRbePct6syILOLLCBJ5J5rQyGr00l1zQvdNKYp4tT5EFlqw8tlPkibcsd5Ecc8sTYa77HxNeIa6DRuObC5H9t85ALJyDVZC3Y4ES/u61Q7LDnB3kG9MnXJsJiQxm1pLkE7Zfxy29d5JaXbbfwhCDSjE4+dUQoq2MVIt2qVjZSo5Hd/bAFGU1Lmc7GkFeLiLjNTOfECF52ms/dks92Wx/glfRuK4h/fcxtGB4Q2VXu5k68e/2uojs6jnFsMKVe+FVUDkQIDAQAB';
|
||||
@ -70,7 +102,7 @@ document['cookie'] = 'm=' + '2' + res + '; path=/';
|
||||
console.log(document);
|
||||
```
|
||||
|
||||
## 找出`JSEncrypt`加密生成逻辑
|
||||
## `JSEncrypt`加密生成逻辑
|
||||
|
||||
先将`udc.js`中的代码,用`v_jstools`进行16进制转成10进制,全局搜索就找到`JSEncrypt`赋值点,
|
||||
|
||||
@ -171,8 +203,93 @@ if (_0x41a2bf[_0x56ae("0xe73", "XiWX")](("" + _0x457d14 / _0x457d14)[_0x41a2bf[_
|
||||
修改后
|
||||
```javascript
|
||||
if (_0x41a2bf['LRGDx'](("" + _0x457d14 / _0x457d14)['length'], 1) || (_0x457d14 % 20) === 0) {
|
||||
|
||||
'debugger'
|
||||
} else {
|
||||
|
||||
'debugger'
|
||||
}
|
||||
```
|
||||
```
|
||||
|
||||
到这里就可以顺利调试了
|
||||
|
||||
## 去除浏览器环境检测代码
|
||||
|
||||
**window环境检测**
|
||||
|
||||
第一处:
|
||||
|
||||

|
||||
|
||||
第二处:
|
||||
|
||||

|
||||
|
||||
第三处:
|
||||
|
||||

|
||||
|
||||
**删除多余代码**
|
||||
|
||||

|
||||
|
||||
**atob检测**
|
||||
|
||||
当你在本地运行时,没有再出现报错信息,但加密的结果值还是不对。这里就要用到`js proxy`代理,通过代理打印检测点。
|
||||
|
||||
```javascript
|
||||
window = this;
|
||||
navigator = {};
|
||||
location = {};
|
||||
document = {};
|
||||
|
||||
// 框架代理功能
|
||||
catvm = {};
|
||||
catvm.proxy = function (o) {
|
||||
return new Proxy(o, {
|
||||
set(target, key, value) {
|
||||
console.log('set-->', target, key, value);
|
||||
return Reflect.set(...arguments);
|
||||
},
|
||||
get(target, key, receiver) {
|
||||
console.log('get-->', target, key, target[key]);
|
||||
return target[key];
|
||||
},
|
||||
deleteProperty: function (target, key) {
|
||||
console.log('delete-->', target, key);
|
||||
return true
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
window = catvm.proxy(window);
|
||||
navigator = catvm.proxy(navigator);
|
||||
location = catvm.proxy(location);
|
||||
document = catvm.proxy(document);
|
||||
```
|
||||
|
||||
打印信息:
|
||||
|
||||
get--> {} atob undefined
|
||||
set--> {} atob [Function (anonymous)]
|
||||
get--> { atob: [Function (anonymous)] } crypto undefined
|
||||
|
||||
`atob undefined`对应的位置:
|
||||
|
||||

|
||||
|
||||
修改成:
|
||||
|
||||
```javascript
|
||||
_0x4f1af6.atob
|
||||
```
|
||||
|
||||
`crypto undefined`对应的位置:
|
||||
|
||||

|
||||
|
||||
直接删除即可。
|
||||
|
||||
## python代码运行
|
||||
|
||||
最后爬虫实现
|
||||
|
||||

|
BIN
猿人学Web端爬虫攻防刷题平台/猿人学第9题js混淆-动态cookie2/img/10.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
猿人学Web端爬虫攻防刷题平台/猿人学第9题js混淆-动态cookie2/img/11.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
猿人学Web端爬虫攻防刷题平台/猿人学第9题js混淆-动态cookie2/img/12.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
猿人学Web端爬虫攻防刷题平台/猿人学第9题js混淆-动态cookie2/img/13.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
猿人学Web端爬虫攻防刷题平台/猿人学第9题js混淆-动态cookie2/img/14.png
Normal file
After Width: | Height: | Size: 70 KiB |
BIN
猿人学Web端爬虫攻防刷题平台/猿人学第9题js混淆-动态cookie2/img/15.png
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
猿人学Web端爬虫攻防刷题平台/猿人学第9题js混淆-动态cookie2/img/16.png
Normal file
After Width: | Height: | Size: 31 KiB |
BIN
猿人学Web端爬虫攻防刷题平台/猿人学第9题js混淆-动态cookie2/img/9.png
Normal file
After Width: | Height: | Size: 26 KiB |
@ -17,36 +17,40 @@ class 实例1(object):
|
||||
'Cookie': 'sessionid=t9dlfwn9s4ed4z1w1sktxg3k55dc3ko6'
|
||||
}
|
||||
response = requests.request("GET", url, headers=headers, data=payload)
|
||||
try:
|
||||
m_num = re.findall(r'\(m,([0-9]{1})\);m\+\+\)', response.text)[0]
|
||||
except Exception as e:
|
||||
m_num = re.findall(r'm<=([0-9]{1});m\+\+\)', response.text)[0]
|
||||
time_str = re.findall(r'decrypt.*?([0-9]{10})', response.text)[0]
|
||||
return time_str
|
||||
return time_str, m_num
|
||||
|
||||
def get_sign(self, date_time):
|
||||
def get_sign(self, date_time, m_num):
|
||||
data = {
|
||||
'sign': str(date_time)
|
||||
'sign': str(date_time),
|
||||
'm_num': str(m_num)
|
||||
}
|
||||
req = requests.post(self.sign_url, data=data)
|
||||
sign = req.text
|
||||
return sign
|
||||
|
||||
def get_task(self, i, time_str):
|
||||
m = self.get_sign(time_str)
|
||||
print(m)
|
||||
def get_task(self, i, time_str, m_num):
|
||||
m = self.get_sign(time_str, m_num) + '; path=/'
|
||||
url = f"https://match.yuanrenxue.cn/api/match/9?page={i}"
|
||||
Headers = {
|
||||
"User-Agent": "yuanrenxue.project",
|
||||
'Cookie': f'm={m}; sessionid=t9dlfwn9s4ed4z1w1sktxg3k55dc3ko6'
|
||||
'Cookie': f'{m}; sessionid=t9dlfwn9s4ed4z1w1sktxg3k55dc3ko6'
|
||||
}
|
||||
req = requests.get(url, headers=Headers)
|
||||
return req.text
|
||||
|
||||
def run(self):
|
||||
time_str = self.get_decrypt()
|
||||
for i in range(2, 6):
|
||||
res_dict = json.loads(self.get_task(i, time_str))
|
||||
for i in range(1, 6):
|
||||
time_str, m_num = self.get_decrypt()
|
||||
res_dict = json.loads(self.get_task(i, time_str, m_num))
|
||||
print(res_dict)
|
||||
for j in res_dict.get('data'):
|
||||
self.sum_value += j.get('value')
|
||||
print(self.sum_value)
|
||||
print(self.sum_value / 50)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -8,8 +8,9 @@ app.use(bodyParser());
|
||||
app.post('/get_sign', function (req, res) {
|
||||
let result = req.body;
|
||||
let sign = result.sign;
|
||||
let m_num = result.m_num;
|
||||
console.log(sign);
|
||||
result = encryption.get_m(sign);
|
||||
result = encryption.get_m(sign, m_num);
|
||||
res.send(result.toString());
|
||||
});
|
||||
|
||||
|