爬虫(js逆向)调试干扰-处理debugger-调试检测-内存爆破-JS逆向举例(4)

如果本文有任何问题错误,欢迎评论指正!

前面文章:

爬虫(js逆向)网络基础协议与抓包原理-chrome开发工具-fiddler抓包-重放攻击(1)
https://blog.csdn.net/weixin_44238683/article/details/118468491
爬虫(js逆向)js基础-函数进阶-原型链(prototype、proto、构造函数-this绑定对象(2)
https://blog.csdn.net/weixin_44238683/article/details/118503753
爬虫(js逆向)非指纹built-in函数-js进阶-混淆与伪代码-常见反爬措施-爬虫逆向方法论-(3)
https://blog.csdn.net/weixin_44238683/article/details/118530864

一、常见反爬措施

对于第三篇文章的补充

1、刷新cookie

同一个接口,第一次请求,没有携带cookie,会存在看不到js,第二次会重定向请求才能可能到数据

解决方法:利用抓包工具,session请求,生成cookie措施

2、ajax请求

在这里插入图片描述

如何确定是ajax请求,可以通过观察页面某些元素,比如标题,点击相关按钮,页面部分刷新,可以确定是ajax请求

  • 发现规律

3、什么是node.js

简单的说 Node.js 就是运行在服务端的 JavaScript。

Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台。

Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常好。

借助node.js 可以通过python代码实现调用js

4、python执行js代码原理

python如何运行js代码,需要借助node.js,需要借助第三方库pyexcejs

5. 构造器的深入理解,如何从根源上修改隐式 new Function

a = function(){}
Function.prototype.constructor = function(){} 

二、调试干扰

无限debugger,并不是真正意义上的
死循环debugger,会让整个页面卡死,要么在业务代码前,要么业务代码之后
无限debugger,还有一个非常靓丽的名字,叫debugger地狱
所以无限debugger真正,在业务操作的时候,只是实现很频繁的debugger,而不是真正的死循环

因此安全实现一个debugger是用setTimeout()或者setInerval,但是这个循环一定时有次数限制的

1、debugger实现方法

下面这个网址就存在debugger,出不去

http://cpquery.cnipa.gov.cn/index.jsp

1.1 html或console实现debugger

console实现

function a(){debugger;}

html实现
在这里插入图片描述

1.2 eval实现debugger

实际上,通过eval实现debugger,是创建一个虚拟机,操作成本提高,但是无论怎么变化,都有debugger关键字

在这里插入图片描述

1.3 通过function实现debugger

Function('debugger').call()   
Function('debugger').apply()
a = Function('debugger').bind()
a

1.4 函数与匿名函数实现debugger

函数

function a(){}   
a.constructor('debugger').call()

匿名函数,这些都是在匿名函数堆栈没找不到

Function.constructor('debugger').call()
setInterval(function(){debugger;},9000)

1.5 高度混淆debugger

可以通过相关参数替换,类似jsfuck(前面文章提及)

+!+[]
1
a = 'deerere'
"abcd"
eval(a[+[]] + 'ebugger') //相当于 eval('debugger')

可以明显看到是由个数组 拼接成debugger单词
在这里插入图片描述

2、处理debugger

无限debugger的处理实际上很简单,有以下几种情况

  1. 无限debugger贯穿全局
    干掉定时器等全局事件(置空或重写)

  2. 无限debugger在加密逻辑之前
    详细讨论

  3. 无限debugger在加密逻辑之后
    不用管,script/第一行断点打上,从头开始

2.1 无限debugger贯穿全局

2.1.1 重写定时器

业务代码之前,创建一个debugger

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    function a() {
        debugger;
    };
    setInterval(a, 500);
    alert('1111')
</script>
</body>
</html>

可以发现,进入了debugger状态,到达不了业务代码
在这里插入图片描述

因为业务代码在debugger之后(debugger在业务之后也可以),如果将setInterval定时器重写,那么是没有影响的,在console执行下面方法就可以跳出无限debugger

这种方式相当于hook(hook是能被检测到的)

setInterval_back = setInterval
setInterval = function(a,b){
	if(a.toString().indexOf('debugger') != -1){ //证明有无限debugger
	return setInterval_back(a,b)
	} 
}
2.1.2 置空定时器

置空前提是,业务代码没有涉及定时器用法

setInterval =function(){}

2.2 无限debugger在加密逻辑之后

业务代码已经执行完毕了,debugger没有意义,如果想知道业务代码具体生成,那么在业务代码之前打上断点即可

2.3 无限debugger在加密逻辑之前

1. 业务代码没有涉及setinterval定时器置空或者修改

跟2.1节一样逻辑

2. 添加条件断点,永远不再这停
  • 针对debugger没有创建新的虚拟机好用

http://cpquery.cnipa.gov.cn/index.jsp
在这里插入图片描述
在这里插入图片描述

3. 利用fiddler autoresponse或者Overrides删除debugger

存在弊端,定位位置不好找

添加映射规则,比如,在一些网站,专门编写了一个debugger.js文件,利用fiddler添加规则到此文件,在本地自定义了一个空的debugger.js文件,这样就可以过了,同样devtool工具中overrides也是可以的

这样的话就不会读浏览器缓存,而是读本地的js文件

如何添加规则,使用方式见:https://blog.csdn.net/weixin_44238683/article/details/118468491 第一篇文章

2.4 针对真动态文件或Autoresponse失效或删掉debugger逻辑很繁琐的情况下

  1. 如果是 Function 原理的 debugger,可以重写 函数构造器
  2. 如果是eval型的构造器,可以重构 eval函数
  3. 如果是定时器,并且2失效了,可以重构定时器
  4. 在以上方式都失效时,向上找堆栈,在进入无限debugger之前打上断点将触发无限debugger的函数置空(最麻烦,但是适用性最广)
1.(过Fcuntion debugger)利用hook,游猴脚本,注入进去
Fcuntion.prototype.constructor_bc = Function.prototype.constructor
Function.prototype.constructor = function(){
	if(arguments[0] === 'debugger'){}
	else{
		return Function.prototype.constuctor_bc.apply(this,arguments)
	}
}
2.eval型
eval_bc = eval  
eval =function(a){
	if (a===='debugger;a=asdasdasdas')
	return eval_bc(a)
}
3.定时器

置空或者重写,前面提及

4.调用堆栈
  • 以上都失效的话,调用堆栈
  • 最麻烦,但是适用性最广,置空

打上断点一步步调试,找到debugger

三、调试检测

1.F12无法打开开发者工具

手动打开开发者工具,火狐浏览器,等换个浏览器

2.检测到打开开发工具,出现js干扰

js调试,一定需要在函数定义之后,即需要调试的js特定加载完成后,才进行重写调试函数,否则js都没有定义,提前操作没有任何意义

  • 利用script断点并且先尝试进行关键词搜索找线索。

  • 随机打上断点,不断缩小检测范围,直到找到。

  • 若是静态js/假动态直接可以Autoresponse干掉。

  • 若是真动态则在执行控制台检测逻辑附近的时候重置函数
    (这个可以参考无限debugger处理方案,重写函数,hook关键位置等)

在这里插入图片描述
干扰:出现鼠标禁止,跳转上一页,播放音乐,出现提示,内存爆破,等等一系列骚操作

2.1 跳转上一页

调试过程当中,按F9下一步,发现js文件,一直会回到上一页的js文件,可以搜索关键词,
urlopengoto、等等,并且记住上一页的url名称,跳转上一页,那么一定会方法指向这个url,
因此搜索上一页的url,或者出现跳转后的url也是可以的

2.2 控制台检测原理

利用了console

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    var x = document.createElement('div');
    //绑定了一个 id属性
    Object.defineProperty(x, 'id', {
        get:function() {
            alert('1111')
        }
    });

    function use() {
        console.log(x);
        console.log('禁止调试!!!!!!!')

    }
    setInterval(use, 200);
</script>
</body>
</html>

可以看到控制台疯狂输出禁止!!!,还有生成console.log(x)创建div标签
在这里插入图片描述

2.3 内存爆破

可以类似,上面的样式,检测到调试等,疯狂的在js文件,或者html中进行读写,cookie重写追加,字节追加,导致内存不足够,卡死

内存爆破,指js通过死循环/频繁操作数据库(包括cookie)/频繁调取history等方式,使浏览器崩溃的一种反调试手段。关键词:频繁

还有一种特性情况:js文件很大,电脑内存不足(这种情况在调试层面几乎无解)

特点:

  1. 正常运行时,一切正常
  2. 调试时利用时间差,调试特点等讲控制流推入循环
  3. 利用正则/toString() 判断代码是否进行格式化
  4. 利用浏览器指纹判断是否为浏览器环境

2.4 OB混淆,正则匹配,判断tostring()长度变化,出现的内存爆破

先了解js中正则的test()方法

test() 方法用于检测一个字符串是否匹配某个模式.

返回一个 Boolean 值,它指出在被查找的字符串中是否匹配给出的正则表达式。 regexp.test(str)

参数

regexp 必选项。包含正则表达式模式或可用标志的正则表达式对象。 str 必选项。要在其上测试查找的字符串。 说明 test
方法检查字符串是否与给出的正则表达式模式相匹配,如果是则返回 true,否则就返回 false

tostring()检测原理,如果调用了控制台console,那么会改变tostring()后的长度,定义了一个a函数,通过toString()方法改变了原有的长度,如果将代码拉到本地,格式化等操作。一定会出现下面变化,内存爆破可以检测这一点

在这里插入图片描述

st9

案例

一般来说在,在js文件中看到了如下图格式的样式,一般为OB混淆,利用正则RegExp关键词搜索
在这里插入图片描述
那么搜索RegExp

在这里插入图片描述
在这里插入图片描述

2.5 如何处理内存爆破

针对2.4节,可以将函数逻辑作为正则取反,实际上内存爆破没有通解,需要具体情况具体分析

寻找蛛丝马迹

四、JS逆向-调试实战

bs12、13
st1、2

案例1: ajax请求参数加密

  1. 一般来说,先尝试全局搜索,如果是(sign,afsdfsd一些辨识度高的适用)
  2. XHR搜索(需要开启XHR fetch)
  3. js文件内搜索(堆栈调试)

在这里插入图片描述
点击下一页,发现m出现变化
在这里插入图片描述
全局搜索m,可以发现太多m了,无法分辨
在这里插入图片描述
可以看到m的生成方式,产生了,是通过base64加密
在这里插入图片描述

打上断点,翻页尝试,并在控制台输出,与第一幅图一致

在这里插入图片描述
实际上还要校验,是否base64加密方法是否被魔改过
在这里插入图片描述
随便找个base65工具验证,发现一致
在这里插入图片描述
代码实现略~~~

案例2: cookie刷新变化

bs13

第一次请求2,3页
在这里插入图片描述
间隔一段时间,发现cookie变化,这个时候,就需要逆向cookie生成方式
在这里插入图片描述
抓包工具
在这里插入图片描述

在控制台复制打印,所以就是一个拼接过程
在这里插入图片描述
代码实现:

直接访问,没有携带cookie,是得不到数据的,通过抓包工具,是先请求得到一个有效cookie之后,二次请求才能得到值
在这里插入图片描述
因此处理第一次请求返回的参数,生成cookie
在这里插入图片描述
携带cookie访问,可以看到得到数据

在这里插入图片描述

案例3: 请求头headers加密参数

下图是分别翻页后,有个safe参数变化

在这里插入图片描述

因此采用全局搜索的方式,相对前面的ajax请求m参数,safe这个单词具有辨识度
可以看到,设置请求头headers,这个参数来自tokens,并且这个参数是通过 base64加密a字符串(’9622’),并且再转md5,显而易见
(其中要注意,md5,base64加密方法是否被魔改,要进行验证)

在这里插入图片描述

案例4:hook技术

下一篇文章撰写~~!!

  • 14
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值