首页 > 其他分享 >补环境系列教程

补环境系列教程

时间:2023-01-12 18:00:11浏览次数:54  
标签:教程 set 系列 target get 环境 console return property

补环境系列教程

掌握自动吐坏境操作
掌握环境差异化hook操作

1 项目实操一

1.1  逆向目标

●目标:https://www.zhihu.com/topic/19555513/hot

●参数:x-zse-96:  _02B4Z6wo00901-PSSggAAIDC

1.2 逆向分析

全局搜索某乎关键字、然后在JS里面有2处地方,全部选中然后下断点调试

 

 从这里可以看出

 

 

signature: (0,Z(r).encrypt)(f()(s))

进去里面的算法查看,下个断点看数据。

 

 这就不好办了,那么即使补环境出来的结果,也不知道是不是对的。一般这种情况下,就是计算涉及到的随机数或者时间。而这里就是包含的随机数,所以需要hook随机数的返回

Math.random = function(){
    return 0.50
};

然后在头部加上jsdom的代码

const{JSDOM}=require("jsdom");
const dom=new JSDOM("<!DOCTYPE html><p>Hello world</p>");
window=dom.window;
document=window.document;  //document对象:代表给定浏览器窗口中的HTML文档,
navigator=window.navigator; // 关于运行当前脚本的应用程序的相关信息
location=window.location; //对象包含当前页面的URL信息
history=window.history; // 历史会话
screen=window.screen; // 浏览器屏幕

Math.random = function(){
    return 0.50
};

这个结果和样本明显不一样,说明还缺少了其他环境没有补到,,这个时候就需要使用自动吐环境啦,对前面的环境变量上代理,看看还用到了什么属性和方法

window = new Proxy(window, {
    set(target, property, value, receiver) {
        console.log("设置属性set window", property, typeof value);
        return Reflect.set(...arguments);
    },
    get(target, property, receiver) {
        console.log("获取属性get window", property, typeof target[property]);
        return target[property]
    }
});
document = new Proxy(document, {
    set(target, property, value, receiver) {
        console.log("设置属性set document", property, typeof value);
        return Reflect.set(...arguments);
    },
    get(target, property, receiver) {
        console.log("获取属性get document", property, typeof target[property]);
        return target[property]
    }
});
navigator = new Proxy(navigator, {
    set(target, property, value, receiver) {
        console.log("设置属性set navigator", property, typeof value);
        return Reflect.set(...arguments);
    },
    get(target, property, receiver) {
        console.log("获取属性get navigator", property, typeof target[property]);
        return target[property]
    }
});
location = new Proxy(location, {
    set(target, property, value, receiver) {
        console.log("设置属性set location", property, typeof value);
        return Reflect.set(...arguments);
    },
    get(target, property, receiver) {
        console.log("获取属性get location", property, typeof target[property]);
        return target[property]
    }
});
history = new Proxy(history, {
    set(target, property, value, receiver) {
        console.log("设置属性set history", property, typeof value);
        return Reflect.set(...arguments);
    },
    get(target, property, receiver) {
        console.log("获取属性get history", property, typeof target[property]);
        return target[property]
    }
});
screen = new Proxy(screen, {
    set(target, property, value, receiver) {
        console.log("设置属性set screen", property, typeof value);
        return Reflect.set(...arguments);
    },
    get(target, property, receiver) {
        console.log("获取属性get screen", property, typeof target[property]);
        return target[property]
    }
});

2 项目实操二

2.1 逆向目标

地址:http://q.10jqka.com.cn/

2.2 补环境实操

先补充基本的环境

 注:如图环境补完后、发现还是没有cookie的值、这个时候需要排查是不是代码走了其他的分支、导致输出异常。可以在try、catch里面输出查看。

 在这个位置输出、可以发现有环境出现了异常,这个时候需要补了

 

 3 吐环境脚本

 3.1 简介

 Proxy可以理解为,在目标对象之前设一层"拦截",外界对该对象的访问,都必须通过这层拦截,可以对外界的访问进行过滤和改写(表示可以用它"代理"某些操作,可以翻为“代理器")。

 

 基本使用

// 目标对象(被代理对象)
var target = {
    name: 'JACK',
    age: 18,
};

// 代理行为对象(对目标对象进行取值或赋值行为时,会进入此对象的方法)
var handler = {
    get: function(target, property, receiver) {
        console.log("get: ", target, property, target[property]);
        return target[property];
    },
    set: function(target, property, value) {
        console.log("set: ", target, property, value);
        return Reflect.set(...arguments);
    }
};

// 使用 Proxy 构造函数实例出新的target对象
var targets = new Proxy(target, handler)

// 取值操作 会进入handler中的get方法 并打印
targets.name     //  get:  {name: 'JACK', age: 18} name JACK
// 赋值操作 会进入handler中的set方法 并打印
targets.age = 25 //  set:  {name: 'JACK', age: 18} age 25

 Proxy对象由两个部分组成:target、handler
target:目标对象 handler:是一个对象,声明了代理target的指定行为,支持的拦截操作,一共13种:

get(target,propKey,receiver):拦截对象属性的读取。
set(target,propKey,value,receiver):拦截对象属性的设置,返回一个布尔值(修改成功)。

 对于JS逆向来说,我们扣完代码的目的就是调用目标网站的加/解密函数或某个值的算法,一般情况下我们把他的算法扣下来能够直接执行,但是如果检测了浏览器指纹,那就比较难了,只能够去深入分析进行补环境。
一般的补环境的是通过运行程序后的undefined报错去一点一点分析,一点一点的去补一些环境,是非常掉头发的。
所以我们使用 Proxy 对全局遍历window、document、navigator等常见环境检测点进行代理,拦截代理对象的读取、函数调用等操作,并通过控制台输出,这样的话我们就能够实现检测环境自吐的功能,后续我们再针对吐出来的环境统一的进行补环境,这样就会方便的多。

 3.2 脚本编写

 

document = new Proxy(document, {
    set(target, property, value, receiver) {
        console.log("设置属性set document", property, typeof value);
        return Reflect.set(...arguments);
    },
    get(target, property, receiver) {
        console.log("获取属性get document", property, typeof target[property]);
        return target[property]
    }
});

4 jsdom补环境

 参考地址:https://github.com/jsdom/jsdom/wiki/jsdom-中文文档
jsdom是一个纯粹由 javascript 实现的一系列 web标准,特别是 WHATWG 组织制定的DOMHTML 标准,用于在nodejs中使用。大体上来说,该项目的目标是模拟足够的Web浏览器子集,以便用于测试和挖掘真实世界的Web应用程序

 4.1 环境安装

npm install jsdom --save

4.2 基本使用

const jsdom = require("jsdom");
const { JSDOM } = jsdom;
const dom = new JSDOM(`<!DOCTYPE html><p>Hello world</p>`);
title = dom.window.document.querySelector("p").textContent
console.log(title)

4.3 添加参数形式

const dom = new JSDOM(``, {
  url: "http://q.10jqka.com.cn/",
  referrer: "http://q.10jqka.com.cn/",
  contentType: "text/html",
  includeNodeLocations: true,
  storageQuota: 10000000
});

  

 

标签:教程,set,系列,target,get,环境,console,return,property
From: https://www.cnblogs.com/yoyo1216/p/17047419.html

相关文章