爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)

文章目录

  • 一、hook定义
    • 1 为什么能实现hook
    • 2 hook目的是什么
  • 二、hook使用
    • 1 hook步骤
    • 2 函数hook公式:
    • 3 对象中属性hook公式:
      • 3.1 defineProperty方法
      • 3.2 实现方法
  • 三、hook实操
    • 1、应对cookie解密(st2)
    • 2、应对cookie解密(st9)
    • 3、通过eval确定debugger产生位置代码
    • 4、hook的弊端和缺陷
  • 四、hook插件:油猴脚本
    • 1、油猴脚本参数介绍
    • 2、油猴脚本基本使用
  • 五、hook补充
    • 1. 局部函数的hook
    • 2. 全局变量的hook
    • 3. 一些常用的hook逻辑
  • 六、验证码实现原理
    • 1、基本原理
    • 2、交互验证过程举例(ds8)
    • 3、一线验证码
    • 4、解决方案
  • 七、js逆向核心-扣代码-补环境-jsRPC
    • 1、扣代码优缺点
    • 2、补环境优缺点
    • 3、jsRPC
  • 八、扣代码实战
    • 1、cookie参数加密入口捕获(st2)
    • 2、cookie参数(bs2)(浏览器指纹检测与格式化检测)
  • 七、总结

创作不易,希望点个赞!
如果本文有任何问题错误,欢迎评论指正!

(点个赞!点个赞!点个赞!点个赞!点个赞!点个赞!)

前面文章:

