前言
距离上次逆向马蜂窝网站的cookie已经过去3个月。
今天稍微看了下那个网站,貌似已经发生了变化了,有大量的变量混淆。还有小型的控制流平坦化。
自从接触了ast,感觉这种的都较为容易了。(强力安利学习ast)
(代码运行多次还是提示语法错误的话,一般是环境没搞好。node运行时与浏览器环境可不一样。这个自己解决吧。 2021.5.11下午4点代码运行正常)
思路
这里就讲讲逆向此网站的思路吧。因为是cookie逆向,不管这个代码怎么变态,它最终还是要使用document.cookie 来操作cookie。
那我们便可以从这个来入手。我们要做的便是hook document.cookie。相关的hook代码如下。
Object.defineProperty(document, "cookie", { set: function (newCookie) { debugger; } });
我们可以将响应的js代码复制下来(注意清除掉cookie),粘贴到本地文件。然后在js代码的最前面加上上面的两行语句。
// index.html Object.defineProperty(document, "cookie", { set: function (newCookie) { debugger; document.cookie = newCookie; } }); // 下面便是你复制的代码
在浏览器中打开此文件
最好先F12打开控制台,然后复制文件路径进行访问。不然可能页面会卡死
然后就可以看到页面在此处卡住了,而所设置的cookie便是我们想要的。
调用栈往上找一层,就可以看到设置cookie的代码了
这样的写法算是正常的一种,其实还有另外一种写法(可以自行探索下)。
我们需要将这些语句转化一下。因为node中没有location.href, 虽然可以定义个假的。
转化成以下这个样子
然后我们可以定义个方法返回即可
ast转化-具体实现
1. ast.js 用于转化这些代码,以便在非浏览器环境中运行。
const generator = require("@babel/generator");
const parser = require("@babel/parser");
const traverse = require("@babel/traverse");
const types = require("@babel/types");
const fs = require("fs");
function compile(code) {
const ast = parser.parse(code);
const visitor = {
CallExpression(path) {
// func(setTimeout)
const node = path.node;
let cookiePartExpression;
if (
node.arguments
&& node.arguments[0]
&& node.arguments[0].name === "setTimeout"
) {
// 获取执行的函数体
cookiePartExpression = node.arguments[1].body.body[0].expression.right
// console.log(cookiePartExpression)
// 删除此节点
//
;
// console.log(parentFunc.node.expression)
}
// console.log(node.callee)
if (
node.callee
&& node.callee.name === "setTimeout"
) {
cookiePartExpression = node.arguments[0].body.body[0].expression
console.log(cookiePartExpression)
}
if (cookiePartExpression) {
path.replaceWith(types.expressionStatement(
types.assignmentExpression("=",
types.memberExpression(types.identifier("window"), types.identifier("cookie")),
cookiePartExpression
)
))
}
}
};
traverse.default(ast, visitor);
return generator.default(ast, {}, code).code;
}
// const code = fs.readFileSync("./input.js", "utf-8");
// const output = compile(code);
// fs.writeFileSync("output.js", output.code)