從 SQL Server 7.0 起,系統內建數個未公開文件化的擴展預存程序(Extended Stored Procedures),可直接讀寫 Windows 註冊表。這些功能雖在 SQL Server 2000 中保留,但微軟從未正式支援,且可能在未來版本移除。更關鍵的是,它們常被惡意利用作為提權與側向移動的跳板。本文完整記錄其語法、參數與實戰範例,並給出強化防護建議。
功能:以多重結果集返回指定註冊表路徑下的所有鍵值對。
EXEC xp_regenumvalues @rootkey, @subkey
| 參數 | 說明 | 範例值 |
|---|---|---|
| @rootkey | 根鍵常數字串 | 'HKEY_LOCAL_MACHINE' |
| @subkey | 子鍵路徑(無反斜線) | 'SOFTWARE\Microsoft\Windows\CurrentVersion\Run' |
實戰範例:檢視開機自啟動項目
USE master;
EXEC xp_regenumvalues 'HKEY_LOCAL_MACHINE', 'SOFTWARE\Microsoft\Windows\CurrentVersion\Run';
功能:精確讀取指定路徑下的特定數值。
EXEC xp_regread @rootkey, @subkey, @value_name
實戰範例:取得常用檔案目錄
USE master;
EXEC xp_regread 'HKEY_LOCAL_MACHINE', 'SOFTWARE\Microsoft\Windows\CurrentVersion', 'CommonFilesDir';
功能:建立或更新註冊表數值,支援字串與整數兩型別。
EXEC xp_regwrite @rootkey, @subkey, @value_name, @type, @value
| @type 值 | 對應型別 | 備註 |
|---|---|---|
| 'REG_SZ' | 字串 | 最常用 |
| 'REG_DWORD' | 32 位整數 | 需傳入數字字串 |
實戰範例:寫入測試字串值
USE master;
EXEC xp_regwrite 'HKEY_LOCAL_MACHINE', 'SOFTWARE\Microsoft\Windows\CurrentVersion',
'TestValueName', 'REG_SZ', 'hello';
EXEC xp_regdeletevalue @rootkey, @subkey, @value_name
範例:移除上述測試值
USE master;
EXEC xp_regdeletevalue 'HKEY_LOCAL_MACHINE', 'SOFTWARE\Microsoft\Windows\CurrentVersion', 'TestValueName';
EXEC xp_regdeletekey @rootkey, @subkey
範例:刪除測試鍵
USE master;
EXEC xp_regdeletekey 'HKEY_LOCAL_MACHINE', 'SOFTWARE\Microsoft\Windows\CurrentVersion\Testkey';
Run、Services、Image File Execution Options 等關鍵路徑可植入後門xp_cmdshell 或直接使用 xp_regwrite 修改 HKLM\SYSTEM\CurrentControlSet\Services\TermService\Start = 2 開啟 RDP-- 撤銷 public 角色執行權限(需 sysadmin 執行)
REVOKE EXECUTE ON xp_regenumvalues TO public;
REVOKE EXECUTE ON xp_regread TO public;
REVOKE EXECUTE ON xp_regwrite TO public;
REVOKE EXECUTE ON xp_regdeletevalue TO public;
REVOKE EXECUTE ON xp_regdeletekey TO public;
-- 建立受控封裝程序,記錄所有註冊表操作
CREATE PROCEDURE dbo.sp_safe_regread
@rootkey NVARCHAR(100), @subkey NVARCHAR(200), @value_name NVARCHAR(100)
WITH EXECUTE AS OWNER
AS
BEGIN
INSERT INTO dbo.Registry_Audit (SPID, LoginName, RootKey, SubKey, ValueName, OpTime, OpType)
VALUES (@@SPID, SYSTEM_USER, @rootkey, @subkey, @value_name, GETDATE(), 'READ');
EXEC xp_regread @rootkey, @subkey, @value_name;
END;
| 服務 | 建議帳戶類型 | 禁止帳戶類型 |
|---|---|---|
| MSSQLSERVER | 專用網域使用者帳戶 | Local System / Local Admin / Domain Admin |
| SQLServerAgent | 專用網域使用者帳戶 | Local System / Local Admin / Domain Admin |
注意:若 SQL Server Agent 需執行 CmdExec/ActiveX 作業或使用 SQL 驗證連線,則需本機管理員權限——此時應拆分關鍵業務至獨立實例,隔離風險。
sp_execute_external_script 支援 Python/R,可透過標準庫操作註冊表,具備更細緻權限模型這五個未文件化擴展預存程序是 SQL Server 早期架構的歷史遺留。雖提供註冊表直存便利,但其高風險屬性決定了必須嚴格管控。現代架構下,應優先採用 CLR、外部腳本或應用層 API 替代,並配合最小權限原則徹底封鎖直接資料庫層面的系統級操作能力。