目录
- 调试干扰
- 参数逆向
调试干扰
打开开发者工具,首先会进入 setInterval 生成的 debugger
将 uzt.js uyt.js 内容替换 将这两个文件的内容置空,并刷新页面就可以正常调试了
参数逆向
点击翻页,可以发现 https://match.yuanrenxue.cn/api/match/1 接口的数据与页面的数据是对应的
请求参数 m 参数是动态加密的 每次加密的信息都不一样
查看对应的堆栈信息,并点击进入
点击翻页请求数据,会在断点处断住
‘data’ 参数是 _0xb89747 变量,向上查看 _0xb89747 变量生成的位置
代码是经过了 ASCII 码混淆的,手动解混淆之后代码逻辑会清晰很多
var _0x2268f9 = Date['parse'](new Date()) + 100000000
var _0x57feae = oo0O0(_0x2268f9['toString']()) + window['f'];
const _0x5d83a3 = {};
_0x5d83a3['page'] = window['page'];
_0x5d83a3['m'] = _0x57feae + '丨' + _0x2268f9 / 1000;
var _0xb89747 = _0x5d83a3;
AST 解混淆代码
遍历 StringLiteral 节点,将 rawValue 与 raw 替换即可
// 安装 babel 库: npm install @babel/core
const fs = require('fs')const traverse = require('@babel/traverse').default // 用于遍历 AST 节点
const types = require('@babel/types') // 用于判断, 生成 AST 节点const parser = require('@babel/parser') // 将js代码解析成ast节点
const generator = require('@babel/generator').default // 将ast节点转换成js代码// 读取
const ast_code = fs.readFileSync('1\\demo.js', {encoding: 'utf-8'
})let ast = parser.parse(ast_code) // 将js代码解析成ast语法树// 解混淆
traverse(ast, {StringLiteral(path){console.log('替换前: ', path.node.extra);path.node.extra.raw = `'${path.node.extra.rawValue}'`console.log('替换后: ', path.node.extra);console.log('============================================================')}
})let js_code = generator(ast).code // 将ast节点转换成js代码// 写入
fs.writeFileSync('1\\New_demo.js', js_code, {encoding: 'utf-8'
})
解混淆后的代码
_0x5d83a3[‘m’] 是由 _0x57feae + ‘丨’ + _0x2268f9 / 1000 还需要找 _0x57feae
_0x2268f9 参数是 Date[‘parse’](new Date()) + 100000000
_0x57feae 是 oo0O0 方法传入 _0x2268f9[‘toString’]() 再加上 window[‘f’]
点击查看 oo0O0 方法
在 eval 处下断 能发现方法中的 eval 前的代码是用于生成执行 在eval中执行 的代码
将执行的代码解混淆
window[‘b’] 代码是固定的,mw 是传进来的时间戳
将atob(window[‘b’])代码扣到本地
扣下来的代码最后是 window.f = hex_md5(mwqqppz)
mwqqppz 在 eval 执行前被替换成了时间戳
查看 oo000 方法,返回值是空字符串,返回查看执行这个方法的代码
eval 将加密参数的值赋值给了 window.f
方法的返回值为 ‘’, 调用加密方法的代码又加上了 window[‘f’]
扣下来的 js 代码最后可以改写为
function sdk(timeStrap){return hex_md5(timeStrap)
}
查看浏览器参数与加密结果
结果一致
python 代码
import requests
import execjs
import timeheaders = {"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
}
cookies = {"sessionid": "你的sessionid",
}def call_js(file_name, func_name, *args):with open(file_name, mode='r', encoding='utf-8') as f:js_code = execjs.compile(f.read())return js_code.call(func_name, *args)def get_data(page):url = "https://match.yuanrenxue.cn/api/match/1"time_ = int(str(int(time.time() * 1000))[:10] + '000') + 100000000encrypt_txt = call_js('1.js', 'sdk', str(time_))params = {"page": f"{page}","m": f"{encrypt_txt}丨{int(time_ / 1000)}"}response = requests.get(url, headers=headers, cookies=cookies, params=params)print(response.json())if __name__ == '__main__':get_data(1)