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

SQL Server 掛馬修復:游標遍歷全表替換惡意腳本代碼

     編輯:關於SqlServer

網站遭 SQL 注入導致數據庫大量字符字段被植入惡意 `'; -- 待清除字符串 DECLARE @Clean NVARCHAR(MAX) = N''; -- 替換為空 -- 遍歷所有用戶表的字符型列 DECLARE Cur CURSOR LOCAL FAST_FORWARD READ_ONLY FOR SELECT QUOTENAME(SCHEMA_NAME(o.schema_id)) + '.' + QUOTENAME(o.name) AS TableName, QUOTENAME(c.name) AS ColumnName FROM sys.objects o INNER JOIN sys.columns c ON o.object_id = c.object_id INNER JOIN sys.types t ON c.user_type_id = t.user_type_id WHERE o.type = 'U' AND t.name IN ('char','nchar','varchar','nvarchar','text','ntext') AND o.is_ms_shipped = 0; OPEN Cur; FETCH NEXT FROM Cur INTO @TableName, @ColumnName; WHILE @@FETCH_STATUS = 0 BEGIN -- 動態構建並執行更新 DECLARE @Sql NVARCHAR(MAX) = N'UPDATE ' + @TableName + N' SET ' + @ColumnName + N' = REPLACE(CAST(' + @ColumnName + N' AS NVARCHAR(MAX)), ' + QUOTENAME(@Malicious, N'''') + N', ' + QUOTENAME(@Clean, N'''') + N')' + N' WHERE ' + @ColumnName + N' LIKE ' + QUOTENAME(N'%' + @Malicious + N'%', N''''); -- PRINT @Sql; -- 調試用 EXEC sp_executesql @Sql; FETCH NEXT FROM Cur INTO @TableName, @ColumnName; END CLOSE Cur; DEALLOCATE Cur; GO

關鍵技術點

點說明
CAST(... AS NVARCHAR(MAX))統一轉換為 MAX 類型,避免 text/ntext 不支援 REPLACE 的問題
QUOTENAME(..., '''')字符串字面量自動加單引號並轉義內部單引號,防注入
WHERE ... LIKE僅更新受影響行,大幅減少日志量與鎖競爭
LOCAL FAST_FORWARD READ_ONLY游標優化組合,最小開銷

事後加固清單(必做)

  1. 修補注入漏洞:代碼層面全面改用參數化查詢/預存過程,禁止字符串拼接 SQL。
  2. 最小權限原則:Web 應用連接賬號僅擁有 db_datareader/db_datawriter,禁用 db_owner/sysadmin。
  3. WAF/參數檢查:部署 Web 應用防火牆,攔截疑似注入載荷。
  4. 審計與監控:啟用 SQL Server 審計/擴展事件,記錄失敗登入、錯誤、DDL 變更。
  5. 備份驗證:確保備份未被污染,定期演練還原。
  6. 密碼輪換:立即變更所有數據庫賬號密碼、應用連接串。

現代替代方案:集合化動態 SQL(無游標)

DECLARE @Sql NVARCHAR(MAX) = N'';

SELECT @Sql += N'UPDATE ' + QUOTENAME(SCHEMA_NAME(o.schema_id)) + '.' + QUOTENAME(o.name) + 
    N' SET ' + QUOTENAME(c.name) + 
    N' = REPLACE(CAST(' + QUOTENAME(c.name) + N' AS NVARCHAR(MAX)), ' + 
    QUOTENAME(@Malicious, N'''') + N', ' + QUOTENAME(@Clean, N'''') + N')' +
    N' WHERE ' + QUOTENAME(c.name) + N' LIKE ' + QUOTENAME(N'%' + @Malicious + N'%', N'''') + N';'
FROM sys.objects o
INNER JOIN sys.columns c ON o.object_id = c.object_id
INNER JOIN sys.types t ON c.user_type_id = t.user_type_id
WHERE o.type = 'U' 
  AND t.name IN ('char','nchar','varchar','nvarchar','text','ntext')
  AND o.is_ms_shipped = 0;

-- PRINT @Sql;  -- 確認語句
EXEC sp_executesql @Sql;

優勢:單批次編譯執行、無游標開銷、易於事務控制。注意:語句過長可能超過批次大小限制,超大庫建議分 Schema 分批執行。

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