概述:本文将用于了解爬虫中localStorage的检测原理以及讲述一个用于检测localStorage的反爬虫案例,最后对该参数进行Hook断点定位
目录:
三、如何破解?(Hook如何断点定位到localStorage)
LocalStorage 是一种 web 端的存储机制,主要用于在本地上存储一些用户的信息
从反爬的角度上看,在一些网站中,他会将一些指纹数据(如设备信息,版本号,鼠标,用户行为等等)存储在LocalStorage中用于反爬的计算,通过分析这些参数是否异常来判断是否为爬虫。
LocalStorage的特性:
1、localStorage可以将请求的数据直接存储到本地,这个相当于一个5M大小的前端页面数据库,相比于cookie可以节约带宽。
2、目前所有的浏览器中都会把localStorage的值类型限定为string类型,要使用JSON对象类型则需要一些转换。
3、localStorage在浏览器的隐私模式下面是不可读取的。
4、localStorage不能被爬虫抓取到。
也是由于最后一个特性,在爬虫中会被经常用于指纹的验证
在某盾网站中的 xxxxxxxxNjc50Q==:c 便是藏在了 LocalStorage 的参数里面,而这个Njc50Q==:c是其指纹校验的一个重要生成的参数
下面我们将Hook定位到这个参数的位置
在Hook之前,首先要了解这个参数的赋值原理:
要在 web 应用中使用 localStorage,首先要熟悉它提供的属性和方法:
length:返回 localStorage 中的键值对的数目
setItem():增加一个键值对到 localStorage 中
getItem():从 localStorage 中查询指定 key 的值
removeItem():从 localStorage 中删除指定的键值对
clear():清空 localStorage 中所有键值对
key(): 传入一个数字 n,用于返回指定第 n 个键的名字
根据localStorage在赋值时需要使用到.setItem方法这个特性
使用Hook来改写setItem方法定位到 key(即arguments[0]) 的最后一位数为 ":d" 的赋值位置
let s = Storage.prototype.setItem
Storage.prototype.setItem = function() {
if (arguments[0].endsWith(':d')) {
debugger
}
return s.apply(this, arguments)
}
在浏览器的控制台中实验一下:
当出现localStorage.setItem('xxxxxxxxxxx:d','2') 赋值2时,会进行断点:
由于每次刷新,控制台中的Hook都会被刷新掉,此时需要借用 油猴 来写一个Hook脚本
油猴网址:https://www.tampermonkey.net/
某盾滑块网站:aHR0cHM6Ly9kdW4uMTYzLmNvbS90cmlhbC9qaWdzYXc=
在油猴上编写脚本,保存并启动
注意:@match 为此脚本针对的目标网站接口,这个不能随意改动!!
// ==UserScript==
// @name yidun
// @namespace http://tampermonkey.net/
// @version 2023-12-27
// @description try to take over the world!
// @author You
// @match https://dun.163.com/trial/*
// @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @grant none
// ==/UserScript==
(function() {
'use strict';
let s = Storage.prototype.setItem
Storage.prototype.setItem = function() {
if (arguments[0].endsWith(':d')) {
debugger
}
return s.apply(this, arguments)
}
})();
保存之后记得点击启动即可,接着打开某盾滑块的链接
打开控制台调试一下确认是否能Hook到,还是输入localStorage.setItem('xxxxxxxxxxx:d','2')来测试一下:
此时这里能被断住说明是正常,先在控制台输入localStorage输出一下
发现是值是已经生成好了,我们目标是还原他生成的过程,因为我们要先将localStorage清空,输入 : localStorage.clear()?
在清空之后刷新一下该网站,发现已经成功被断住,剩下的就是如何扣代码的问题了