多個開源的js補環境框架測試

Python成长路發表於2024-05-07

原文連結:https://mp.weixin.qq.com/s/uEMFGpE5bqmTvzSgX2twvA

前言

在做js逆向時肯定會遇到補環境的情況,看到github開源了好幾個補環境用的框架,這篇文章做個測試,看看哪個比較好用。

  • https://github.com/pysunday/sdenv
  • https://github.com/bnmgh1/node-sandbox
  • https://github.com/ylw00/qxVm
  • https://github.com/xuxiaobo-bobo/boda_jsEnv
  • https://github.com/Big1moster/catvm
  • https://github.com/cilame/v_jstools

測試網站

測試的網站我這裡用某號店的captchaToken引數來測試,如果想看逆向過程可以直接搜這個引數名,文章挺多的。這裡我就不扣程式碼,使用整個js檔案來補環境。

https://passport.yhd.com/front-passport/passport/js/js-nocaptcha.js

sdenv

依賴安裝

  • node版本20.10.0+
  • python
  • vs2022( 使用C++的桌面開發)

然後把原始碼下載下來,執行npm install安裝需要的node包。直接執行example目錄下的示例是能跑通的。

測試案例

照葫蘆畫瓢,我也在example建一個目錄,裡面建一個index.js檔案,直接賦值example/use-local/index.js的內容。然後改一些需要改的內容,比如baseUrl,html和js路徑。

ts檔案裡放的是一些要在js裡使用的變數,所以ts檔案這裡可以不用。在js程式碼後加一行呼叫和列印的程式碼var jab = new JAB( {bizId: 'PASSPORT_LOGIN',initCaptcha: true});console.log(jab.getData());

然後執行這個index.js是可以直接得到結果的,這個結果我就不去驗證能不能用了,這裡只是測一下框架執行正不正常。

總結

說是補環境框架,但是我找了半天沒找到哪裡有吐環境,搜尋了下程式碼和文件。發現只有部分物件和函式可以監聽並列印日誌,比如cookie、eval等。

所以這其實是一個模擬環境的框架,修改了jsdom容易被檢測的地方,可以直接執行網站的js出結果。並不能吐環境出來,然後自己補環境。

node-sandbox

依賴安裝

這個專案沒有任何依賴,node也是用github裡提供的,node_modules這個依賴包資料夾也一起打包了。

測試案例

給的案例程式碼在main.js裡,看了下呼叫的例子。只需要在裡面增加下面的程式碼,然後把js放到"./work/1hao.js"

function test_vm() {
    const sandbox = {
        wanfeng: wanfeng,
        globalMy: globalMy,
        console: console,
    }
    let workCode = fs.readFileSync("./work/1hao.js");
    a = +new Date;
    var code = "debugger;\r\n" + globalMy_js + init_env + envCode + "\r\n" + workCode + "\r\n" + endCode + `var jab = new JAB( {bizId: 'PASSPORT_LOGIN',initCaptcha: true});console.log("captchaToken: ", jab.getData())`;
    vm.runInNewContext(code, sandbox);
    console.log("執行環境Js + 工作Js 耗時:", +new Date - a, "毫秒");
}

test_vm();

注意執行的時候需要用他給的node執行,解壓node.zip,然後執行.\node main.js就出結果了

呼叫了哪些函式,獲取了哪些物件也都列印出來了,captchaToken的結果也輸出了。後面只需要根據列印的內容補上對應的環境,如果不知道具體是什麼值,可以打上斷點,看看哪裡呼叫的,然後在瀏覽器同樣的位置也打上斷點看看具體值。

如果想要除錯main.js,先在vscode 裡點執行與除錯這個視窗然後建立launch.json,增加一個runtimeExecutable值,填這個node的路徑,vscode就會用這個node來除錯,而不是系統環境裡的node。

完整的launch.json:

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "node",
            "request": "launch",
            "name": "啟動程式",
            "skipFiles": [
                "<node_internals>/**"
            ],
            "program": "${workspaceFolder}\\main.js",
            "runtimeExecutable": "D:\\Code\\JavaScript\\env\\node-sandbox\\node.exe"
        }
    ]
}

