使用深度学习破解点击验证码

使用深度学习破解点击验证码

问题描述&可行性分析

网易验证码样例如下图1所示,需要在图中顺序点击文字。

极验,腾讯等点击同样适用。

图片点选验证码_验证码接口_验证安全系统_在线体验_网易云易盾


图1

该问题本质是图片的detection问题,是图像处理中的经典问题。使用R-cnn,Yolo,SSD等深度学习技术完全可以解决。针对这个验证码,我考虑了两种方法:

  1. 直接使用R-cnn,Yolo,SSD这样的模型进行端到端训练
  2. 使用R-cnn,Yolo,SSD先进性检测,后进行识别

最终选择了方法2,原因是:

  1. 端到端训练难度大
  2. 需要大量训练样本

最终选择Yolo作为定位网络,网络框架使用 Darknet: Open Source Neural Networks in C

训练过程

定位训练

网络准备cfg/yolo-origin.cfg

爬取验证码图片,最初爬取500张,进行极为痛苦的手工标注。因为打算只定位汉字一类,故只需要标框就可以了,darknet有提供Yolo训练代码。

在这里需要注意修改cfg/yolo-origin.cfgfilter=30classes=1num=5代表每个框最多可以预测多少类,这里我没有进行修改 。

[convolutional]
size=1
stride=1
pad=1
filters=30
activation=linear

[region]
anchors =  1.3221, 1.73145, 3.19275, 4.00944, 5.05587, 8.09892, 9.47112, 4.84053, 11.2364, 10.0071
classes=1
coords=4
num=5
softmax=1
jitter=.3
rescore=1

filter计算公式如下:

(classes+ coords+ 1)* (NUM)

因为检测只有汉字1类,坐标为中心点坐标+图片宽高,共4个数,还有1个置信度,每个cell预测5个box,故最后输出 (4+1+1) * 5 = 30

可以提供通过url进行识别破解的demo(针对网易点选验证码)

训练配置cfg/yolo-origin.data

训练配置文件格式如下

backup = products/backup
classes = 1
names =  names
results = products/results
train = products/trainval.txt
valid = products/test.txt
  • backup 用于保存训练权重
  • classes代表定位有几个类
  • names代表网络前向时图片对应标签的名字,如下图中的dog bicycle truck。定位只需一类就写一个。
  • results 代表使用darknet valid选项时存放结果的位置。
  • train & valid 代表存放训练 & 验证标签位置的路径,标签文件名需要与图片文件名一样,标签格式为<object-class> <x> <y> <width> <height> 。其中object-calss代表类标签,因为只有一类所以为0;x & y代表中心点的相对坐标,width & height代表文字相对高度。

如下图为实例,的标签为0 0.2 0.75 0.16 0.18的标签为 0 0.7 0.15 0.15 0.17 。所以整张图的标签为

0 0.2 0.75 0.16 0.18
0 0.7 0.15 0.15 0.17

trainval.txt 的内容为图片的路径,label与图片放在同一文件夹下并且文件名相同。

products/trainval/0000172_6_0.jpg
products/trainval/0000172_6_1.jpg
products/trainval/0000172_6_2.jpg

products/trainval文件夹内容

训练
sh run.sh yolo_train

识别训练

网络准备cfg/chinese-character.cfg

标准的全卷积识别网络。filter代表最后汉字数量。

[convolutional]
filters=3549
size=1
stride=1
pad=1
activation=leaky
训练配置cfg/chinese.data

描述如下,名称相同的与检测描述一致。

classes=3549
train  = darknet/chinese_character_train/train.list
valid  = chinese_character_train/train.list
labels = darknet/data/chinese_label.names
backup = darknet/model/classifier
top=100
  • labels代表label的位置,names文件中存放所有编码后的label。如data/chinese_label.names
abcdefg
abcdegf
abcdfeg
abcdfge
abcdgef
abcdgfe
abcedfg
abcedgf

由于darknet中train存储训练图片的路径,图片的label包含在图片的绝对路径中如图片路径为/data/some_path/abcdefg.jpg,因为chinese_label.names中存在abcdefg编码,所以这张图片的标签为abcdefg

注意

darknet在解析label时图片的绝对路径中如果包含多个label.names中的编码则会加载多个标签,导致无法训练,如:

label_names中如果包含1,2作为标签则 /data2/some_path/1.jpg这张图会解析到1 2均为这张图片的标签(data后的2以及1.jpg的1)。可以将标签加前导零或者使用全排列。

  • top 代表在valid的时候我们选取多少计算正确率,如top100代表分类出的概率前100为中存在正确的汉字即为正确;top1代表仅一个字对才算对。因为点选验证码会告诉你点击哪个字,所以识别结果的字有候选方案
训练
sh run.sh chlassifier_train

Pipelinepython/server.py

先使用yolo进行定位,定位后将图片进行切分,送入分类器进行分类。选取出现在候选字中的字符,返回位置即可。

Bug process_img_to_darknet_input 函数当子函数调用传入darknet中数据前8位发生错误
因为darknet教程使用的本地读取图片的方式,python接口使用的ctypes,我写的server通过网络加载图片,故需要将图片转换为darknet输入格式。
推测原因:可能由于c与python分配对象方式不同 process_img_to_darknet_input存在调用时, python在子函数进入栈分配堆内存与c分配方式不同。

Bug 内存泄露
修改darknet分配bbox函数,增加free函数,python每次申请后进行释放即可。

效果

网易

极验

需要做字符分割后再进行破解

项目地址

cos120/captcha_crack

详细文档

大家有问题请到github仓库内发issue。


免责声明

该项目仅用于学术交流,不得任何商业使用!

编辑于 2018-05-06