前言
距离上次逆向马蜂窝网站的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)
2. package.json ast.js的依赖文件。可以自己写。不过npm i更快些
{ "name": "version2", "version": "1.0.0", "description": "", "main": "ast.js", "scripts": { "test": "echo "Error: no test specified" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "@babel/generator": "^7.11.0", "@babel/parser": "^7.11.3", "@babel/traverse": "^7.11.0", "@babel/types": "^7.11.0" } }
3. run.py 运行的主文件
import requests import execjs # 需要的一些环境 BrowserEnvironment = """ var window = {}; window.navigator = {}; window.navigator.userAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/532.36 (KHTML, like Gecko) Chrome/83.0.1127.05 Safari/527.16"; function getCookie() { return window.cookie; } var document = { createElement: function(tag){ var innerHTML; return { firstChild: { href: "https://www.mafengwo.cn/" } } } }; window.document = document; var location = {"href": "https://www.mafengwo.cn/"}; window.location = location; """ ASTContext = execjs.compile(open("ast.js", "r").read()) def get_content(url): headers = { "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/532.36 (KHTML, like Gecko) Chrome/83.0.1127.05 Safari/527.16", # "cookie": "__jsluid_s=8f0ed86e64be8f70ffe0d9bacbbaaf7f; __jsl_clearance=1597471392.957|0|kwsM9EZXPySOSHcJWP0SyV7vZQ8%3D;" 1597471392.957|0|kws EZXPySOSHcJWP0SyV7vZQ8%3D } r = requests.get(url, headers=headers) # # print(r.text) __jsluid_s = r.headers["Set-Cookie"].split(";")[0] + "; " cookieStr = __jsluid_s # with open("input.js", "w") as f: # f.write(r.text) jsCode = ASTContext.call( "compile", BrowserEnvironment + r.text.strip().strip("<script>").strip("</script>"), ) context = execjs.compile(jsCode) jsl_clearance = context.call("getCookie").split(";")[0] + ";" cookieStr += jsl_clearance headers.update({"cookie": cookieStr}) r = requests.get(url, headers=headers) print(r.text) get_content("https://www.mafengwo.cn/i/18252205.html")
运行效果截图
代码
https://gitee.com/re_is_good/js_reverse/tree/master/mafengwo