记一次验证码破解(上)——获取数据集

165次阅读
没有评论

人工智能 VS 验证码

一直都知道,以目前的 AI 发展,即使是我这种 AI 门外汉,也能轻易的用 AI 破解简单的验证码,这次恰好有需求,来试一试。

获取数据集

社会工程学

本次的需求来源于我想自动登录某网站,他的验证码是这样的。
记一次验证码破解(上)——获取数据集
通用的做法是刷爆验证码的 api,下载一堆未标注的图片,然后自己手动或者花钱找人对大量图片进行标注。
一般来说 1000 张图片就够了。
但是我在这里动用了一点社会工程学,该网站的是做 php 教学的,并且他的教学大纲里有该站点的建立过程,其中就提到了验证码的实现,是直接采用了某开源的方案。
打开开源项目的主页mews/captcha,bingo,完全一致。
记一次验证码破解(上)——获取数据集
这就好办了,有了源码,想让他输出多少图片,就能输出多少带标签的图片。

搭建 php 服务

接下来经典老大难问题,如何把开源项目跑起来。
这部分是真难,从我入行,就一直没碰过 php,完全从 0 开始。
经过各种百度,我终于知道怎么搞了,这里踩坑如何如何暂且不论。

首先创建一个 Dockerfile 文件

FROM php:7
# 验证码的项目需要 gd 这个 php 的图形扩展,下面这个东西是为 php 安装扩展的工具
ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/
# 安装 php 的 gd 图形扩展,他应该是赋予了 php 的绘图能力,验证码是图片,所以用到了这个能力
# composer 为包管理器,相当于 pip 或者 npm
RUN chmod +x /usr/local/bin/install-php-extensions && \
    install-php-extensions gd @composer
# 新建项目,版本号稍微低一点
RUN composer create-project --prefer-dist laravel/laravel:^7.0 myapp

WORKDIR /myapp

# 添加验证码组件
RUN composer require mews/captcha:^3.0
# 这个应该是生成配置文件吧
RUN php artisan vendor:publish --provider="Mews\Captcha\CaptchaServiceProvider"

构建他,并启动

docker build . -t myapp
docker run -it --rm --net=host myapp bash

接着修改两个文件

config/captcha.php内的 math 对应上述那种加法类型的验证码,把他的宽高改成 160*60

记一次验证码破解(上)——获取数据集

vendor/mews/captcha/src/Captcha.php第 358 行的 hash 改成 bag,让验证码数值明文显示

记一次验证码破解(上)——获取数据集

最后启动 php!

php artisan serve --host 0.0.0.0

访问 " http://127.0.0.1:8000/captcha/api/math " 接口就能看到返回的数据

{
    "sensitive": false,
    "key": "17 + 6 = ",
    "img": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKAAAAA8C......"
}

其中 img 本来是 base64 表示的图片,key原本是加密数据,被我们改成了明文,至此服务器创建完成。

下载图片验证码

使用 python 下载 1000 张验证码,并以验证码上的字给他们命名。

import requests
import base64
import os
import uuid

# 单个目标接口
url = "http://1.1.1.145:8000/captcha/api/math"

def download_captcha():
    response = requests.get(url)

    if response.status_code == 200:
        captcha_data = response.json()

        key = captcha_data["key"].replace(" ", "")
        img_data = captcha_data["img"].split(",")[1]  # 获取 base64 编码的图片数据部分

        # 解码 base64 数据
        img_bytes = base64.b64decode(img_data)

        # 以 key 作为目录名,如果目录不存在则创建
        save_directory = os.path.join("captchas", key)
        if not os.path.exists(save_directory):
            os.makedirs(save_directory)

        # 生成唯一标识符(UUID)作为文件名
        unique_filename = str(uuid.uuid4())
        save_path = os.path.join(save_directory, f"{unique_filename}.png")

        # 保存图片到相应目录
        with open(save_path, "wb") as img_file:
            img_file.write(img_bytes)

        print(f"Saved image for key: {key}")
    else:
        print(f"Failed to fetch captcha from {url}. Status code: {response.status_code}")

# 发送请求一万次,单线程
for _ in range(10000):
    download_captcha()

print("Finished downloading captchas.")
正文完
 1
评论(没有评论)