怼就完事了,总结几种验证码的解决方案

简介: 怼就完事了,总结几种验证码的解决方案

截止到今天咸鱼已经写了很多期关于 Js 逆向的文章,不过这么多的文章都有一个共同点,都是关于加密参数或者密码加密的解析,很多读者在后台私信希望能够出一些关于滑动验证或者人机验证的分析教程。

于是咸鱼总结了目前遇到过的的验证码类型以及总结出来的相关处理方式和大家聊一聊。

现在市面上的验证码的类型大致有下面几种类型。

图形验证码

比较常见的英文数字组合成的图形验证码,常常辅以各类干扰线扭曲图片中的内容达到提高混淆难度的目的,并且通过加长图片中的文字长度提升识别成本。

7位英数-难度高4位英数-难度中等4位英数-难度低

像这类验证码的处理方案有很多种,简单给大家概括一下。

难度中低的两类验证码,安装 tesserocr,通过 OCR 技术结合 Python 的 tesserocr 库可以就可以完成识别。如果验证码中带有简单干扰线可以使用灰度和二值化的方法提高代码的识别率。

常用示例代码:

import tesserocr
from PIL import Image
image = Image.open('code2.jpg')
image = image.convert('L')
threshold = 127
table = []
for i in range(256):
    if i < threshold:
        table.append(0)
    else:
        table.append(1)
image = image.point(table, '1')
result = tesserocr.image_to_text(image)
print(result)

难度较高的多位英数+扭曲的图形验证码包括上面总结的中低难度的图形验证码,可以通过 TensorFlow 训练的方式达到识别验证码的目的。

之前我有一个系列文章介绍了整个训练部署的流程,大家可以点击参考。

大佬说 | 写给程序员的TensorFlow教程-准备篇

大佬说 | 写给程序员的TensorFlow教程-编码篇

大佬说 | 写给程序员的TensorFlow教程-上线篇

使用这个方式的朋友记得要先准备好足够的验证码的样本,只要你的模型不是太差,通过足量的样本,不断调优是可以达到一个较为可观的识别率。

目前体验过最好的程序是冷月的四位英数,识别成功率高达 99.99% ,不过据知情人透露整个训练的样本达到了 6000 W ,耗费的时间精力可想而知。

旋转验证码

这类验证码是将验证码的图片旋转并且需要用户拖动下方滑块完成将图片摆正的操作才可以完成验证。

旋转验证码

不过某家的这个验证码有一些小小的 bug,依靠劳苦大众的智慧,我在 GitHub 上发现了一个很 Nice 的项目。

项目地址:https://github.com/scupte/xuanzhaunyanz

因为图库的容量问题,没有超大的图库作为后盾,将全部的原图抓取下来对比完全可以得到旋转的角度了。

不过鉴于该家的验证码并没有普及所以了解一波即可。

部分对比代码:

# -*- coding: utf-8 -*-
import cv2
import numpy as np
imagepath = '9_1.png'
img = cv2.imread(imagepath)
gray = cv2.cvtColor ( img , cv2.COLOR_BGR2GRAY )
ret, binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)  
contours, hierarchy = cv2.findContours(binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)  
#cv2.drawContours(img,contours,-1,(0,0,255),1)  
for cnt in contours:
    # 最小外界矩形的宽度和高度
    width, height = cv2.minAreaRect(cnt)[1]
    if width* height > 100:
        # 最小的外接矩形
        rect = cv2.minAreaRect(cnt)
        box = cv2.boxPoints(rect)  # 获取最小外接矩形的4个顶点
        box = np.int0(box)
        print box
        if 0 not in box.ravel():
            #绘制最小外界矩形
            for i in range(4):
                cv2.line(img, tuple(box[i]), tuple(box[(i+1)%4]), 0)  # 5
            theta = cv2.minAreaRect(cnt)[2]
            if abs(theta) <= 45:
                print('图片的旋转角度为%s.'%theta)
            #     angle = theta
print theta            
cv2.imshow("img", img)  
cv2.waitKey(0)  
滑动验证码

滑动验证码

说到滑动验证码,一定一定要提某验,虽然说市面上关于滑动验证码的产品有很多,但是某验的地位就像 10 年前脑白金在保健品市场的地位一样,业界标杆啊。

