人工智能 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.")
正文完