聊聊滑块验证码破解
Posted 点融黑帮
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了聊聊滑块验证码破解相关的知识,希望对你有一定的参考价值。
在爬虫的需求中,越来越多的网站采用验证码来抵御爬虫的入侵,而滑块验证码也被运用在很多的用户登录场景中。
我们若是去分析它的接口规则,往往得不偿失,主要是因为这类接口加密参数多且更新频繁,一旦更新后,又得从头开始分析加密,人力终究有限。
我们以qq邮箱的滑块验证码为例,一步一步从正面来破解它。在目标网站上使用账号密码来登录,这个时候很大概率会出现滑块验证码,如下图所示:
我们可以看到这类验证码比较简单,主要就是计算缺口的X轴坐标,然后用js来拖动按钮来滑动,虽然在此过程中,对方服务器会记录用户的所有操作行为,但我们可以在拖动的时候尽量拟人化,来达到验证成功的目的。而计算缺口坐标则是难点也是本文主要分析的地方。
经过简单的抓包分析或在浏览器的F12帮助下,我们可以得知服务器返回了两张图片,一张是缺口滑块图,一张是有缺口的底图。
这个时候,我们有两种方案。第一种我们想办法拿到没有缺口的原始图,通过原始图和有缺口的底图进行对比,得到缺口的坐标。
第二种,直接把缺口滑块图在缺口底图上进行匹配,得到缺口坐标。这两种方案也是根据对方返回的底图缺口类型决定的。
比如这次世界杯主题的验证码,它的缺口都是集中在底图右侧(下载大量图片进行对比分析),而平时的验证码的缺口则是随机分布在底图上的。
所以在进行破解的时候,缺口集中在右侧用方案二,缺口随机分布则用方案一。
方案一
由于缺口在底图中是随机分布的,对于同一类型的底图而言,只要拥有足够的数据集经过一系列切割重组就能够拼接成一张完整的原始图。
而每次的验证码底图和我们已经复原的原始图进行对比,就能得到二者不同的区域,然后定位此区域的坐标就是验证码的缺口坐标。所以,接下来我们进行图片复原的准备。
1、获取大量图片数据集,保存在本地。
2、每个类型的图片提取一张作为标本。
3、对数据集进行分类处理,不同类型的图片保存在不同的文件夹中。若是人工分类处理的
话,要是图片少还好操作,图片多的话简直苦不堪言,我自己经历过一天手工处理8W张图片用于机器学习,后面看见这种图片就想吐。
在这里,我使用像素对比的方式。以图片左上角为坐标原点,X轴50个单位和Y轴50个单位的区域,分别将此区域中每个位置的像素和标本中的图片相同位置像素进行对比。
若错误率大于80%则判断不是同一类型图片。(因为就算是同类型的两张图片,它们相同位置的像素也不一定相等,这个只是针对qq验证码图片,所以可以用比较粗暴的方式处理。)
4、对同一类型的所有图片进行等长切割。比如A类型的验证码图片有100张,我们依次将每张图片竖着切割成等长的10份,然后将切割后的所有第一部分保存在一起,所有第二部分保存在一起,以此类推。最终A类型的验证码图片被切割分成10份。以下是部分切割代码:
部分已分类好的切割图
相同部分切割样例
5、在第四步中,我们已经得到同一类型验证码图片被切割后的10份,接下来我们得从每一份中判断出一张不含验证码的切割图。
我们使用两两组合对比的方式,先对切割图进行二值化,然后比较它们的像素大小,浮动相差在2以内则判断像素是一样的,反之为错误,并记录错误次数,最终错误率大于2%则认为两张切割图不相同,证明它们某一张或都有验证码区域(杂质)。部分代码如下:
6、组装完整的原始图。上一步中,我们可以得到某一类型验证码图片的10份无杂质的切割图,这时就可以通过拼接或粘贴等方式还原成原始图。
新建一张同等宽高的白色图片,然后依次将切割图粘贴上去。部分代码如下:
无缺口的原始图
经过这6个步骤,我们能拼接出所有的原始图片。将这些原始图片作为素材库,在后续的验证码中,我们用有缺口的验证码底图和原始图片进行对比,获取缺口的偏移坐标。
ImageChops.difference()函数能够判断两张图片的不同处并返回差异图。部分代码和差异图如下所示:
我们再使用老办法----像素对比,就能获取到缺口的坐标了。
此方案能够应对腾讯平常日子的验证码,因为在特殊的节假日,腾讯会根据当时的节日变动底图,且缺口分布也所有变化,就如同世界杯主题验证码,它的缺口集中分布在右侧,所以我们采用第二种方案来破解。
方案二
此方案中,我们首先二值化缺口滑块图和缺口底图。由于缺口滑块图二值化后,背景和半圆都为黑色,所以我们需要去掉黑色背景部分。
然后使用OpenCV的matchTemplate模板进行归一化相关系数匹配,大于我们设置的阈值后则匹配成功,反之调低阈值再次匹配。最终获取缺口的左上角坐标。
1、首先二值化图片,便于接下来的图片对比:
得到的图片如下所示:
缺口滑块图
缺口底图
2、截取缺口滑块图,不能包含黑色区域,其中每个参数都是对比量化后所得。得到的截取图作为模板,将被用在缺口底图的匹配中。
截取后图片如下所示:
3、模板匹配。阈值初始化为0.99,然后使用归一化相关系数匹配算法来获取满足条件的区域坐标,并在底图中用红色方框进行标记。其中需要注意一点是,由于此方案二是针对缺口集中在右侧的验证码,所以我们需要设置缺口的最小横纵坐标,以此来提高匹配的准确性。
其匹配结果为:
拖动滑块
通过以上两个方案,我们获取到缺口的X、Y坐标,然后再使用selenium来进行滑块的拖拽,在此过程中,我们需要注意的是,拖拽速度不要过快,设置好上下、前后的抖动区间和时间,尽可能的模拟人的操作。在此,有几个细节需要说明一下:
1、我们训练或下载的图片分辨率为680*390px,而网页上显示的分辨率为280*158px,所以它的缩放率为280/680,X轴的偏移量与此有关;
2、滑块相较于坐标原点(0,0)有一个偏移量,可以经过测量得到值为22;
3、拉动滑块的时候,我们把这一步骤分为N个移动偏移量,每个偏移量长度随机(X轴偏移量,Y轴偏移量同理),移动每个偏移量的时间也是随机。所以我们需要定义偏移量和时间的最大、最小值,下面是拉动滑块的核心代码:
拉动滑块函数
以下是实验效果图:
往期精彩:
以上是关于聊聊滑块验证码破解的主要内容,如果未能解决你的问题,请参考以下文章