它越牛逼,市场上用它做防护的网站也越多,像国家企业信用信息公示系统、B 站、狗东等等。

像某验的解决方案也有很多,不过原理大同小异。

selenium 模拟滑动

使用 selenium 这个大家都听过,步骤大致是将缺口图和原图进行对比获取缺口的横坐标,并使用计算完成拖动轨迹模拟,之后使用 selenium 按照轨迹滑动完成缺口的拼接。

这一类方法的优点是门槛低,原理简单,缺点是完成滑动耗时较长,成功率无法估计(同一轨迹计算规则使用多次后成功率迅速下降)

常见的轨迹生成代码:

import numpy as np
import math
def ease_out_expo(x):
    """
    曲线函数
    :param x:
    :return:
    """
    if x == 1:
        return 1
    else:
        return 1 - pow(2, -10 * x)
def get_tracks(distance, seconds):
    """
    轨迹生成函数
    :param distance: 滑动总距离
    :param seconds: 滑动总时间
    :return:
    """
    tracks = [0]  # 存放轨迹的数组
    offsets = [0]  # 存放滑动总距离的记录数组
    for t in np.arange(0.0, seconds, 0.1):  # 产生一个数列如[0.0, 0.1, 0.2, 0.3]
        offset = round(ease_out_expo(t/seconds) * distance)  # 根据时间t计算在曲线上的滑动距离
        tracks.append(offset - offsets[-1])  # 本次计算的距离减去上一次移动的距离,得到本次的轨迹
        offsets.append(offset)  # 至本次滑动了的总距离
    return offsets, tracks
a, b = get_tracks(138, 3)
print(a, b)
def get_tracksb(distance):
    """
    根据物理的先加速再减速规律计算
    :param distance:
    :return:
    """
    distance += 20  # 加上20是为了滑动超过缺口再回滑
    v = 0  # 初速度
    t = 0.2  # 以0.2秒为一个计算周期
    forward_tracks = []  # 轨迹记录数组
    current = 0  # 初始移动距离
    mid = distance * 3 / 5  # 减速阀值即五分之三的距离加速剩下距离减速
    while current < distance:  # 总移动距离等于输入距离时结束
        if current < mid:  # 加速状态
            a = 2  # 加速度为+2
        else:  # 减速状态
            a = -3  # 加速度-3
        s = v * t + 0.5 * a * (t ** 2)  # 计算0.2秒周期内的位移
        v = v + a * t  # 计算本次周期后的速度
        current += s  # 将之前移动的总距离,加上本次0.2秒周期内移动的距离
        forward_tracks.append(round(s))  # 记录本次0.2秒周期内的移动距离为轨迹
    back_tracks = [-3, -3, -2, -2, -2, -2, -2, -1, -1, -1]  # 手动将开头加上的20,生成减去轨迹,即回滑轨迹
    return {'forward_tracks': forward_tracks, 'back_tracks': back_tracks}

Js 破解关键的参数

这类方法的门槛就比较高了,通过断点调试 Js,逆向分析滑动后提交参数的生成逻辑完成参数的生成,之后构造请求完成提交,当然这中间也是需要分析图片的缺口位置与模拟轨迹,不过没有使用到模拟所以速度快成功率高。

缺点是风险高,代码维护成本高,更新一个新版本就要重新分析而且逆向相关产品的代码是有一定的法律风险的,免费吃住也不是开玩笑的,所以很多能够商业化的大佬们都闷声发大财不会到处张扬。

使用现有的服务

上面两种方法各有各的优缺,很多人就想把这一块的工作量与风险分出去,这就要使用到第三方的服务商了。

不过目前国内市场上的服务商并没有这类服务,目前咸鱼在使用的是一家俄罗斯的服务商 - 2Captcha

这个服务商提供的验证码服务有很多种,其中包含了我们比较关心的 GeeTest 。

每1000次的价格

下面咸鱼给大家简单介绍下如何使用服务。(不要问为啥收费,人家服务商也要吃饭,况且这个价格实在便宜了)

首先,注册一个账号,官网是 http://2captcha.com/zh

首页

完成注册之后会跳转到控制台界面,这里最重要的是获取到属于你的 API Key 。

API KEY

好,拿到这个 API Key 之后就可以上手使用服务完成滑动的破解了。

