验证码突破#
验证码主要用在登陆表单中进行登陆验证,防止表单被暴力破解。如果验证码模块设置不当,如客户端验证、服务端验证码不过期等,验证码就形同虚设。
一般有如下集中验证码分类:
- 图形验证码
- 短信验证码
- 邮件验证码
- 滑动验证码
- 语音验证码
短信验证码#
验证码暴力破解#
现在的短信验证码大多都是 6 位数的验证码,6 位数的验证码不容易爆破,但是如果遇到 4 位数的验证码且失效时间和验证码未限制发送次数的情况下,那么就可以尝试爆破。
4 位数的验证码只需爆破 10000 次,次数算少的了,0000~9999 区间。
案例 1: 任意用户注册
攻击者填写任意手机号进行注册,服务器向攻击者填写的手机号发送短信验证码,此案例的验证码是 4 位数,设置验证码的范围为 0000~9999 区间,对验证码进行暴力破解,成功获取到验证码后,就自动注册了账号。
通过返回的数据包可以判定是否破解成功。
如上图所示,通过返回值的长度可以判定响应大小为 49 的是正确的验证码。
修复建议:
针对验证码的暴力测试,建议采取如下的加固方案:
(1)设置验证码的失效时间,建议为 180 秒;
(2)限制单位时间内验证码的失败尝试次数,如 5 分钟内连续失败 5 次即锁定该账号 15 分钟
验证码绕过测试#
漏洞原理:
在一些案例中,通过修改前端提交服务器返回的数据(例如:res_code 等字段),可以实现绕过验证码,执行我们的请求。
测试流程:
攻击者进入注册账户页面,输入任意手机号码,获取验证码,在注册账户页面填写任意验证码,提交请求并抓包,使用抓包工具查看并修改返回包信息, 转发返回数据包,查看是否注册成功。
修改响应包
修复建议:
针对此漏洞,建议在服务端增加验证码的认证机制,对客户端提交的验证码进行二次校验。
验证码重复使用#
漏洞原理:
在网站的登录或评论等页面,如果验证码认证成功后没有将 session 及时清空,将会导致验证码首次认证成功之后可重复使用。测试时可以抓取携带验证码的数据包重复提交,查看是否提交成功。
测试流程:
攻击者正常流程注册账号,输入页面验证码,抓取提交的数据包,使用发包工具对数据包中的用户名字段修改后进行重复提交,然后查看是否成功注册多个账号。
修复建议:
针对验证认证次数问题,建议验证码在一次认证成功后,服务端清空认证成功的 session,这样就可以有效防止验证码一次认证反复使用的问题。
验证码 GET 传输泄露#
可以看到,验证码就在 get 包中,直接就能获取到验证码, 这样一来,即使无须有的手机号依然可以注册,直接把验证码输入
短信轰炸#
漏洞原理:
短信发送模块处,未对短信的发送次数进行限制,导致可无限制发送短信验证码。
测试流程:
攻击者在短信发送处填写手机号,点击发送验证码,抓包,重复发包尝试是否可以多次接到短信验证码,如果 1s 中可以接收到多次验证码,说明存在短信轰炸漏洞。
一些绕过方法:
1、利用空格绕过
2、修改 cookie 值绕过
3、ip 绕过
4、修改返回值绕过
5、不同账户发送短信绕过
图片验证码#
验证码绕过 (on client)#
js 前端验证
禁用 javascript
浏览器 F12 - 设置 - 停用 JavaScript
来到登陆框
burp 抓包
intruder 爆破成功
验证码绕过(on server)#
同一个验证码发送多次不过期,可爆破,成功登陆
图片验证码自动识别测试#
下载 captcha-killer-modified#
captcha-killer的修改版,支持关键词识别base64编码的图片,添加免费ocr库,用于验证码爆破,适配新版Burpsuite
在Releases处下载 jar 文件
burpsuite 加载此 jar 文件
然后下载 captcha-killer-modified 源码仓库,需要用到 codereg.py 文件,这个文件是用来开启验证码识别模块的,前提需要安装 dddddocr 库。
git clone https://github.com/f0ng/captcha-killer-modified.git
安装 ddddocr 库#
仓库地址:https://github.com/sml2h3/ddddocr
注:我的环境是 mac m1 pro
# brew安装onnxruntime
brew install onnxruntime
pip3 install ddddocr # python3.9安装运行codereg.py报错
使用 python3.10 安装 aiohttp
pip310 install aiohttp -i http://pypi.doubanio.com/simple/ --trusted-host pypi.doubanio.com
运行python310 codereg.py
报错:TypeError: The port is required to be int.
解决报错:
将脚本中default="8888"
更改为default=8888
再次运行即可
重新运行python310 codereg.py
,正常
实战案例 1#
靶场是用 pikachu 的靶场
1、burp 请求验证码 url
请求验证码 URL,点击获取,可以获取右侧的验证码
上图中左侧的请求内容可以先抓个登陆框的包,然后修改 post 中的 url 为验证码的 url,下图中发送到 captcha-killer-modified 插件。
其他案例,关键字
提取
2、设置 ddddocr 接口 url
设置请求模版,Request template
POST /reg HTTP/1.1
Host: 127.0.0.1:8888
Authorization:Basic f0ngauth
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:97.0) Gecko/20100101 Firefox/97.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 8332
<@BASE64><@IMG_RAW></@IMG_RAW></@BASE64>
接口地址设置为:http://127.0.0.1:8888,codereg.py 启动的服务
设置如下:
此时 captcha-killer-modified 面板的内容如下,精准识别了验证码
3、开始 intruder 爆破
- 设置 attack type 为 pitchfork
- 爆破密码字段和 vcode 验证码字段
设置密码处的 payload
设置验证码的 payload
最终识别率,这里用的靶场验证码比较复杂。
codereg.py 的输出
参考#
- https://gv7.me/articles/2019/burp-captcha-killer-usage/
- 书籍参考:《web 攻防业务安全实战指南》