天天看点

极验验证的滑动验证码破解

后来研究了下觉得要破解这个验证码有这么几个问题:

无法直接通过发送url请求来实现鼠标拖动的动作;

实际的背景图片是乱的,并不是我们实际肉眼看到的图像,如下图;

“开创行为判别算法,利用数据挖掘和机器学习,提取超过200多个行为判别特征,建立坚若磐石的多维验证防御体系。”这是官网的描述,听上去就已经很高大上,查了些资料也都说拖动轨迹的识别是geetest的核心内容而无过多的表述,那么这也应该是主要的难点了。 

后面我也就基于了以上的问题去一步一步研究如何实现模拟这一操作: 

在github中clone出最新Demo项目:

安装GeetestSDK:

安装Django,要注意的是最新的Django-1.10.1和当前的GeetestSDK是有兼容性问题的,要用Django-1.8.14:

后面就可以直接运行了:

这里要实现鼠标拖动的动作靠直接发送url请求是无法实现的,需要有个真的浏览器再去模拟鼠标拖动的动作。根据参考的内容使用了Selenium(也有python版本的)可以实现这一操作。

上面的移动位置我写了一个固定的值,实际情况这个值是不固定的,需要根据背景图片的缺口来算出这个偏移量。然而要计算缺口的偏移量还要先还原图片。 

如上图,原始的图片是乱的,但是我们可以在html里面可以看到把同一个图片的位置进行重新组合就可以看到还原后的图片了: 

代码如下:

通过python的PIL.ImageChops可以计算出两个图片不同地方的位置,方法如下:

但是这在我们这里并不适用。因为我们得到的两个图片是通过拼接而成的,并且两张原图在背景上也还是稍有区别的,而difference方法计算得过于精确,所以这里得到的位置并不会是我们要的缺口的位置。这里我借用的参考内容的方法:两张原始图的大小都是相同的260*116,那就通过两个for循环依次对比每个像素点的RGB值,如果相差超过50则就认为找到了缺口的位置:

如果我们直接把上面算出来的缺口位置放到前面脚本里,你会发现即使移动的位置正确了,提示却是“怪物吃了饼图”,验证不通过。很显然,geetest识别出了这个动作并不是人的行为。这我们就需要去查看自然人滑动鼠标和我们代码实现的滑动在轨迹上有什么不同。 

geetest目前版本客户端最核心的是geetest.5.5.36.js,我们可以把它复制出来加以改造。首先找个工具把原代码格式化一下,然后再加入以下的内容:

index.html页面的上直接调用的是gt.js,再由gt.js去调用geetest.5.5.36.js。我用的土办法是自己搭建一个简易的web server,并在host里面把static.geetest.com域名指向到我自己的web server,然后再把页面上要调用的static.geetest.com里的内容都放到我自己搭建的web server上,当然geetest.5.5.36.js是要用我刚才改造过的那个。

static.geetest.com里面只要static目录里的内容即可,pictures里面的图片找不到会自动指向到他们备用的网站的。我用的简易web server是HTTP File Server,可以在下载。

如此一来,我们每次滑动鼠标包括代码实现的滑动操作在浏览器里都能显示出滑动的轨迹: 

这里我总结了一下差别(一个{x,y,z}是一个轨迹记录点,x代表x轴,y代表y轴,z代表累计时间毫秒): 

1.时间不宜太长又或者太短,最好能控制在1-5秒之内,另外两个相邻的记录点的时间也最好能控制在50ms以内,并且间隔的时间也不宜相同; 

2.乡邻的x值差值也不宜太大,最好控制在以5内,并且差值也不要是一层不变的; 

3.geetest虽然是横向拖动的,不会涉及到纵向移动,所以这部分很容易是被忽略的:y轴的值要控制在[-5,5]范围内,不能过大。而且上下抖动的频率不能高,要平缓一点。我试下来最好的办法就是平稳固定的0上,也不要上下抖动了。

完整代码如下:

运行结果:

1.最为重要的就是代码注释里说的y轴的高度问题,我试了PhantomJS,Chrome和Firefox三个浏览器,每一种渲染出来的高度都是不一样的,一定要保证最终的结果是拖动球高度的一半(一般都是22); 

2.版权兼容性(以下是我验证过可行的): 

selenium (2.53.6)===>PhantomJS 2.1 

selenium (2.53.6)===>Chrome 52 

selenium (2.53.6)===>Firefox 45(注意不要用48,有兼容问题) 

3.webdriver的cookie问题: 

有的时候我们需要带入cookie进行验证,那就有了cookie的问题了。Chrome和Firefox都可以通过webdriver.add_cookie来实现,但是经我试下来这个方法和PhantomJS有兼容性问题,我是这样解决的:

再如此调用就可以解决cookie的兼容性问题了:

4.PhantomJS浏览器解析出来的图片url是不带引号的,而Firefox和Chrome解析出来的是带引号的,这里正则过滤的时候要注意一下的。 

我最终使用的是selenium+Firefox。我实际运行的环境是centos,PhantomJS确实是个不错的选择,直接在shell里运行就可以了,不需要配置图形界面。但是使用下来破解的成功率不高,因为没有界面,也看不出运行的情况。Chrome在centos6.5里面没有现成的安装包,安装使用比较复杂。最终也就只有Firefox了。

centos配置firefox方法如下:

注意不要纯shell环境下运行,要在图形界面的运行。运行init 5可以从字符界面切换到图形界面。

本文转自 yntmdr 51CTO博客,原文链接:http://blog.51cto.com/yntmdr/1905966,如需转载请自行联系原作者