通过参考官方的 API 文档,我们只需要构建两个 Get 请求就可以了。

第一个 Get 请求的组成是这样的:

https://2captcha.com/in.php
?key= 上面获取的API KEY 
&method=geetest
&gt= 某验参数
&challenge= 某验参数
&api_server=api-na.geetest.com(可选)
&pageurl= 滑动验证码所在的网页地址

参数列表:

参数名 参数介绍
key API KEY
method 表示验证码类型
gt 某验参数1
challenge 某验参数2
api_server api-na.geetest.com(选填)
pageurl 滑动验证码所在的网页地址

这里解释下关于 gtchallenge 这两个参数的获取。

第一个请求中这两个参数其中 gt这个参数是固定的,找一个使用某验的网站就可以获取。例如:

challenge这个参数是由请求返回,你找到这个请求之后按照请求重新获取一次,如果是 XHR 的话也可以直接 replay XHR 。

完成参数构建,提交完第一个请求之后,成功会返回类似下面的结果。


OK|2122988149 or as JSON {"status":1,"request":"2122988149"}

这里面的一串数字就是会话 ID。

有了这个会话 ID 之后我们就可以构建下一个请求,记住两个请求中间需要等待一些时间哦。

https://2captcha.com/res.php
?key=API KEY
&action=get
&id=2122988149

参数列表:

参数名 参数介绍
key API KEY
action Get
id 上一个请求返回的会话ID

这个请求返回的结果就是我们需要的加密参数。

{
      "challenge":"1a2b3456cd67890e12345fab678901c2de",
      "validate":"09fe8d7c6ba54f32e1dcb0a9fedc8765",
      "seccode":"12fe3d4c56789ba01f2e345d6789c012|jordan"
}

以上常见的几类验证码,已经全部介绍完了。

肯定有人问像 google 家的 ReCaptcha 以及和他相似的 hCaptcha 的解决方案没有提到啊?

像以上两类验证码,刚刚提到的服务商也同样有提供接口打码。

至于其他不依靠服务商的解决方案,目前咸鱼还没有接触过,毕竟这两类验证码,咸鱼手动点击都没办法做到一次通过,目前也只能依赖服务商了。


相关文章
|
机器学习/深度学习 人工智能 Java
验证码破解全流程实战
验证码破解全流程实战
456 0
验证码破解全流程实战
|
6月前
|
存储 缓存 前端开发
综合性练习(验证码案例)
综合性练习(验证码案例)
61 6
|
7月前
|
安全 网络安全 数据安全/隐私保护
关于无感验证码的一些感想
无感验证码改善用户体验,通过分析用户行为和设备特征实现悄无声息的验证,有效防范恶意攻击。但其潜在的隐私问题、准确性和技术挑战不容忽视,需平衡隐私保护与系统安全,提高容错性和兼容性,以推动其发展和应用。
|
运维 前端开发 小程序
支付宝认证道理有没有用?想考证书需要做什么准备?
现在的社会中,想要获得更好的生活,就一定要拥有过硬的技术和豪华的资历,在同等的能力下,企业更愿意选择拥有好证书的人,在拥有相同的证书时,企业才会考虑员工的技术能力。
|
运维 机器人 API
细数验证码的N种生成方式
验证码(CAPTCHA)是一种用于确定网站或应用程序使用者是否为人类的技术。它通常由一组图像或数字组成,用户需要输入正确的内容才能通过验证。验证码被广泛用于防止自动化脚本或机器人攻击,以确保用户是真正的人类。
451 0
细数验证码的N种生成方式
|
文字识别 测试技术 Linux
软件测试|一文教你绕过头疼的图形验证码
软件测试|一文教你绕过头疼的图形验证码
软件测试|一文教你绕过头疼的图形验证码
|
文字识别 测试技术 API
验证码识别最佳方案,你不来试试?
验证码识别最佳方案,你不来试试?
|
Java Spring
网站验证码的设计与实现
网站验证码的设计与实现
|
数据采集 机器学习/深度学习 存储
无感验证码将成新趋势,凯格无感验证码深度剖析
滑动拼图验证码,智能无感验证,文字点选验证码,成语点选验证码,行为验证码,凯格科技,空间推理验证码,字体识别验证码,中文字符验证码
530 0
无感验证码将成新趋势,凯格无感验证码深度剖析