zoukankan      html  css  js  c++  java
  • 马蜂窝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

  • 相关阅读:
    Android动画 interpolator的用法
    ListView的addAll方法
    界面切换动画
    ListView的setSelectionFromTop()方法与setSelection()方法的联系
    new总结
    linux中进程控制
    linux设备模型
    如何将驱动加入内核
    linux缓冲的概念fopen /open,read/write和fread/fwrite区别
    点云的滤波
  • 原文地址:https://www.cnblogs.com/re-is-good/p/mafengwo_version2_ast_cookie.html
Copyright © 2011-2022 走看看