素材巴巴 > 程序开发 >

JS逆向之浏览器补环境(一)

程序开发 2023-09-15 12:32:42

JS逆向之浏览器补环境(一)

简介

今天分享是是浏览器环境检测以及node js补环境

image-20220316154027340

我们点击检测设备信息看发出的请求,可以看到是sign和data

image-20220316154144257

这个data看起来像base64,我们试一下,发现不是

image-20220316154314765

分析加密位置

image-20220316154405883

可以看到经过混淆了

image-20220316154448202

我们选中看一下

image-20220316154508608

image-20220316154606258

那我们接下来就知道了,要逆向的两个参数变量

_0x392f2d
 _0xd9e63f
 

我们直接把整个文件拷贝到webstrom里,看一下这两个变量在哪里定义的,可以看到在这

image-20220316154803280

由于我们只需要这两个变量,所以下面的代码可以删除了,变成这样

image-20220316154849200

追踪检测

然后引入proxy检测对象变化的代码

proxy.js

let _window = {};
 let _stringify = JSON.stringify;
 JSON.stringify = function (Object) {// ?? 的意思是,如果 ?? 左边的值是 null 或者 undefined,那么就返回右边的值。if ((Object?.value ?? Object) === global) {return "global";}return _stringify(Object);
 };function getMethodHandler(WatchName) {let methodhandler = {apply(target, thisArg, argArray) {let result = Reflect.apply(target, thisArg, argArray);console.log(`[${WatchName}] apply function name is [${target.name}], argArray is [${argArray}], result is [${result}].`);return result;},construct(target, argArray, newTarget) {let result = Reflect.construct(target, argArray, newTarget);console.log(`[${WatchName}] construct function name is [${target.name}], argArray is [${argArray}], result is [${JSON.stringify(result)}].`);return result;}};return methodhandler;
 }function getObjHandler(WatchName) {let handler = {get(target, propKey, receiver) {let result = Reflect.get(target, propKey, receiver);if (result instanceof Object) {if (typeof result === "function") {console.log(`[${WatchName}] getting propKey is [${propKey}] , it is function`);//return new Proxy(result,getMethodHandler(WatchName))} else {console.log(`[${WatchName}] getting propKey is [${propKey}], result is [${JSON.stringify(result)}]`);}return new Proxy(result, getObjHandler(`${WatchName}.${propKey}`));}console.log(`[${WatchName}] getting propKey is [${propKey}], result is [${result}]`);return result;},set(target, propKey, value, receiver) {if (value instanceof Object) {console.log(`[${WatchName}] setting propKey is [${propKey}], value is [${JSON.stringify(value)}]`);} else {console.log(`[${WatchName}] setting propKey is [${propKey}], value is [${value}]`);}return Reflect.set(target, propKey, value, receiver);},has(target, propKey) {let result = Reflect.has(target, propKey);console.log(`[${WatchName}] has propKey [${propKey}], result is [${result}]`);return result;},deleteProperty(target, propKey) {let result = Reflect.deleteProperty(target, propKey);console.log(`[${WatchName}] delete propKey [${propKey}], result is [${result}]`);return result;},getOwnPropertyDescriptor(target, propKey) {let result = Reflect.getOwnPropertyDescriptor(target, propKey);console.log(`[${WatchName}] getOwnPropertyDescriptor  propKey [${propKey}] result is [${JSON.stringify(result)}]`);return result;},defineProperty(target, propKey, attributes) {let result = Reflect.defineProperty(target, propKey, attributes);console.log(`[${WatchName}] defineProperty propKey [${propKey}] attributes is [${JSON.stringify(attributes)}], result is [${result}]`);return result;},getPrototypeOf(target) {let result = Reflect.getPrototypeOf(target);console.log(`[${WatchName}] getPrototypeOf result is [${JSON.stringify(result)}]`);return result;},setPrototypeOf(target, proto) {console.log(`[${WatchName}] setPrototypeOf proto is [${JSON.stringify(proto)}]`);return Reflect.setPrototypeOf(target, proto);},preventExtensions(target) {console.log(`[${WatchName}] preventExtensions`);return Reflect.preventExtensions(target);},isExtensible(target) {let result = Reflect.isExtensible(target);console.log(`[${WatchName}] isExtensible, result is [${result}]`);return result;},ownKeys(target) {let result = Reflect.ownKeys(target);console.log(`[${WatchName}] invoke ownKeys, result is [${JSON.stringify(result)}]`);return result;},apply(target, thisArg, argArray) {let result = Reflect.apply(target, thisArg, argArray);console.log(`[${WatchName}] apply function name is [${target.name}], argArray is [${argArray}], result is [${result}].`);return result;},construct(target, argArray, newTarget) {let result = Reflect.construct(target, argArray, newTarget);console.log(`[${WatchName}] construct function name is [${target.name}], argArray is [${argArray}], result is [${JSON.stringify(result)}].`);return result;}};return handler;
 }
 _window = Object.assign(global, _window);
 const window = new Proxy(Object.create(_window), getObjHandler("window"));
 module.exports = {window
 };
 

在拷贝到webstrom里的代码进行导入

const {window} = require("../tools/proxy");
 

然后我们运行之前拷贝到webstrom里的代码

image-20220316160543376

发现在window上需要定义一个XMLHttpRequest,那是定义在window上呢,还是定义在它的原型链上呢,我们可以浏览器里看一下

第一个是检查对象自身的属性,第二是检查所有属性。因此我们需要定义在它的原型上

image-20220316160907768

修改追踪的代码

image-20220316161447079

然后我们打印看一下,发现也没有问题

image-20220316161521002

我们再运行以下之前的代码,发现需要navigator

image-20220316161654173

那我们也补上

let _window = {XMLHttpRequest: function (){},
 };
 let _navigator = {};
 _window = Object.assign(global, _window);
 const window = new Proxy(Object.create(_window), getObjHandler("window"));
 const navigator = new Proxy(Object.create(_navigator), getObjHandler("navigator"));
 module.exports = {window,navigator,
 };
 

image-20220316161843034

然后又要这个,同理

image-20220316161914701

image-20220316162020706

image-20220316162035672

发现没有问题了,也拿到了sign和data

image-20220316162059446

python调用

然后我们通过python试一下

image-20220316162839091

然后到在线工具里转一下

https://tool.lu/curl/

image-20220316162929633

发现直接被检测到了,就是我们的环境检测没有通过

image-20220316163325740

补环境

我们可以看到有一堆undefined,这些都是我们需要补的环境

image-20220316163459202

然后我们要看一下这个值在浏览器里是怎么样的,并且是定义在对象上还是原型上,比如navigator来说,发现是定义在原型上的。

image-20220316163945631

然后就照着补就行了

注意这个,getOwnPropertyDescriptor是拿的自身属性上的

image-20220316164211915

最后补的结果

let _window = {XMLHttpRequest: function (){},sessionStorage: function (){},localStorage: function (){},
 };
 let _navigator = {userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36 Edg/99.0.1150.39",appCodeName: "Mozilla",plugins: {length: 0},
 };
 let _screen = {colorDepth: 24,height: 900,width: 1440,
 };
 _window = Object.assign(global, _window);
 const window = new Proxy(Object.create(_window), getObjHandler("window"));
 const navigator = new Proxy(Object.create(_navigator), getObjHandler("navigator"));
 const screen = new Proxy(Object.create(_screen), getObjHandler("screen"));
 module.exports = {window,navigator,screen,
 };
 

再跑一次,拿着data和sign去请求,通过!

image-20220316165302878

另一种操作(不推荐)

使用JSDOM自带的浏览器环境

安装

npm install jsdom
 

使用

const jsdom = require("jsdom");
 const {JSDOM} = jsdom;const {window} = new JSDOM(``);
 const navigator = window.navigator;
 const screen = window.screen;
 // 这个是缺啥补啥 基本都齐了
 window.XMLHttpRequest = function XMLHttpRequest() {
 };
 module.exports = {window,navigator,screen
 };
 

导入

image-20220316180345893

但是会出现各式各样的问题,不推荐

image-20220316180416200


标签:

上一篇: Three.js加载采用DRACO压缩的glft 下一篇:
素材巴巴 Copyright © 2013-2021 http://www.sucaibaba.com/. Some Rights Reserved. 备案号:备案中。