爬虫(js逆向)网络基础协议与抓包原理-chrome开发工具-fiddler抓包-重放攻击(1)
爬虫(js逆向)js基础-函数进阶-原型链(prototype、proto、构造函数-this绑定对象(2)
爬虫(js逆向)非指纹built-in函数-js进阶-混淆与伪代码-常见反爬措施-爬虫逆向方法论(3)
爬虫(js逆向)调试干扰-处理debugger-调试检测-内存爆破-JS逆向举例(4)

对于前面文章的补充:

  1. 关于之前讲述的控制台打开检测原理

    看到一个页面,并非单存的是通过html组成
    实际上是:html+css+javascript 组成
    关于html、css文章,我的博客有非常详细的介绍
    html_后端工程师必备知识-这些你都懂了吗?大概3w多字
    CSS_后端工程师必备知识-从入门到劝退详解-呕心沥血撰写(滑稽)写了大概4W多字,自认为非常详细
    而javascript的知识内容在前面博客有提及,包含我的有道云笔记(简写常用)(详细的可以看w3c教程)

  2. Autoresponseder 替换注意事项

    Autoresponseder 是fiddler的一个功能,使用方式在第一篇js逆向文章已经非常的详细讲述
    实际上,比如直接打开百度,看到的页面源代码,html+css+js,可以通过fiddler拦截其中比如js,编写自己的js规则

  3. 关于js的一些作用域问题

    负责收集并维护由所有声明的标识符(变量)组成的一系列查询,并实施一套非常严格的规则,确定当前执行的代码对这些标识符的访问权限。

    var a = 1;引擎会在定义这个变量的局部中寻找,比如定义在某个函数内,在函数内没有查找到,那么会接着查找,直到找到
    否则报错

    LHS 与 RHS作用域查询机制是什么?

    var a = 1;  // LHS查询:赋值操作左侧的查询,LHS查询试图找到变量的容器本身,,从而对其赋值。
    console.log(a) // RHS查询:赋值操作右侧的查询,可以理解为“取到某某的值”
    

    相关文章:
    https://www.h5w3.com/57138.html
    https://www.h5w3.com/62830.html
    https://www.h5w3.com/70576.html
    https://www.h5w3.com/34296.html
    https://www.h5w3.com/32056.html
    https://juejin.cn/post/6844904033308655623

一、hook定义

  • Hook 技术又叫做钩子函数,在系统没有调用该函数之前,钩子程序就先捕获该消息,钩子函数先得到控制权,这时钩子函数既可以加工处理(改变)该函数的执行行为,还可以强制结束消息的传递。

  • 简单来说,就是把系统的程序拉出来变成我们自己执行代码片段。

  • 在js中,系统程序可以指浏览器API,也可以指代码中实现的一些方法等

  • 分类:手动hook\自动hook

1 为什么能实现hook

客户端拥有js的最高解释权,可以决定在任何时候注入js而服务器无法左右

只能通过检测和混淆手段令hook难度加大,但是却无法阻止。

2 hook目的是什么

js hook目的是找到函数入口以及一些参数变化,便于分析js逻辑

但是 hook的能力远不及此。我们只借助其寻找函数入口。

二、hook使用

1 hook步骤

  1. 寻找hook点 (确定目标,想要hook浏览器的document或者eval函数等等,window.a,或者相关参数)
  2. 编写hook逻辑
  3. 调试

2 函数hook公式:

func为需要处理的函数,赋值给一个新的备份变量old_func,重写需要处理的函数方法funcarguments为函数传入的参数
mytask为处理业务的代码,打印,也可以写一个debugger方便调试,然后return old_func.apply(arguments),返回这个函数的调用

old_func = func
func = function(arguments){
	mytask;
	return old_func.apply(arguments)
}

那么hook的原理是什么呢?

第三篇文章,提及了原型链,重写了函数的方法,那么会发生改变
eval举例,先看原生的eval
在这里插入图片描述
修改后,可以明显的发现,其原型链指向的内容发生变化
爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第1张图片
那么通过上面的eval举例,实际上为了应对反爬措施(开发业务代码的,判断原型链是否发生了变化),利用了hook,可以伪装没有被修改,需要抹除被hook的痕迹,也就是需要生成对应的 伪造指纹,下面第三节的第3小节有讲述evalhook完毕需要伪造正常的指纹,避免被发现

func.prototype..... = .......
func :要hook的函数

3 对象中属性hook公式:

3.1 defineProperty方法

相关文章1
相关文章2(这篇文章直白易懂)

基本语法: Object.defineProperty(obj, prop, descriptor)

  • 参数(obj): 被操作的对象本身
  • 参数(prop): 属性名称, 指定对象要修改或者新增的属性名
  • 参数(descriptor): 对属性的描述(如 value指定属性的值)

descriptor 属性详解

  • value: 需要设置属性的值(默认为 undefined)
  • writable: 该属性是否为可修改的(默认为 false)
  • configurable:是否可以配置descriptor中的属性是否可以修改(默认为 false 除了 value和writable属性外)
  • enumerable:该属性是否可枚举(默认为false)
  • set(): 该属性修改时会调用此函数(默认为undefined)
  • get(): 该属性获取时 会调用此函数(默认为undefined)

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第2张图片

3.2 实现方法

实际上是借助上面提到的 defineProperty方法,obj.attr 某属性进行复制一个新的变量old_attr

old_attr = obj.attr
Object.defineProperty(obj, 'attr', {
        get: function() {
            console.log(cookie_cache);
            return old_attr 
	},
        set: function(val) {
		 return  ......
}

通过案例说明公式原理,实际上,复制了浏览器document对象cookie值为1,然后将其赋值给一个新变量document.cookie_bak,结合definePropertydescriptor属性get,方法,当访问documentcookie的属性时候,会执行此函数,经过cookie_bak,伪装没有修改过,那么此时,访问document.cookie,时候,因为函数中编写了debugger,那么会进入到debugger状态,这样就成功了,那么调用堆栈,就可以找蛛丝马迹呢~~~

document.cookie = '1'
document.cookie_bak = document.cookie
Object.defineProperty(document,'cookie',{
    get:function(){
        debugger;
        return document.cookie_bak
    }
})
document.cookie

进入到debugger状态

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第3张图片

三、hook实操

st 2、9
bs2、10

1、应对cookie解密(st2)

下面新增set,调用创建的的适合进入debugger状态

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

调试前,打开script监听

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第4张图片
提前打开控制台,点击需要调试的网页,可以看到网页在加载且进入,只有触发F8,F10,F11这些才会加载script

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第5张图片
打开console,注入hook代码

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第6张图片
关闭script事件监听,并且单步F10调试,慢慢按,遇到一个debugger,右键行号,点击neve paue here,过debugger

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第7张图片
继续调试~~~
爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第8张图片
点击上一级调用后,找到了
爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第9张图片

2、应对cookie解密(st9)

修改下hook代码

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

经过注入代码,单步调试后

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第10张图片
一一查看堆栈

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第11张图片
可以看到,这是sign关键词

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第12张图片
将这段复制出来在控制台打印,每次打印都是不同变化

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第13张图片
骚操作(滑稽)

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第14张图片

  • 现在已经确定了cookie生成源代码地方
  • 那么剩下的就是如何扣下这些生成代码逻辑
  • 扣代码后面提及

3、通过eval确定debugger产生位置代码

debugger,有些并不会直接写出来,而是通过eval混淆调用,是看不到名称的,如果在解决了常规debugger情况,有些东西还是拿不到,就要考虑打开网站之前就要做debugger测试hook,是否是eval型debugger

构建eval方式的hook,且伪造指纹

eval_bk = eval
eval = function(val){
    debugger;
    return  eval_bk(val)
}
eval.toString = function(){
    return " function eval() [native code]"
}

注入hook,经过调试(其中测试的时候,我发现chrome无痕调试比较准确能够)

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第15张图片
向上找堆栈,发现是在这里进入的第二层,为此处调用的eval
爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第16张图片
继续F10 往下执行,进入了第二层代码,函数入口

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第17张图片

4、hook的弊端和缺陷

(1)函数hook 一般情况下不会出现hook失败的情况,只有可能是 proto 模拟的不好导致被检测到了。

(2)属性hook 当所有网站的逻辑都采用Object.defineProperty绑定后,属性hook就会失效。暂时没有发现好的解决方案。

第一次执行绑定没有问题,第二次绑定会报错,如果整个网站都用这个绑定的时候,代码绑定之前,可以hook,绑定之后无处理。

有些网站会自己写hook,如果尝试hook,hook失败的话,会写一个蜜罐逻辑,让调试者调试失效

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第18张图片

(3)局部hook,原理是一样的,只不过需要在进入作用域的那一刻进行hook。

如果不想手动写脚本,比如自定义通用脚本,可以借助油猴

四、hook插件:油猴脚本

chrome网上应用商店

搜 tampermonkey
爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第19张图片
下载后添加

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第20张图片
官方文档(最好去看,下面内容只截取一部分)

https://www.tampermonkey.net/faq.php?version=4.13&ext=dhdg&updated=true

1、油猴脚本参数介绍

红色的很重要

@name :脚本名,你爱叫什么叫什么。

@namespace :脚本的命名空间。(一般就是写个url,告诉自己用在哪里)。

@version:版本,你爱写多少写多少。

@author:作者,你爱写谁写谁。

@description:描述,你爱怎么描述怎么描述。反正别人也看不懂。

@homepage, @homepageURL, @website and @source: 一般正常人都不写这几个参数。从脚本名称链接到给定页面的作者主页。

@icon, @iconURL and @defaulticon:一般正常人都不写这几个参数,低分辨率脚本图标。

@icon64 and @icon64URL:一般正常人都不写这几个参数,高分辨率脚本图标。

@updateURL: 更新检查的url,@version参数开启,会向url检查更新。

@downloadURL:定时监测到更新会自动下载url内容,若为 none则不检查

@include @match @exclude:匹配规则相关。支持精确匹配与正则匹配。@exclude是排除,不写相当于脚本白写

@require @resource :导包,支持url引入。比如引入 jquery,可以使用$

@connect:标记定义域,感觉很有用,但是我菜,所以很少用

@grant:白名单函数:比如:@grant window.close 。很强大,如果默认不写则会对一些原生函数如:eval等进行保护,显然这不是我们所期待的,所以就直接 @grant none了

@antifeature :官方文档的意思:开发人员是否允许别人把脚本货币化。

@noframes:在主页上运行而不在iframes上运行。

@unwrap:卵用没有,官方文档的意思:在chrome上,不需要它,自动被忽略了(淦!)

@nocompat:一般默认,官方文档写了好长,大概的意思指支持标记浏览器。如:@nocompat Chrome,这样就不能在火狐浏览器运行它了。

逆向中最重要的参数!!!
@run-at: 指定油猴脚本在什么时候执行,默认是在所有js加载完成后执行。(那hook脚本还有个屁用啊!)
参数:
@run-at document-start :脚本尽快注入(相当于script断点之后,进入页面一瞬间注入)
@run-at document-body :如果页面body元素存在,则注入(所以练习平台第二题就注不进去了)
@run-at document-end :脚本将在DOMContentLoaded事件发生注入。
@run-at document-idle:默认值。脚本将在DOMContentLoaded事件发生之后才注入
@run-at context-menu:如果在浏览器上下文菜单中单击脚本(仅限于基于桌面Chrome的浏览器),则会注入脚本。

2、油猴脚本基本使用

示例网站:
http://cpquery.cnipa.gov.cn/

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第21张图片

将代码放入进去ctrl+s保存

// ==UserScript==
// @name         万能hook eval函数
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  eval-everything
// @author       An-lan
// @include      *
// @grant        none
// @run-at      document-start
// ==/UserScript==

// ==UserScript==
// @name         万能hook eval函数
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  eval-everything
// @author       An-lan
// @include      *
// @grant        none
// @run-at      document-start
// ==/UserScript==


(function() {
    alert('hook success');
    var eval_bk = eval;
    eval = function(val){
       debugger;
       console.log(val);
       return eval_bk(val);
    };
    eval.toString = function(){
         return "function eval() { [native code] }"
    };
    eval.length = 1;
})();

打开网址,成功!
爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第22张图片
如果没有自启动函数也能成功

// ==UserScript==
// @name         万能hook eval函数
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  eval-everything
// @author       An-lan
// @include      *
// @grant        none
// @run-at      document-start
// ==/UserScript==

 alert('hook success');
 var eval_bk = eval;
 eval = function(val){
    debugger;
    console.log(val);
    return eval_bk(val);
 };
 eval.toString = function(){
      return "function eval() { [native code] }"
 };
 eval.length = 1;

gif 动态演示,保存编辑好脚本后,打开网页,F5刷新,可以看到自动跳转到了debugger地方,这个时候就可以查看堆栈了
(滑稽,一开始漏写debugger语句进脚本,不会自动调到脚本,TMD找了15分钟原因)

调试的网址,不贴出来了!!!

开启油猴脚本后,在目标网址打开控制台,F5刷新网页,就能进来,接着就可以分析堆栈了~~

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第23张图片

五、hook补充

1. 局部函数的hook

    function a() {
        function b(a) {
            return a
        }

        // hook b的 arguments  a 为 5的时候打断点
        b_bk = b;
        b = function (val) {
            if (val === 5) {
                debugger;
            }
            return b_bk(val)
        }
        // 下面为业务逻辑代码
        b(1);
        b(2);
        eval('b(' + 5 + ')');
    }
    a()

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第24张图片

如何hooke到d呢?暂时没有思路。。。

function c() {
	let d = 2;
}

2. 全局变量的hook

Object.defineProperty(window, 'hook', {
        set: function () {
            debugger;
        }
    })

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第25张图片

3. 一些常用的hook逻辑

  • hook eval 、
  • hook Function 、
  • hook JSON.stringify、
  • JSON.parse 、
  • hook cookie、
  • hook window
  • hook String

实际上查看String相关的方法,可以通过hook下面的方式,得到非常多想要的内容
在前面已经提及了,如何编写hook

  1. 函数hook公式(新建变量,重写函数,伪造指纹(原型链))
  2. 属性hook公式(新建变量既操作的对象属性,通过defineProty,编写hook)

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第26张图片

六、验证码实现原理

1、基本原理

所有验证码都是基于以下原理,验证码本质上就是交互过程与模拟过程

  • 交互过程:可以机器学习方式实现等等
  • 模拟过程:如果难一点纯走协议,就需要逆向js等等

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第27张图片

2、交互验证过程举例(ds8)

比如这是一个验证码
爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第28张图片

利用fiddler抓包工具

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第29张图片

通过base64解密,验证码图是在img中的链接中加密请求

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第30张图片
并且请求服务端,响应后设置了一个cookie

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第31张图片

那么经过人为点击处理完毕验证码,会携带上面的cookie,以及下面的图片点击的坐标,请求点击后的接口,那么服务端就会校验,成功的话会返回一个成功的cookie(此时会删除之前的cookie)或者其它参数,表示用户通过,前端js缓存的内容可能会存在校验

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第32张图片

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第33张图片

这个时候就会成功获得数据
爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第34张图片

市面一线的验证码,都会将请求的参数进行加密,不可能像上面的的案例看到数字,后端会去再将加密的解码。

3、一线验证码

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第35张图片

捕获了如下请求

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第36张图片
在用户操作成功后,再请求一个接口,返回了token,通过这个token,当前页面,会将这个token会传向后端就会二次验证,整个过程就是如此

在这里插入图片描述

4、解决方案

  • 机器学习处理验证码
  • 得到加密参数
  • 通过session保持会话请求

补充session和cookie的关系:

首先cookie是服务端识别客户的唯一标识的依据,客户在访问网站时候,服务端为了记住这个客户,会在服务端按照它的规则制作一个cookie数据,会将这个cookie数据保留在服务端一段时间,同时会给客户的一份它自己保留,这样就无需每次都要登录来认证自己了。

先来了解几个概念。

1、无状态的HTTP协议:

协议是指计算机通信网络中两台计算机之间进行通信所必须共同遵守的规定或规则,超文本传输协议(HTTP)是一种通信协议,它允许将超文本标记语言(HTML)文档从Web服务器传送到客户端的浏览器。

2、HTTP协议是无状态的协议。
一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接。这
就意味着服务器无法从连接上跟踪会话。
3、会话(Session)跟踪:

会话,指用户登录网站后的一系列动作,比如浏览商品添加到购物车并购买。会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术

是Cookie与Session。Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定

4. 从爬虫(验证码)角度来看,是以set-cookie建立了连接(以抓包情况演示验证码) 【当然了,不一定是以set-cookie的形式,还有可能是以接口API形式返回,反正无论如何,必须让服务器给你标记一下】

七、js逆向核心-扣代码-补环境-jsRPC

抠代码的三个阶段:

A.  缺啥补啥,稳扎稳打

B.  见文知义,化繁为简

C.  了然于胸,如履平地

1、扣代码优缺点

优点:

  1. 执行效率高
  2. 并发能力强
  3. 能感受到进度(抠出一行是一行)
  4. 只要有耐心,笨办法也能成大事

缺点:

  1. 比较吃经验,只有勤学苦练才能更快
  2. 若想精通则对js基础要求较高(尤其是对于浏览器API的掌握程度)
  3. 网站即使微调,js可能就会失效
  4. 做不到完全还原浏览器的某些值,对风控响应不够及时。

2、补环境优缺点

优点:

  1. 复用性强、开发速度快
  2. 有现成的库可供调用(如 jsdom)
  3. 简单网站,相对于抠代码,对熟练度要求更低
  4. 仅需对服务器的混淆代码做少量处理即可。

缺点:

  1. 占用资源大,计算速度可能慢
  2. 若想高并发可能需要开发多种浏览器环境,增加时间成本
  3. 对于极复杂的网站,可能更靠玄学。无法感受到进度的变化
  4. 若想精通则对需对node指纹和浏览器API都足够精通

3、jsRPC

JavaScript RPC 的简单实现过程是:

在客户端JavaScript脚本中,将要调用的服务端PHP函数名和函数参数(本地的JavaScript变量值)作为要传输的数据,通过Ajax传输到服务端,同时,Ajax设置一个回调函数,以便使用服务端函数的返回结果。在服务端PHP脚本中,接收Ajax传输的数据,从中取出要执行的函数名和函数参数。然后执行指定的函数,并将执行函数的返回值作为传输的数据,直接输出到浏览器,以此作为响应AJax的请求。客户端的Ajax在接受服务端的响应后,把返回的数据传递给AJax的回调函数。到此完成了一个RPC的流程。

八、扣代码实战

st2,bs2

1、cookie参数加密入口捕获(st2)

直接请求这个网址,返回的是script脚本

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第37张图片

写一个hook,捕获cookie

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

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第38张图片
过debugger

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第39张图片hook到cookie

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第40张图片

查看右边堆栈,定位到了代码

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第41张图片
核心步骤:扣代码,复制代码

 document[_$ob('0x35')] = a[_$ob('0x47')](a[_$ob('0x1')](a['NpWYd'](a['gpbdE'](a[_$ob('0x5e')](a[_$ob('0x2')](a[_$ob('0x48')], Math[_$ob('0x1c')](a[_$ob('0x11')](c, 0x3e8))), '~'), token), '|'), md), a['zQTqr']);

核心步骤:定义一个变量去接收,创建一个test.js文件存放代码

 var cookie  = a[_$ob('0x47')](a[_$ob('0x1')](a['NpWYd'](a['gpbdE'](a[_$ob('0x5e')](a[_$ob('0x2')](a[_$ob('0x48')], Math[_$ob('0x1c')](a[_$ob('0x11')](c, 0x3e8))), '~'), token), '|'), md), a['zQTqr']);
扣代码,就是缺啥补啥

引入眼帘的是a,是一个对象,那么还是不知道a是什么,继续向上看a

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第42张图片
搜索var a ,定位当定义a的方法,( 可以其它方法搜索,查找,能定位到就是好方法)

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第43张图片
将这一段复制到test.js

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第44张图片
现在查看 a 里面缺什么(采用深度优先,需要解决a及其相关,再考虑广度优先),现在解决_$ob

在这里插入图片描述
鼠标放置上面,点击进入

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第45张图片

定位到此处,复制到test.js

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第46张图片
可以看到_$oa是啥不知道,那么需要重复上面的步骤,定位复制
爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第47张图片
_$oa是一个数组

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第48张图片
搜索_$oa,在上面可以看到,是将_$oa进行数组移位生成的

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第49张图片
复制_$oa,分为静态,跟动态方式

静态(直接复制数组):

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第50张图片

动态(复制逻辑代码):

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第51张图片

到这一步感觉上是都扣代码完成了,那么可以直接运行脚本,发现c没有定义

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第52张图片

定位到了c,并将其复制test.js

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第53张图片

再次运行,发现token没有定义,复制粘贴,一运行发现window没有定义,这是因为node.js没有

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第54张图片
定义window

在这里插入图片描述
再次运行,不难发现,window中没有btoa,即每页base64方法

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第55张图片
base64个人是建议手写出来,但是注意是否被魔改(没有魔改),安装nodejs中btoa包

npm install btoa

也可以pycharm手动安装

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第56张图片

导入包

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第57张图片

再次运行 发现md没有定义

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第58张图片
继续复制md

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第59张图片
再运行,hex_md5 没有定义

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第60张图片
继续找

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第61张图片
点击后,发现是引入的第三方库

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第62张图片
可以复制整个粘贴进去,但也扣需要的

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第63张图片

继续扣~~~

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第64张图片
继续

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第65张图片
继续

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第66张图片

继续

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第67张图片
继续

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第68张图片

继续~。。。

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第69张图片
再次运行

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第70张图片
实际上这些都要

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第71张图片
再运行~~~~(QAQ 痛苦~~)

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第72张图片
扣完再运行

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第73张图片

继续扣,最后运行,不报错!!!nice

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第74张图片

打印一下cookie看看,逻辑完成

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第75张图片

但是还不够,希望的是,python去调用cookie,写一个python脚本,调用js,运行代码,成功打印页面html,而并非是js代码~~~,芜湖~~~通过!!!!

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第76张图片

2、cookie参数(bs2)(浏览器指纹检测与格式化检测)

  1. 格式化检测
  2. 内存溢出

猿人学大赛第二题


注入控制台hook脚本

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

然后就是看堆栈,扣代码~~~省略步骤说明!!!!

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第77张图片

通过堆栈确定是这些

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第78张图片

查找 _0xe54e90,可以看到,这个变量是由_0x2b293a定义而成

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第79张图片
继续扣
爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第80张图片
补完上面代码,一运行,缺少,继续找

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第81张图片
省略说明。。。。
爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第82张图片
爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第83张图片

最后补完后,一运行,报错

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第84张图片
将代码复制到控制台(检测是否浏览器指纹检测)

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第85张图片
错误发现跟本地运行一样的错误,得出结论(格式化检测,并不是指纹检测)

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第86张图片
将代码复制继续排查是否内存泄漏,不过现在,添加个debugger语句

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第87张图片

回车运行后,F11调试,找到内存溢出的地方,可以看到疯狂的在这运行,进入死循环

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第88张图片

进入死循环原因是,这个分支判断,进行调用了setcookie方法

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第89张图片

最简单的方式,是直接修改这个,但是,可能会产生一些问题,可能会影响后续,分支判断

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第90张图片

继续往上找,不能发现是一个正则处理方法,利用这个方法,test方法调用toString方法
爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第91张图片
那么手动修改removeCookie,实际上是检测这个有没有被格式化,将其手动调整不要格式化

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第92张图片
此时运行还是错误状态,继续在console。调试,又进入循环,


实际上这是一个数组移位问题

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第93张图片

跳过这个,不然F11半天

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第94张图片

接着F11调试的时候,浏览器卡死,内存溢出!!!!!!!!!!!!

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第95张图片
对应在此处打上debugger;
爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第96张图片
可以看到,又有格式化检测,并且RegExp

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第97张图片
处理正则匹配这个函数。去除格式化

再次运行,发现终于没有卡死了,出现了未定,未定义好解决呀。。继续扣代码

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第98张图片
继续运行

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第99张图片
进入
爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第100张图片

一运行还是进入了执行状态,卡死,没有出来
爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第101张图片

去掉debugger,浏览器又出现了卡死,在下面地方继续debugger;找出卡死原因,即调用这个函数地方上面打上debugger

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第102张图片
而后在这里触发了卡死

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第103张图片
删除上一个debugger后,在卡死上方继续debugger,发现这里一运行就灰色卡死(缩小了范围)

爬虫(js逆向)hook实现方式-油猴脚本-javascript抠代码实战-硬抠高度ob混淆-应对内存溢出-debugger缩小范围(5)_第104张图片

后面步骤省略,都是重复性,利用debugger缩小方位,扣代码

唯一提及的 global,看到这个就要想到是否重写了函数,实际的确重写了函数

  • navigator 未定义,将其置空 这是一个浏览器指纹
    在这里插入图片描述

  • 而后就是,最后打印cookie的时候,会发现console.log方法实际上已经 被重写,利用hook方法重写打印即可

在这里插入图片描述

七、总结

1、如何编写hook函数(一般hook、对象属性hook)
2、油猴脚本使用方式
3、扣JavaScript代码流程
4、逐步利用debugger;去缩小出现内存溢出地方
5、浏览器指纹置空
6、global关键字,要思考是否内置方法被重写


补环境、jsRPC之后文章写

bs(1、2、5、6、9)

你可能感兴趣的:(爬虫逆向-javascript,javascript,python,逆向,hooks,混淆)