马蜂窝cookie逆向更新(ast)

前言

距离上次逆向马蜂窝网站的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)
View 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"
  }
}
View Code

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")
View Code

运行效果截图

代码

https://gitee.com/re_is_good/js_reverse/tree/master/mafengwo

原文地址:https://www.cnblogs.com/re-is-good/p/mafengwo_version2_ast_cookie.html