原文連結: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 釋出!