前言
距離上次逆向馬蜂窩網站的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
