本章目录(7)On this page (7)
  1. 先试最简单的三件事
  2. 识别类绕过
  3. 识别率决定可行性
  4. 为什么这类问题通常不定高危
  5. 顺带一提:短信验证码
  6. 修复
  7. 参考
文章Articles

验证码

从「能不能复用」到「能不能识别」,以及为什么识别类绕过在报告里通常不算高危。

更新Updated 2026.10.25securitywebautomation

先试最简单的三件事

拿到一个带验证码的登录口,别急着上工具。先试这三条:

  1. 验证码能不能复用。登录失败后,同一个验证码再提交一次,看服务端认不认。
  2. 验证码有没有过期。拿到图片,等十分钟再提交。
  3. 验证码有没有跟会话绑定。换一个 session,用原来的验证码。

这三条只要有任意一条成立,爆破就没有障碍,不需要任何识别技术。而这三条在实际系统里成立的比例,比想象中高。

很多系统在前端做了「刷新验证码」,但服务端只校验「这个码在不在已发放的池子里」,不校验「是不是这个会话的」——池子共享,等于没有。

识别类绕过

三条都不成立,才轮到识别。

思路很直接:程序自动取验证码图片 → OCR 识别 → 填进登录请求。识别率够高,爆破就能跑起来。

工具链是现成的:

  • ddddocr:离线 OCR 库,专为验证码场景训练。ocr.classification(img_bytes) 一行出结果,支持限定字符集(纯数字、纯字母、算术式)。
  • captcha-killer-modified:Burp 插件,把「取验证码 → 调识别接口 → 回填」串进 Intruder。
  • Yakit:用 beforeRequest / afterRequest 两个钩子做同样的事,不用装插件。

识别服务通常是一个几十行的 HTTP 服务:收 base64 图片,返回识别结果。放在本地跑,不依赖外部接口。

算术验证码(3+5=?)也能识别,识别出算式之后自己算一下再提交,命中率比纯字符高。

识别率决定可行性

一个四位字符的验证码,识别率 90%,意味着平均 1.1 次能过一次。配合密码字典,几千次尝试就能跑完。

识别率 50%,就需要两次一次成功,请求量翻倍,很容易触发频率限制。

所以测这类问题时,先跑 100 张看识别率。低于 60% 就别往下做了,报告里写「验证码可被自动识别,识别率 xx%」,比硬跑出结果更诚实。

为什么这类问题通常不定高危

「验证码可被 OCR 识别」单独拿出来,只是一个「防护措施强度不足」。它要变成高危,必须叠加一个前提:没有其他登录保护。

如果系统同时有:账号锁定(5 次失败锁定 30 分钟)、异地登录告警、强密码策略——那验证码被识别只是让爆破变慢,不构成实际风险。

如果系统什么都没有,只有验证码这一道,那它就是唯一的防线,被绕过等于没有。

报告里写这个区别,客户才知道该先修哪个。

顺带一提:短信验证码

登录、注册、找回密码三个入口的短信验证码,问题往往比图形验证码多:

  • 验证码 4 位、6 位数字,有效期 5 分钟,可爆破。
  • 校验通过后不失效,同一码可重复用。
  • 手机号和验证码不绑定,A 的码能验证 B 的手机号。
  • 返回包里有 code 字段,前端校验后端不校验。

第四条最常见:把响应里的 {"success":false} 改成 true,前端就跳转了,后端根本没验。

修复

  • 验证码与会话绑定,一次性使用,60 秒过期。
  • 图形验证码不要太简单,也别太复杂——太复杂用户体验差,且挡不住 OCR。
  • 登录失败次数限制,按账号 + IP 双维度。
  • 短信验证码:6 位、5 分钟、一次有效、与手机号绑定、后端校验。
  • 关键操作(改密码、转账)加二次验证。

参考

  • 《验证码绕不过去》,公众号 瑶光安全团队Alkaid