【JS 逆向百例】猿人学系列 web 比赛第二题:js 混淆 - 动态 cookie,详细剖析
字数 1041 2025-08-11 08:35:55
JS逆向实战:猿人学Web比赛第二题 - 动态Cookie与JS混淆解析
逆向目标
目标网站:猿人学 - 反混淆刷题平台Web第二题
目标URL:https://match.yuanrenxue.com/match/2
API接口:https://match.yuanrenxue.com/api/match/2
任务要求:提取全部5页发布日热度的值,计算所有值的加和
逆向参数
关键逆向参数为Cookie中的m参数,格式示例:
0ef478cf61e0749d7444c7997c917679|1663213224000
逆向过程详解
1. 初步分析
-
页面分析:
- 页面数据通过XHR异步加载
- 翻页时提示"cookie失效,正在重置页面",说明cookie有时效性且会校验
-
关键发现:
- Cookie中的
m参数是动态生成的加密值 m参数由三部分组成:加密字符串|固定值|时间戳
- Cookie中的
2. 定位加密位置
使用Hook技术定位m参数的生成位置:
// Hook代码示例
(function() {
'use strict';
var cookieTemp = '';
Object.defineProperty(document, 'cookie', {
set: function(val) {
if (val.indexOf('m') != -1) {
debugger;
}
console.log('Hook捕获到cookie设置->', val);
cookieTemp = val;
return val;
},
get: function() {
return cookieTemp;
}
});
})();
成功定位到加密代码位置:
document[$dbsm_0x42c3(qqLQOq, iOiqII) + $dbsm_0x42c3(q1IoqQ, QQlLlq)] = _0x5500bb['\x4e\x74\x44' + '\x72\x43'](...);
3. 代码简化与分析
原始加密代码可简化为:
_0x313b78(_0x160e3a) + lOo0QQ + _0x160e3a
其中:
_0x160e3a:当前时间戳lOo0QQ:固定字符串"|"_0x313b78:核心加密函数
4. 核心加密函数分析
_0x313b78函数结构:
function _0x313b78(_0x575158, _0x1fa91a, _0x1cf5de) {
// 复杂加密逻辑
// 最终返回加密后的字符串
}
5. 代码扣取与调试
关键步骤:
-
补全依赖:
- 补全
_0x5500bb、_0x434ddb等对象定义 - 补全
$dbsm_0x42c3字符串解密函数 - 补全移位自执行函数(位于大数组和字符串解密函数之间)
- 补全
-
解决无限循环问题:
- 代码中存在反格式化检测,会将格式化后的代码引入无限循环
- 解决方案:将关键函数体压缩为一行,避免被检测
示例修复:
'removeCookie': function() {return 'dev';}, -
环境补全:
// Node.js环境补全 var window = global; window.navigator = {}; window.history = {}; // 替换可能导致问题的console.log var result = console.log; -
性能优化:
- 移除或优化包含大量循环的检测代码(如1100000次的for循环)
6. 完整解决方案
JavaScript部分(关键代码):
var window = global;
window.navigator = {};
var result = console.log;
// 补全所有依赖的函数和对象定义
// ...
function _0x313b78(_0x575158, _0x1fa91a, _0x1cf5de) {
// 核心加密逻辑
// ...
}
function getCookieM() {
var _0x160e3a = Date.parse(new Date());
var m = _0x313b78(_0x160e3a) + "|" + _0x160e3a;
return m;
}
Python调用部分:
import execjs
import requests
def get_cookie_m():
heat_total = 0
for page_num in range(1, 6):
with open('yrx2.js', 'r', encoding='utf-8') as f:
encrypt = f.read()
cookie_m = execjs.compile(encrypt).call('getCookieM')
headers = {
"user-agent": "yuanrenxue,project",
}
cookies = {
"sessionid": "your_sessionid",
"m": cookie_m
}
url = f"https://match.yuanrenxue.com/api/match/2?page={page_num}"
response = requests.get(url, headers=headers, cookies=cookies)
for item in response.json()['data']:
heat_total += int(item['value'])
print(heat_total)
if __name__ == '__main__':
get_cookie_m()
技术要点总结
-
混淆特征识别:
- 典型的OB混淆,包含三部分:大数组、移位自执行函数、字符串解密函数
- 动态Cookie生成机制
-
调试技巧:
- 使用Hook技术快速定位关键代码
- 浏览器Snippets调试复杂JS代码
- 解决无限debugger和反格式化检测
-
扣代码原则:
- 完整补全依赖链
- 注意环境依赖(如浏览器对象)
- 处理反调试和反格式化机制
-
性能考量:
- 优化或移除大量循环
- 合理处理内存消耗问题
资源链接
通过本案例,可以深入掌握JS混淆逆向、动态Cookie生成机制分析和复杂JS代码扣取等高级逆向技术。