r0ckyzzz's Blog.

利用captcha_trainer进行验证码识别

Word count: 1.7kReading time: 9 min
2021/08/02 Share

利用captcha_trainer进行验证码识别

前言

因为在渗透过程中会遇到有验证码的问题,搜索了一番,发现有个captcha_trainer可以零基础运用卷积神经网络对验证码进行训练,从而达到识别验证码的效果。本着学习的使用的心态,尝试用它来识别一下织梦的验证码
其实python里的muggle_ocr模块就可以进行很多的验证码识别,但还是想自己操作一下,以免以后遇到不会操作

工具链接
https://github.com/kerlomz/captcha_trainer
https://github.com/kerlomz/captcha_platform
参考文章
https://blog.csdn.net/puhaiyang/article/details/102504263
https://www.e4rl.com/archives/198.html

获取训练样本

运用docker启动一个dedecms 然后修改vdimgck.php 让它能够输出我们想要它生成的验证码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import requests
import uuid
import random
import threading
dic="qwertyupasdfghjklmnbvcxz1234567890"
def getpic():
global k
while True:
code=''
for i in range(4):
code=code+dic[random.randint(0,33)]
r=requests.get("http://127.0.0.1:8082/uploads/include/vdimgck.php?i={0}".format(code))
pic=open("dede/{0}_{1}.jpeg".format(code,uuid.uuid1()),"wb")
pic.write(r.content)
pic.close()
klock.acquire()
k=k+1
print(k)
klock.release()
klock=threading.Lock()
k=0
for i in range(4):
threading.Thread(target=getpic,args=[])
while True:
getpic()

生成了5万个验证码样本

upload successful
##编写训练文件
我买了矩阵云的服务器进行训练,因为只是测试,所以我把结束的准确率设置为0.9,这样训练得更快些
按照github的文档给的编写格式编写了model.yaml
./projects/dede/model.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# - requirement.txt  -  GPU: tensorflow-gpu, CPU: tensorflow
# - If you use the GPU version, you need to install some additional applications.
System:
MemoryUsage: 0.8
Version: 2

# CNNNetwork: [CNN5, ResNet, DenseNet]
# RecurrentNetwork: [CuDNNBiLSTM, CuDNNLSTM, CuDNNGRU, BiLSTM, LSTM, GRU, BiGRU, NoRecurrent]
# - The recommended configuration is CNN5+GRU
# UnitsNum: [16, 64, 128, 256, 512]
# - This parameter indicates the number of nodes used to remember and store past states.
# Optimizer: Loss function algorithm for calculating gradient.
# - [AdaBound, Adam, Momentum]
# OutputLayer: [LossFunction, Decoder]
# - LossFunction: [CTC, CrossEntropy]
# - Decoder: [CTC, CrossEntropy]
NeuralNet:
CNNNetwork: CNNX
RecurrentNetwork: GRU
UnitsNum: 64
Optimizer: RAdam
OutputLayer:
LossFunction: CTC
Decoder: CTC


# ModelName: Corresponding to the model file in the model directory
# ModelField: [Image, Text]
# ModelScene: [Classification]
# - Currently only Image-Classification is supported.
Model:
ModelName: dede_9885
ModelField: Image
ModelScene: Classification

# FieldParam contains the Image, Text.
# When you filed to Image:
# - Category: Provides a default optional built-in solution:
# -- [ALPHANUMERIC, ALPHANUMERIC_LOWER, ALPHANUMERIC_UPPER,
# -- NUMERIC, ALPHABET_LOWER, ALPHABET_UPPER, ALPHABET, ALPHANUMERIC_CHS_3500_LOWER]
# - or can be customized by:
# -- ['Cat', 'Lion', 'Tiger', 'Fish', 'BigCat']
# - Resize: [ImageWidth, ImageHeight/-1, ImageChannel]
# - ImageChannel: [1, 3]
# - In order to automatically select models using image size, when multiple models are deployed at the same time:
# -- ImageWidth: The width of the image.
# -- ImageHeight: The height of the image.
# - MaxLabelNum: You can fill in -1, or any integer, where -1 means not defining the value.
# -- Used when the number of label is fixed
# When you filed to Text:
# This type is temporarily not supported.
FieldParam:
Category: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k', 'm', 'n', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
Resize: [68, 24]
ImageChannel: 1
ImageWidth: 68
ImageHeight: 24
MaxLabelNum: 4
OutputSplit: null
AutoPadding: True


# The configuration is applied to the label of the data source.
# LabelFrom: [FileName, XML, LMDB]
# ExtractRegex: Only for methods extracted from FileName:
# - Default matching apple_20181010121212.jpg file.
# - The Default is .*?(?=_.*\.)
# LabelSplit: Only for methods extracted from FileName:
# - The split symbol in the file name is like: cat&big cat&lion_20181010121212.png
# - The Default is null.
Label:
LabelFrom: FileName
ExtractRegex: .*?(?=_)
LabelSplit: null


