hook知识和JJ,AA jsfuck,ob混淆的理解和解法

一. 前言

这里主要是写对于hook知识的一个理解和对于市面的混淆做出一个他的解法, 相当于一个总和

二. hook

什么是hook? Hook技术又叫做钩子函数,在系统没有调用该函数之前,钩子程序就先捕获该消息,钩子函数先得到控制权,这时钩子函数既可以加工处理(改变)该函数的执行行为,还可以强制结束消息的传递。简单来说,就是把系统的程序拉出来变成我们自己执行代码片段。在程序中我们可以把他理解为劫持。

在js中的hook,替换原函数的都可以理解为hook,那么我们就有个疑问了,我们为什么可以hook呢, 原因就是我们客户端拥有最高解释权,可以决定在任何时候注入hook,而服务器无法阻止,只能通过检测hook或者混淆,让其难度加大。这里我强烈推荐一篇文章, 可以让你理解hook知识:https://mp.weixin.qq.com/s/IYFyjVrVkHtUdCzn9arkJQ。hook当然还有一个插件,那就是油猴,关于油猴就不在这里面过多描述了,可百度。

fillder中的JS替换

 

 

 

这里hook需要着重理解的就是object.defineProperty():

  Object.defineProperty(obj, prop, descriptor)是基本语法,作用就是在一个对象上面定义一个新的属性,或修改一个对象现有的属性。

  接收三个参数如下:

        obj: 需要定义属性的对象.

        prop: 当前需要定义的属性名, 也就是你要hook的属性

        descriptor:属性的描述符, 可以取以下的值:

        

 

这里写一个hook cookie的一个列子: 

      

1 Object.defineProperty(document, 'cookie', {
2             set:function(val){
3                debugger;
4                return val
5 }
6 })

 

这里第一个就是当前需要定义的对象, 第二个就是你要hook的属性, 第三个就是描述符了。

在 Hook 中,使用最多的是存取描述符,即 get 和 set。

get:属性的 getter 函数,如果没有 getter,则为 undefined,当访问该属性时,会调用此函数,执行时不传入任何参数,但是会传入 this 对象(由于继承关系,这里的 this 并不一定是定义该属性的对象),该函数的返回值会被用作属性的值。

set:属性的 setter 函数,如果没有 setter,则为 undefined,当属性值被修改时,会调用此函数,该方法接受一个参数,也就是被赋予的新值,会传入赋值时的 this 对象。

列子的话大家可以在我贴的上面代码实现, 需要注意的是,网站加载时首先要运行我们的 Hook 代码,再运行网站自己的代码,才能够成功断下,或者用fillder替换。这个过程我们可以称之为 Hook 代码的注入,下面写几种注入hook获取属性方法。

Hook Cookie

Object.defineProperty(document, 'cookie', {
            set:function(val){
               debugger;
               return val
}
})

 

Hook Header

Header Hook 用于定位 Header 中关键参数生成位置,以下代码演示了当 Header 中包含 Authorization 关键字时,则插入断点:

(function () {
    var org = window.XMLHttpRequest.prototype.setRequestHeader;
    window.XMLHttpRequest.prototype.setRequestHeader = function (key, value) {
        if (key == 'Authorization') {
            debugger;
        }
        return org.apply(this, arguments);
    };
})();

Hook URL

URL Hook 用于定位请求 URL 中关键参数生成位置,以下代码演示了当请求的 URL 里包含 login 关键字时,则插入断点:

(function () {
    var open = window.XMLHttpRequest.prototype.open;
    window.XMLHttpRequest.prototype.open = function (method, url, async) {
        if (url.indexOf("login") != -1) {
            debugger;
        }
        return open.apply(this, arguments);
    };
})();

Hook JSON.stringify

JSON.stringify() 方法用于将 JavaScript 值转换为 JSON 字符串,在某些站点的加密过程中可能会遇到,以下代码演示了遇到 JSON.stringify() 时,则插入断点:

(function() {
    var stringify = JSON.stringify;
    JSON.stringify = function(params) {
        console.log("Hook JSON.stringify ——> ", params);
        debugger;
        return stringify(params);
    }
})();

Hook  JSON.parse

JSON.parse() 方法用于将一个 JSON 字符串转换为对象,在某些站点的加密过程中可能会遇到,以下代码演示了遇到 JSON.parse() 时,则插入断点:

(function() {
    var parse = JSON.parse;
    JSON.parse = function(params) {
        console.log("Hook JSON.parse ——> ", params);
        debugger;
        return parse(params);
    }
})();

ob混淆

ob混淆呢具有以下特征:

  1. 具有大数组的情况

  2. 数组移位(有内存泄露风险、建议不格式化),自执行函数,进行移位操作,有明显的 push、shift 关键字

  3.解密函数(有内存泄露风险、建议不格式化)------可能有定时器--------(看加密的开关开启数量)

  4.实际代码+控制流平坦化(整体ob的强度几乎完全取决于这段的代码强度,这里面是加密前的逻辑)

  5.控制流平坦化+无限debugger自执行函数+死代码注入。一般情况下不会有业务逻辑所以不要问,ob、sojson如何破解。这些东西只是一层壳,破解强度完全取决于第四段代码,也就是其他网站作者写的代码强度!

  6.函数名和变量名通常以 _0x 或者 0x 开头,后接 1~6 位数字或字母组合;

解决方法呢:上面也讲了,还有就是AST解码混淆 推荐和猿人学的解混淆http://tool.yuanrenxue.com/,或者你硬刚也是可以的。

列如猿人学的第二题

 

 

 

 

通过上面的列子我们可以知道运用hook的知识, 然后硬刚基本还是可以的, 不过遇到了复杂的混淆, hook是hook不到的 只能从头开始跟。

JJEncode混淆

jjencode是日本的Yosuke HASEGAWA在2009年开发的,它可以将任意 JavaScript 编码为仅使用 18 个符号的混淆形式 []()!+,\"$.:;_{}~=。

缺点:JJEncode 易于解码,它不是实用的混淆,只是一个编码器,JJEncode很容易被检测,而且还浏览器依赖,它的缺点是压栈很严重,如果 JS 很大,去做加密可能内存溢出,所以只适合核心功能加密,事实上 JJEncode 商用的还是很少,不过认识一下并没有什么坏处。

举例:

 

 

 这一个正常的代码。

然后这是混淆过后的代码

 

解决办法:

  1:控制台执行报错,且非unsafe错误:点击报错信息即可还原代码

  2:控制台执行不报错,删除一些语法(以括号为主),强制令其报错

  3:控制台报unsafe错误:自写个html运行,然后删除语法令其报错即可还原 

 

 

 AAEncode混淆

跟JJencode , jsfuck一个作者,方法都是差不多 在控制台进行打印。上面那几种方法都适用

解决方法:

  1:去掉代码最后一个符号 ('_') 后,放到浏览器里面去直接执行就可以看到源码

  2:在线调试,在 AAEncode 代码第一行下断点,然后一步一步执行,最终也会在虚拟机(VM)里看到源码

jsFuck混淆

jsfuck都是差不多的,方法跟上面都适用, 不过会有一种jsfuck技术在控制台打印他也显示不出来,他是在jsfuck套了一层,比如你想知道a  但是你控制台打印出来是b.

这种的解决办法是:在混淆前面打上debugger,然后在控制台一步一步的调试。跟到生成a的代码里面。这是唯一需要注意的一个点。其他基本差不多

 

posted @ 2021-12-22 16:03  风一样得男子  阅读(2500)  评论(0编辑  收藏  举报