爬虫学的好,牢饭少不了。
——坊间流传
爬虫是什么?我不再说了,除非村里刚通上网,你总会知道或是听说过爬虫。
既然讲的是爬虫那么为什么标题是JS反爬呢?
咳咳,一句话:时代变了~
十年前,国内网络有大量的数据泄露、黑客攻击,防护措施基本为0,丝毫没有安全意识。
十年后,各安全厂商纷纷崛起,开始重视网络安全……(越扯越远)
不讲历史了,这篇文章主要是列举了一些非常规情况下的反爬虫手段。
浏览器全局对象检测
对window,navigator,Location等浏览器全局对象进行检测,以及navigator是否freeze
这类检测的范围较广,尤其对于一些浏览器异于非浏览器下对象,例如Fingerprint2中检测了一些常见的浏览器数据
User-agent | navigator.userAgent |
osCpu | 操作系统类型 |
cpuClass | 浏览器系统的 CPU 等级,一般无法获取 |
platform | 返回表示浏览器平台的字符串,该规范允许浏览器始终返回空字符串,因此不要依赖此属性来获得可靠的答案 |
hardwareConcurrency | 返回可用于运行在用户的计算机上的线程的逻辑处理器的数量navigator.hardwareConcurrency |
deviceMemory | 以千兆字节为单位返回设备内存量。该值是通过舍入到最接近的2的幂并将该数除以1024而给出的近似值 |
availableScreenResolution | 返回屏幕分辨率[width,height],无头浏览器无法获取 |
colorDepth | 目标设备或缓冲器上的调色板的比特深度 screen.colorDepth |
languages | 语言 |
screenResolution | 屏幕宽高,并根据屏幕方向矫正返回值[width,height] |
pixelRatio | 像素比 devicePixelRatio |
timezoneOffset | 从当前区域设置(主机系统设置)到UTC的时区差异(以分钟为单位) |
timezone | 时区 |
addBehavior | 此时可能未定义body或以编程方式删除 |
indexedDb | 是否支持 indexedDb |
localStorage | 是否支持 localStorage |
sessionStorage | 是否支持 sessionStorage,不支持时返回错误 |
openDatabase | 是否支持 Web SQL |
doNotTrack | 返回用户的“不跟踪”设置。如果用户请求不被网站,内容或广告跟踪,则为“1” |
plugins | 浏览器安装的插件列表 |
canvas | 浏览器支持canvas则返回生成baes64数据 |
webgl | 浏览器对webgl绘图协议的支持情况汇总 |
webglVendorAndRenderer | 显卡型号相关信息 |
adBlock | 是否安装去广告插件 |
hasLiedLanguages | 用户是否改变了首选语言 |
hasLiedResolution | 用户是否改变了分辨率 |
hasLiedOs | 用户是否改变了操作系统 |
hasLiedBrowser | 用户是否改变了浏览器 |
touchSupport | 最大触摸点数,是否支持touch,是否支持ontouchstart事件 |
fonts | 返回从64种字体种筛选出的可用字体 |
fontsFlash | Flash字体枚举,如果没有swfobject,不会触发 |
audio | 音频指纹 |
enumerateDevices | 请求可用媒体输入和输出设备的列表,例如麦克风,相机,耳机等navigator.mediaDevices |
图像绘制能力与DOM检测
浏览器特有的canvas,document,Image对象都是相应的检测点
上面的Fingerprint中也提到,使用了canvas进行绘制,并进行type,quality校验
document则更易检测,例如:对document.body
添加节点删除节点,访问document.cookie
,以及一些documen特有的属性和方法
浏览器自动化检测
你可能会想,既然不能脱离浏览器环境,那我使用selenium或phantom一类的自动化平台不就可以跳过这些检测了?
你想得到的,别人也能想得到~
对这些自动化工具进行痕迹检测,也是反爬手段之一
下面例举一些selenium下的特征
webdriver
__driver_evaluate
__webdriver_evaluate
__selenium_evaluate
__fxdriver_evaluate
__driver_unwrapped
__webdriver_unwrapped
__selenium_unwrapped
__fxdriver_unwrapped
_Selenium_IDE_Recorder
_selenium
calledSelenium
_WEBDRIVER_ELEM_CACHE
ChromeDriverw
driver-evaluate
webdriver-evaluate
selenium-evaluate
webdriverCommand
webdriver-evaluate-response
__webdriverFunc
__webdriver_script_fn
__$webdriverAsyncExecutor
__lastWatirAlert
__lastWatirConfirm
__lastWatirPrompt
当然,还有许多其他的特征和检测点未曾提及,这里不作补充了。
非浏览器环境运行检测
我若是把检测的环境都通过自定义补上了呢?
可以,但你需要不断地补充,不断的修改~
这里提一下Node下对require的检测
用过node的应该都知道,node有一个特征是浏览器没有的,那就是require,当然处理很简单,只需要重新定义require就能实现跳过
另一个特征:异常堆栈
node运行出现异常时会发生类似于下面的异常堆栈
D:\NodejsProjects\node\1.js:1 console.log(self.locatwion.host); ^ ReferenceError: self is not defined at Object.<anonymous> (D:\NodejsProjects\node\1.js:1:13) at Module._compile (internal/modules/cjs/loader.js:1137:30) at Object.Module._extensions..js (internal/modules/cjs/loader.js:1157:10) at Module.load (internal/modules/cjs/loader.js:985:32) at Function.Module._load (internal/modules/cjs/loader.js:878:14) at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12) at internal/main/run_main_module.js:17:47
而浏览器则是这样
检测什么,聪明的你一定猜得到~
Native函数重写检测
检测对象是否属于对应的类
Window方法及toString方法输出是否包含native code
同样的,可以使用以下代码进行填坑
var originString = Function.prototype.toString; Function.prototype.toString = function () { if (this == Window || this == Location || this == Function.prototype.toString) { return "function Window() { [native code] }"; } return originString.apply(this); };
浏览器指纹计算及Cookie校验
前面提到的fingerprint的最终目的就是计算浏览器指纹
那么通过cookie或Header提交指纹至服务器校验并记录,就能够实现反爬的最终目的了
结语
天道有轮回,苍天饶过谁~既然有了反爬,必然会有反反爬,而后就会有反反反爬……无限套娃ing…
正如CTF中的攻防模式,双方总会进行一番较量,若问谁嬴谁输,也许是这样一副情景:一夫当开,万夫莫关(瞎扯的)
发表回复