提示!本文章仅供学习交流,严禁用于任何商业和非法用途,未经许可禁止转载,禁止任何修改后二次传播,如有侵权,可联系本文作者删除!
目标网站
aHR0cHM6Ly9jcmVkaXQuaGVmZWkuZ292LmNuL2NyZWRpdC13ZWJzaXRlL3B1YmxpY2l0eS94eWNuL3h5Y24tbGlzdC5kbz9uYXZJZD1DRTlGRkY1MTFENkUyQzRGRTA1Mzg4QkQwNDBBREVEMyZjb2x1bW5JZD1CNkE5NzlEQ0I2QTg0OTg0RTA1MzEyMDAxRTBBQzI3NiZyZWxlYXNlSWQ9QjZBOTc5RENCNkE4NDk4NEUwNTMxMjAwMUUwQUMyNzY=
抓包分析
破解的流程 请求分成三个请求:
1、不携带任何cookie的请求521, 拿到详情JS代码
2、携带第一个请求的set-cookie 和js 自执行的cookie 请求521
3、根据第二个请求的js 设置的cookie 发请求 拿到正常页面
第一个请求返回的内容 可以直接执行 拿到结果, 只需要分析第二个请求的js 内容
解混淆
const parser = require("@babel/parser");
const traverse = require("@babel/traverse").default;
const t = require("@babel/types");
const generator = require("@babel/generator").default;
const fs = require("fs");// js混淆代码
process.argv.length > 2 ? encode_file = process.argv[2] : encode_file = "./input/jsl.js";
process.argv.length > 3 ? decode_file = process.argv[3] : decode_file = "./output/jsl_decode.js";// #######################################
// AST解析函数
// #######################################// 获取全局函数
function getGlobalFunc(){let program_body= ast.program.body;for (var i=0; i<3; i++){globalCode += generator(program_body[i]).code + "\n";}return globalCode
}// AST还原流程
// #######################################// 读取需要解码的js文件, 注意文件编码为utf-8格式
let jscode = fs.readFileSync(encode_file, {encoding: "utf-8"});// 将js代码修转成AST语法树
let ast = parser.parse(jscode);console.time("处理完毕,耗时");var globalCode = '';// 获取自执行方法
globalCode = getGlobalFunc();
eval(globalCode);const deal_CallExpression = {CallExpression(path){let {callee, arguments} = path.node;if (callee === undefined || callee.name === undefined)return;if (callee.name != '_0xfecf' || arguments.length !=2 )return;let value = _0xfecf(arguments[0].value, arguments[1].value);// 创建节点并替换结果let string_node = t.stringLiteral(value);path.replaceWith(string_node)}
};// 遍历语法树节点,调用修改函数
traverse(ast, deal_CallExpression);// 合并字符串
const BinaryExpressionFix = {BinaryExpression: {exit: function (path) {try {eval(path.toString()).toString();path.replaceWith(t.stringLiteral(eval(path.toString()).toString()));} catch (e) {}}}
};
traverse(ast, BinaryExpressionFix);// 删除无用方法
nodesToRemove = [];
const remove_path = {enter(path) {// 只在顶层语句中收集前三个节点if (path.parentPath && path.parentPath.isProgram() && nodesToRemove.length < 3) {nodesToRemove.push(path);}}
};
traverse(ast, remove_path);
nodesToRemove.forEach(path => path.remove());console.timeEnd("处理完毕,耗时");// 将ast转成js代码,{jsescOption: {"minimal": true}} unicode -> 中文
let {code} = generator(ast, opts = {jsescOption: {"minimal": true}});
// 将js代码保存到文件
fs.writeFile(decode_file, code, (err) => {
});console.log("end");
解混淆后的代码直接执行 调试,把缺少的环境补上
如下:
window = global;
window.navigator = {};
navigator.userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36";
document = {};
直接执行得到 结果, 和浏览器对比发现是一致的
通过分析多个JS 会发现 整体js 根据参数 执行 MD5, sha1,sha256 加密运算,结果和ct 值作比对
结语
可以通过补环境,提取参数的方式通过执行js拿到cookie 结果, 也可以通过Python改写的方法去完成
ps: 觉得不错点个赞 。。。