總結

使用還挺方便的,可惜的是作者棄坑不維護了。

qxVm

依賴安裝

沒有依賴

測試案例

案例的程式碼在z_working目錄裡,複製一份rs4Vm.js程式碼,修改裡面需要呼叫的js檔案。還需要寫一個函式用於外部呼叫

const fs = require('fs');
const QXVM_GENERATE = require('../qxVm_sanbox/qxVm.sanbox');

function ReadCode(name, dir) {
    let file_path = dir === undefined ? `${__dirname}/${name}` : `${__dirname}/${dir}/${name}`;
    return fs.readFileSync(file_path) + "\r\n"
}

const js_code = ReadCode(`./1hao.js`);

const user_config = {
    isTest: false,
    runConfig: { proxy: true, logOpen: true},
    window_attribute: {},
    env: {
        navigator: {
            userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36 Edg/100.0.1185.55"
        },
        location: {
            href: "https://passport.yhd.com/passport/login_input.do"
        },
        document: {
            referrer: "https://passport.yhd.com/passport/login_input.do",
            cookie: 'msessionid=7HBZXGSGTJVV5DVJZMX79GTAHGFNR1SFBACY; rURL=http%3A%2F%2Fwww.yhd.com; _c_id=1vrexxncjh8v9kuj8ay1714789367454lxua; _s_id=rrvyv3ga2ok1vj5e2tz1714789367454whwa; jab-requestId=""'
        }
    }
}
// 幫助資訊列印
QXVM_GENERATE.help()

let result = QXVM_GENERATE.sanbox(js_code, "get_jab", user_config, false);
let captchaToken = result.get_jab()
console.log("captchaToken:", captchaToken)

執行的時候報錯了:

看錯誤像是什麼環境沒有補全,獲取到了undefined,除錯一下看看

可以看到是MediaDevices.enumerateDevices獲取的是undefined,然後停止了。看了下瀏覽器:

修改他的程式碼返回個Promise物件給他,如果是實際補環境,需要先看看網站需要獲取到什麼在給它什麼。直接補空值雖然可能出結果,但是也可能通不過驗證。這裡我只是驗證下框架

接著執行又出現個新的錯誤:

又是什麼物件沒有,除錯看了下執行到[Func] -> [ HTMLElement.for ] -> () -> [ undefined ],搜尋程式碼裡

那直接給他返回個物件看看,又出現新錯誤TypeError [Error]: Cannot read properties of undefined (reading 'length'),是[Func] -> [ Document.querySelectorAll ] -> (script) -> [ undefined ]沒有返回值。那直接返回個空陣列給它。

結果倒是輸出出來了,但是後面又報錯了:

vmcode.js應該就是上面指定是1hao.js。因為無法再1hao.js打斷點,可以在3406行加一個debugger;,看了下a2是個物件,看物件的內容好像是battery相關的,b("0x4f9", "@])N")是addEventListener,還是在瀏覽器看比較清晰

這裡獲取的其實就是全域性的addEventListener函式,後面就不去折騰了。

總結

很多環境沒有補全,還得自己手擼。不過吐環境效果也還可以,都把環境列印出來了。等於提供一個工具,可以不用從零造輪子。

boda_jsEnv

我太菜了,給的例子我都沒跑成功,這個就跳過了。

catvm

測試了下,環境缺少太多了,比如XMLHttpRequest、Image這些都沒有,不如上面的那幾個好用。用的時候你得像上面執行qxVm一樣,報一個錯誤,打一個斷點看看缺什麼環境補上去繼續執行。

而且也是不更新的狀態,還是建議珍惜生命

v_jstools

這個我就不說了,感興趣的可以自己搜搜,教程還挺多的。

結論

如果想自己補環境,首選node-sandbox,次選qxVm。如果不想補環境,只是想在node中呼叫執行,直接選sdenv,測試可以秒殺很多網站。還是一些未公開的框架就不測試了。

本文由部落格一文多發平臺 OpenWrite 釋出!

相關文章