0x01 目的

日常渗透环境中,有不少的网站存在验证码,导致无法顺利爆破,存在漏洞在眼边溜走的可能性
而一些接口会存在一些次数或者费用的限制,因为一个对验证码识别的库还是有必要的
存在着较棘手的坑点,遂记录下mac系统下安装和使用cnn_captcha的过程

0x02 cnn_captcha

* 引用官方介绍

本项目针对字符型图片验证码,使用tensorflow实现卷积神经网络,进行验证码识别。
项目封装了比较通用的校验、训练、验证、识别、API模块,
极大的减少了识别字符型验证码花费的时间和精力。

项目已经帮助很多同学高效完成了验证码识别任务。 如果你在使用过程中出现了
bug和做了良好的改进,欢迎提出issue和PR,作者会尽快回复,希望能和你共同完善项目。

如果你需要识别点选、拖拽类验证码,或者有目标检测需求,也可以参考这个项目nickliqian/darknet_captcha。

0x03 安装及初始化

  • 我的环境
python3.8.6
macos10.15.6
  • clone 项目
git clone https://github.com/nickliqian/cnn_captcha.git
  • 修改一下requirments.txt里的tensorflow库版本(原先是tensorflow == 1.15.3 改为tensorflow == 2.2.0)
我的python是3.8版本,如果直接按照原先版本安装是会报错提示未找到对应版本的
因为对应python3的tensorflow这个库的最低都是2.0以上版本,所以此处先修改好版本
  • 安装requirments.txt,附一张别的图,因为我是踩坑的,所以tensorflow单独安的
pip3 install -r requirments.txt
  • 对cnn_captcha中使用1.0多版本的tensorflow库语法升级到2.0以上,后面操作就去新的cnn_captcha_v2文件夹操作了,原先的已经没用了
cd ../   //退到项目外
tf_upgrade_v2 --intree cnn_captcha/ --outtree cnn_captcha_v2/ --reportfile report.txt
  • 开始修改py文件导入tensorflow的语法,mac的搜索框直接输入import tensorflow as tf来找到使用这个语法的py文件,全部修改
import tensorflow as tf
↓
import tensorflow as tf
tf.compat.v1.disable_eager_execution()           //就是加上这行的意思
  • 然后可以正式开始运行创建训练集,conf文件夹下是一些配置文件,都是负责什么的,md文件也有写,默认先不管,这里开始生成训练集,就是项目自带的可以生成验证码的py文件,生成一些用来训练的验证码图片,在sample/origin下
python3 gen_sample_by_captcha.py
  • 对验证码图片验证和拆分数据集,我是按照配置在sample目录下创建origin、train、test三个目录,不知道如果不存在这些目录是否会自动创建,自行斟酌
python3 verify_and_split_data.py
  • 终于可以开始训练了,会用些时间,对了,默认是启动gpu的
python3 train_model.py
  • 启动webserver,将下列代码加入webserver_recognize_api.py文件,从88行开始加进去就行 ,进行base64是为了使用burp传图片给cnn时保证验证码图片的一致性
@app.route('/base64',methods=['POST'])
def up_imageBase64():
    if request.method == 'Post' and request.form['image_file']:

        timec = str(time.time()).replace(".","")
        file = request.form['image_file']

        img = base64,b64decode(fi1e)#获取bage64转成图片 fimg =file read()
        img= BytesIO(img)
        img =Image.open(img, mode="r")
        print("接收图片尺寸:{}", format(img.size))
        img_size = img.resize((image_width,image_height), Image.ANTIALIAS)
        print("接收图片尺寸2:{}".format(img.size)) 
        s = time.time()
        value = R.rce_image(img_size)
        e= time.time()
        print("识别结果:{}".format(value))
        print("保存图片: {}{}_{}.{}".format( api_image_dir, vallue, timec, image_suffix)) 
        file_name ="{}_{}.{}".format(value, timec, image_suffix) 
        file_path =os.path.join(api_image_dir + file_name) 
        img.save(file_path)
        result = {
            'time': timec,#时间戳 
            'value': value,#预测的结果
            'speed_time(ms)':int((e-s)*1000)#识别耗费的时间
        }
        img.close()
        return jsonify(result)
    else:
        content = json.dumps({'error_code':"1001"})
        resp = response_headers(content)
        return resp