預設只有 sysadmin 固定伺服器角色成員可執行 xp_cmdshell。若一般登入嘗試執行,會遇到權限不足或代理帳戶錯誤(錯誤 50001:LogonUserW 返回錯誤 1326)。
-- 建立登入與資料庫用戶
USE master;
GO
EXEC sp_addlogin 'njslt', 'nJSlt', 'test_db';
GO
USE test_db;
GO
EXEC sp_adduser 'njslt', 'nJSlt', 'db_owner';
GO
-- 授予 master 資料庫權限與 xp_cmdshell 執行權限
USE master;
GO
EXEC sp_adduser 'njslt', 'nJSlt', 'db_ddladmin';
GO
GRANT EXEC ON xp_cmdshell TO nJSlt;
GO
EXEC sp_addsrvrolemember 'nJSlt', 'sysadmin';
GO
⚠️ 安全性風險極高,sysadmin 擁有伺服器最高權限,僅供測試或特殊需求。
非 sysadmin 使用者執行 xp_cmdshell 時,會模擬 xp_sqlagent_proxy_account 指定的 Proxy 帳戶。若 Proxy 帳戶不可用則失敗。
DECLARE @winuser sysname, @passWord sysname, @Nsql varchar(1000);
-- 1. 在作業系統建立 Windows 使用者作為 Proxy 帳戶
SELECT @winuser = N'xpcmdshell', @passWord = N'xpcmdshell';
SET @Nsql = 'NET USER "' + @winuser + '" "' + @passWord + '" /ADD';
EXEC xp_cmdshell @Nsql;
GO
-- 2. 設定 xp_cmdshell Proxy 帳戶
EXEC master.dbo.xp_sqlagent_proxy_account N'SET', N'', @winuser, @passWord;
GO
設定完成後,以 nJSlt 登入即可正常執行 xp_cmdshell。
-- 移除資料庫用戶、登入、Windows 使用者
USE test_db; GO EXEC sp_dropuser 'nJSlt'; GO
USE master; GO EXEC sp_dropuser 'nJSlt'; GO EXEC sp_droplogin 'nJSlt'; GO
DECLARE @user sysname, @passWord sysname, @sql varchar(1000);
SELECT @user = N'xpcmdshell', @passWord = N'xpcmdshell';
SET @sql = 'NET USER ' + @user + ' /DELETE';
EXEC xp_cmdshell @sql;
SETUSER 切換安全內容無效