一、网站http://www.*****.cn滑动验证码概述
二、极验验证码破解-抓包分析
三、极验验证码破解-搭建本地验证码服务
四、极验验证码破解-分析geetest.js,得到所需参数
五、极验验证码破解-Track的获取
六、极验验证码破解-获取背景图片及缺口距离d的计算
七、极验验证码破解-总结
参考文献
运行截图
(对滑动验证码了解的朋友请跳过本章节)
2.在搜索框中输入待查询企业名(如:百度),点击查询,将会出现如图所示验证码。
拖动滑块到缺口位置,验证成功效果如下:
4.以上为对目标网站滑动验证码的一些基本描述,下面章节将会详细讲解如何使用计算机程序(爬虫)来对该验证码进行破解。
2.我们象征性的拖动滑块,可以看见Network选项下多出一个数据包 ajax.php?gt=…&challenge=…,如下图所示:
鼠标点击上述数据包,可在右侧查看该数据包的详细信息。点击Response可查看服务器响应信息,如下所示:
显然,服务器返回该验证码验证失败:fail。
3.为了查看验证成功时的服务器响应信息,我们拖动滑块至缺口处,已同样方式查看最新的ajax.php页面,我们发现此时ajax.php?数据包的Response变为如下信息:
有上述可知,当服务器检测到客户端验证成功时,返回validate(可看作是一串长字符串密码)和其他success信息。
(PS:为防止验证成功时页面快速切换至查询结果页面,可在Network选项卡下将Preserve log选项勾选,如下图所示:)
4.当验证成功时,页面跳转至查询结果页面,如下所示:
通过分析Network下的数据包可以发现,在最新的验证成功的ajax.php?数据包下面,有一个crop-query-search-1.html数据包,如下所示:
通过查看该项的Response,我们可以发现,该Response的内容即为浏览器页面上展示的内容,亦即我们所需爬取的内容。
为了获取该Response内容,我们将模拟请求该url,我们查看该请求的头部headers信息,如下所示:
从Headers中我们发现,该请求为POST请求,同时发送Form Data给服务器。接下来我们将分析该Form Data是如何得到的,其中geetest_challenge和geetest_validate是关键信息,geetest_seccode是由geetest_validate后加上“|jordan”。Form Data相当于密码,浏览器通过向服务器请求页面,并发送Form Data,服务器端验证该密码正确,将返回页面信息。
接下来我们将逆向探索如何得到geetest_challenge和geetest_validate。(实验证明:tab可为空或’ent_tab’,不影响结果,token可设一相同长度的随机数,不影响结果,searchword为查询关键词)
5.回忆上述3中验证成功时,ajax.php?的Response信息可知,validate的值是由该请求获得。
我们将模拟该请求,以获得validate信息,构造geetest_validate和geetest_seccode。
6.为了模拟请求ajax.php?,我们查看该数据包的Headers信息:
从上图可以看出,此请求附带7个参数。首先,我们可以大胆猜测passtime应该是拖动验证码的时间,imgload应该是验证码图片载入时间,callback应该是“geetest_”+当前时间的时间戳,如下:
关于passtime,我们知道验证码图片在不同的机器上受网速影响,加载时间是不同的,因此该项可暂考虑设为一个0-1000ms的随机数或固定值。
7.我们知道极验验证是根据用户拖动鼠标的轨迹来判断是人为操作还是机器的。Userresponse和imgload从参数名上可猜测是跟拖动滑块的轨迹(用户行为)来生成的。参数a最为复杂,我们先看gt和challenge是如何生成的。
8.分析Network下的数据包(ajax.php?之前的包),我们发现除去一些css、png等无关紧要的东西外,有个get.php?gt=…还是挺显眼的,大胆点进去,如下:
从该数据包的Response中可以发现,"gt": …,对比发现,这就是我们要的gt啊啊啊! “fullbg”也暗示着我们,它表示验证码的背景图片。此时,可以感觉到该Response的信息量之大,继续往后查看,可以发现:
“challenge”出现了,对比发现,这也是我们要的challenge!!!
9.为了得到上述大量信息,我们模拟请求get.php?,查看该包的Headers如下:
我们发现,该请求的参数还有一个gt和challenge(真实一个接着一个…)。除了gt和challenge,其它6个参数看起来没什么价值,可直接保留,我们来分析gt和challenge的生成。
继续查看Network中的数据包(get.php?之前的),我们可以发现SearchItemCaptcha?v=…这个包的Response如下:
惊呆.jpg!比较发现这里的gt和challenge就是我们需要的值。双击
以打开页面,刷新发现每次页面展示的返回值中challenge都在变化。这是因为该api的参数v是根据请求时间动态变化的,因此我们也可以将v设为当前时间的时间戳。
10.OK!至此我们可以按照SearchItemCaptcha?v=… get.php? ajax.php?crop-query-search-1.html的顺序请求数据。关键问题是如何构造ajax.php?参数中的userresponse、passtime和a。passtime从名称可以看出是拖动滑块的时间,userresponse和a应该是根据拖动滑块的轨迹进行加密的。接下来我们将在本地搭建一个简易的web server,修改相关js源码,使得拖动滑块时输出鼠标轨迹信息Track。并分析js源码,找出根据Track得到的userresponse和a的算法。
2.打开static/index.html。
可以发现,该页面请求的gt.js是来自geetest远程服务器的。我们要想修改js源码,打印相关信息,必须使得请求的js来自本地,因此我们搭建简单的文件服务器。
3.https://pan.baidu.com/s/1c26btBE从上述链接下载HFS软件。运行软件,按图示搭建文件夹(所需文件从Network下载):
修改index.html中gt.js的来源,如下所示(地址为hfs的地址):
从http://1ocalhost:8000/下抓包发现,gt.js的确来自本地hfs:
4.打开gt.js。
我们发现geetest.js是由gt.js调用,修改static_server为本地地址:
抓包发现,geetest.js的确来自本地hfs:
(ps.图片等其他本地没有的资源将会继续请求源服务器)。
至此,我们已搭建好本地验证码服务,下面我们将分析geetest.js,找出相关参数userresponse和a的加密过程。