网站七处罚信息反爬破解
前情回顾:
本次破解的网站其实在前面的文章中已经有过了,具体可以参考这篇博客:
https://forchenxi.github.io/2019/09/20/spider-bankofchina/
本次是网站反爬有所升级,所以破解流程也是基于上一次的升级,所以看这篇文章前你需要先补习一下上面那篇。
正式开始:
首先跳过无限Debug
本次网站升级后,当我们按下F12
开始调试时,浏览器会出现无限Debug的情况:
我们只要把鼠标放到Debugger前面的序号3上面,点击鼠标右键,选择Never pause here
就可以解决了。
wzwschallenge
参数
上一次破解时,我们需要获取的就是这样一个东西(省略了前缀):/WZWSREL3poZW5nd3Vnb25na2FpLzEyNzkyNC8xMjgwNDEvMjE2MTQyMS9pbmRleC5odG1s?wzwschallenge=V1pXU19DT05GSVJNX1BSRUZJWF9MQUJFTDg2MzAxMQ==
通过发送这样一个请求来获取cookie,从而成功获取到数据。
而且当时,改变的只有wzwschallenge
参数的值,前面那部分是固定的,下面来看下本次网站改版后是什么情况:
我们在请求主页时,网站返回的js
文件内容我放在了文章末尾,为防止有小伙伴看的时候,网站已经改版,所以这里贴出了返回的源代码,如果可以实际调试,可以直接看下面的内容哈。
在看这个代码的时候,应该很容易看到这部分信息(根据上次的破解经验,这个信息比较有用)
然后在调试的过程中,我们应该能够比较快速的定位到这里(也是依赖于上次的破解经验):
这里的_0x59fc72
变量的值是WZWS_CONFIRM_PREFIX_LABEL13732072
,这个值的形式和我们要找的wzwschallenge
的形式完全一样,所以大胆推测,我们要找的就是这个变量,那么接下来我们就看到底如何自己生成wzwschallenge
。
入手点就是这行代码:
var _0x59fc72 = _0x41b344[_0x4ce3('155', '7ktK')](_0x13698a);
选中_0x4ce3('155', '7ktK')
这部分内容得知其值为:KgBWV
查看_0x41b344
的KgBWV
属性为:
1 | 'KgBWV': function(_0x423ba6) { |
实际上就是执行传入的参数(该参数是一个方法),那这里意思就是执行_0x13698a
,我们找到这个方法如下:
1 | function _0x13698a() { |
这里又依赖了_0x4ce3
方法,同样找出来:
1 | var _0x4ce3 = function(_0x2bafd4, _0x250b3f) { |
这个时候如果你尝试去执行_0x13698a()
,会发现很多问题,这里就根据实际破解过程的顺序逐个来解决问题
数组初始化陷阱
首先会遇到_0x14f9 is not defined
的问题,我们在源代码里可以找到这个变量:
1 | var _0xodK = 'jsjiami.com.v6' |
然后继续执行,首先遇到的应该是“死循环陷阱”,所以这里大家可以先看下面的内容,之后再回过来。
当我们发现_0x4ce3('7b', 'SLM$')
计算得到的值有问题时,同样的也是在浏览器中去调试,查看其在浏览器中得到的值是多少
经过调试,发现浏览器中计算的值为_0x4ce3('7b', 'SLM$')=KPghK
,而我们计算得到的却是乱码,所以问题应该是出在_0x4ce3
方法内部,进入到方法内部调试,发现在这个位置就不对劲了:
在浏览器中,从_0x14f9
数组中取得123号元素值为wp/ClkHCkQg=
,而我们自己调试的话,发现结果为"B8OLwrUDwq4="
,所以由此可以推测,_0x14f9
数组元素的顺序可能存在问题,我们在源代码中搜索_0x14f9
,可以发现仅在三处出现,一个是在初始化时,一个是在此函数体内,另一个就是在下面这个自执行方法的参数列表中:
1 | (function(_0x2d8f05, _0x4b81bb, _0x4d74cb) { |
所以我们初步判断,应该是在此方法内部,修改了数组元素,我们把这个方法添加到我们的代码中,再来执行试一下。
执行时,我们会发现程序好像再一次陷入死循环,我们经过下面那部分内容讲的排查方法,发现只要让程序在这部分
1 | if (!_0xbd1168) { |
条件判断的时候,保证让程序进入到getcookie
操作就好了,走入到setcookie
就会陷入死循环。
死循环陷阱
按照上面抠出来的代码,直接执行会发现程序陷入死循环,如果调试一下你会发现,程序卡在了这个位置:
1 | _0x1e7c5b['prototype']['eYWonn'] = function(_0x5b1c97) { |
准确说是卡在了这个for循环里面,这个时候我们一般是在浏览器中也去调试一下,观察网站实际上是怎么走的,也就是看他浏览器中为什么不会进入死循环。
我们在浏览器中从同样的地方开始进入调试,同样的地方指的是这里:
var _0x1e26f5 = _0x119607[_0x4ce3('7b', 'SLM$')][_0x4ce3('7c', 'tPaN')]('|'), _0xb6e2c5 = 0x0;
之后进入到_0x4ce3
中,单步调试会发现,程序并没有进入到if (_0x4ce3['HFGZMS'] === undefined) {}
这个判断条件中,那当然是不会进入死循环的。
如果这里我们在分析一下,会发现在这个if判断的代码内体内,有这样一个赋值操作:_0x4ce3['HFGZMS'] = !![];
这个执行完之后,_0x4ce3['HFGZMS']
的值为true,所以就不会再进入到这个if体内了,证明在我们当前调试的步骤之前,已经有其他步骤执行过此操作了,当时的操作肯定是进到了if体内,这个时候我们有两个选择
- 找到第一次调用的位置,进入到这里,观察程序如何执行,为何不会陷入死循环,然后根据情况修改代码;
- 既然只要有一次进入到if体内后,之后就再也不会进入了,那我们这里就直接把if体所有东西全部删掉(注释)。
其实这里1、2两点我都试了,都可以解决此问题,因为第2种操作比较简单,这里就以第2中操作继续往下,这时的_0x4ce3
方法就变成了
1 | var _0x4ce3 = function(_0x2bafd4, _0x250b3f) { |
这时候我们尝试执行代码,会发现这样的问题:
Uncaught TypeError: Cannot read property '¨ßF' of undefined
出错的地方依然是这里
var _0x1e26f5 = _0x119607[_0x4ce3('7b', 'SLM$')][_0x4ce3('7c', 'tPaN') , _0xb6e2c5 = 0x0;
这里_0x4ce3('7b', 'SLM$')
计算得到的值有问题,这时问题又回到了上面的数组初始化陷阱问题,再回到上面来看看。
生成可以获取cookie的URL
上面已经介绍了wzwschallenge
参数破解99%的内容,只差最后两个变量定义:
1 | var _0x14e579 = 'KPSutrn(8+D]Ys?6+Mus'; |
这两个变量定义所在的位置,就是我们上面图中给出'/WZWSREL2Z6aHRpYW5qaW4vMTEzNjgyLzExMzcwMC8xMTM3MDcvaW5kZXguaHRtbA=='
的位置,这个值也是至关重要的,虽然与wzwschallenge
参数破解不相关,但是却是构成可以获取cookie的URL的重要组成部分。
所以现在的破解过程是:
- 请求
index.html
获取到其服务器返回的js
混淆代码; - 通过我们的分析,已经从中抠出必须的破解代码,并且可以独立执行生成
wzwschallenge
参数; - 我们需要利用正则将三个参数值取出来,
_0x14e579, _0x351708,_0x500dd8
,前两个参数作为生成wzwschallenge
参数的传入参数,第三个参数作为拼接URL的组成部分; - 生成URL后,发送请求获取cookie;
- 拿到最终获取的cookie,再次请求
index.html
。
有大佬说此网站的源代码是sojson
混淆,可以通过相关技术把代码还原,这样破解起来会事半功倍。
附源代码:
1 | <html> |