承接入門篇,本文深入探討駭客如何繞過單引號過濾、利用大小寫混淆、URL 編碼特性、POST vs GET 差異,並提供 ASP 安全請求封裝函數 SafeRequest 徹底阻擋注入。
-- 原始:WHERE xtype = 'U'
-- 繞過:WHERE xtype = CHAR(85) -- 'U' ASCII 85
-- 中文:WHERE name = NCHAR(29992)+NCHAR(25143) -- '用戶'
SQL Server 解析 CHAR()/NCHAR() 為字元,無需單引號,繞過簡單字串替換過濾。
-- 過濾 'SELECT' → 嘗試 'SeLeCt'、'sElEcT'
-- 過濾 'UNION' → 'UnIoN'
若過濾邏輯未使用 CASE INSENSITIVE 比對,大小寫變體即可通過。
-- 參數:id=1;--
-- SQL 變為:SELECT * FROM t WHERE id=1;-- ... 後續 WHERE 子句被註解
| 技巧 | 說明 |
|---|---|
| 欄位名猜測 | 參考網站登入表單 input name,通常與資料欄位同名 |
| URL 編碼 | + → 空格、%2B → +、%25 → %;注入 Payload 必須雙重編碼 |
| POST 注入 | IIS 日誌不記錄 POST Body,隱蔽性優於 GET |
| Access vs SQL Server | Access 僅能 ASCII 逐字解碼;SQL Server 可利用錯誤訊息回顯 (CAST/CONVERT 溢位) 效率高 10 倍 |
取代所有 Request("param"),統一進入點過濾:
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, "'", "")
ParaValue = Replace(ParaValue, ";", "")
ParaValue = Replace(ParaValue, "--", "")
ParaValue = Replace(ParaValue, "/*", "")
ParaValue = Replace(ParaValue, "*/", "")
' 可擴充:xp_cmdshell 關鍵字、UNION、SELECT 等
End If
SafeRequest = ParaValue
End Function
' 原本:sql = "SELECT * FROM Users WHERE ID = " & Request("id")
' 修正:
Dim safeId
safeId = SafeRequest("id", 1) ' 強制數字
sql = "SELECT * FROM Users WHERE ID = " & safeId
' 字串參數:
Dim safeName
safeName = SafeRequest("name", 0)
sql = "SELECT * FROM Users WHERE Name = '" & safeName & "'"
SafeRequest 屬於「輸入過濾」,無法防禦所有變體 (編碼、二次注入、截斷);唯有參數化查詢從根本分離代碼與資料。
' ADO 參數化範例
Dim cmd, rs
Set cmd = Server.CreateObject("ADODB.Command")
cmd.ActiveConnection = conn
cmd.CommandText = "SELECT * FROM Users WHERE ID = ? AND Name = ?"
cmd.Parameters.Append cmd.CreateParameter("@id", adInteger, adParamInput, , SafeRequest("id",1))
cmd.Parameters.Append cmd.CreateParameter("@name", adVarWChar, adParamInput, 50, SafeRequest("name",0))
Set rs = cmd.Execute