# DatasetPath: [Training/Validation], The local absolute path of a packed training or validation set.
# SourcePath: [Training/Validation], The local absolute path to the source folder of the training or validation set.
# ValidationSetNum: This is an optional parameter that is used when you want to extract some of the validation set
# - from the training set when you are not preparing the validation set separately.
# SavedSteps: A Session.run() execution is called a Step,
# - Used to save training progress, Default value is 100.
# ValidationSteps: Used to calculate accuracy, Default value is 500.
# EndAcc: Finish the training when the accuracy reaches [EndAcc*100]% and other conditions.
# EndCost: Finish the training when the cost reaches EndCost and other conditions.
# EndEpochs: Finish the training when the epoch is greater than the defined epoch and other conditions.
# BatchSize: Number of samples selected for one training step.
# ValidationBatchSize: Number of samples selected for one validation step.
# LearningRate: [0.1, 0.01, 0.001, 0.0001]
# - Use a smaller learning rate for fine-tuning.
Trains:
DatasetPath:
Training:
- ./projects/dede/dataset/Trains.0.tfrecords
Validation:
- ./projects/dede/dataset/Validation.0.tfrecords
SourcePath:
Training:
- /root/dede
Validation:
ValidationSetNum: 1000
SavedSteps: 100
ValidationSteps: 500
EndAcc: 0.9
EndCost: 0.5
EndEpochs: 2
BatchSize: 64
ValidationBatchSize: 300
LearningRate: 0.001

# Binaryzation: The argument is of type list and contains the range of int values, -1 is not enabled.
# MedianBlur: The parameter is an int value, -1 is not enabled.
# GaussianBlur: The parameter is an int value, -1 is not enabled.
# EqualizeHist: The parameter is an bool value.
# Laplace: The parameter is an bool value.
# WarpPerspective: The parameter is an bool value.
# Rotate: The parameter is a positive integer int type greater than 0, -1 is not enabled.
# PepperNoise: This parameter is a float type less than 1, -1 is not enabled.
# Brightness: The parameter is an bool value.
# Saturation: The parameter is an bool value.
# Hue: The parameter is an bool value.
# Gamma: The parameter is an bool value.
# ChannelSwap: The parameter is an bool value.
# RandomBlank: The parameter is a positive integer int type greater than 0, -1 is not enabled.
# RandomTransition: The parameter is a positive integer int type greater than 0, -1 is not enabled.
DataAugmentation:
Binaryzation: -1
MedianBlur: -1
GaussianBlur: -1
EqualizeHist: False
Laplace: False
WarpPerspective: False
Rotate: -1
PepperNoise: -1.0
Brightness: False
Saturation: False
Hue: False
Gamma: False
ChannelSwap: False
RandomBlank: -1
RandomTransition: -1
RandomCaptcha:
Enable: False
FontPath: None

# Binaryzation: The parameter is an integer number between 0 and 255, -1 is not enabled.
# ReplaceTransparent: Transparent background replacement, bool type.
# HorizontalStitching: Horizontal stitching, bool type.
# ConcatFrames: Horizontally merge two frames according to the provided frame index list, -1 is not enabled.
# BlendFrames: Fusion corresponding frames according to the provided frame index list, -1 is not enabled.
# - [-1] means all frames
Pretreatment:
Binaryzation: -1
ReplaceTransparent: True
HorizontalStitching: False
ConcatFrames: -1
BlendFrames: -1
ExecuteMap: {}

最后开始训练

1
2
python3 make_dataset.py 
python3 trains.py

部署验证码识别接口

十几分钟就训练完了,比我想象中的快。完成会生成graph和model文件夹,这就是我们训练好的模型。
https://github.com/kerlomz/captcha_platform
我是直接下载了编译好的windows版

将训练好的模型复制到根目录即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import requests
import base64
import random
import json
dic="qwertyupasdfghjklmnbvcxz1234567890"
def getpic():
global k
code = ''
for i in range(4):
code = code + dic[random.randint(0, 33)]
r = requests.get("http://127.0.0.1:8082/uploads/include/vdimgck.php?i={0}".format(code))
img=base64.b64encode(r.content)
post_data = {
'image': img,
'model_name': 'dede_9885'
}
res = requests.post('http://10.211.55.5:19952/captcha/v1', data=post_data)
data=json.loads(res.text)
if data['message']==code:
print('正确的验证码为:{0},识别的验证码为:{1},识别结果:正确'.format(code,data['message']))
k=k+1
else:
print('正确的验证码为:{0},识别的验证码为:{1},识别结果:错误'.format(code,data['message']))


k=0
for i in range(1000):
getpic()
print(k)

写了个测试程序 准确率为88%

upload successful

CATALOG
  1. 1. 利用captcha_trainer进行验证码识别
    1. 1.1. ¶前言
    2. 1.2. ¶获取训练样本
    3. 1.3. ¶部署验证码识别接口