快速結論:xp_cmdshell 是 SQL Server 用來啟動 Windows 命令殼層的延伸預存程序。它會把命令輸出以文字列傳回 SQL Server,因而能把資料庫權限延伸到作業系統層。新版 SQL Server 安裝預設停用;除非有無法替代的短期維運需求,否則應維持停用。
本篇以 DBA、紅隊驗證與藍隊防禦三種視角,整理 xp_cmdshell 的狀態查核、啟用與停用、執行身分、proxy account、風險、偵測及事件應變。所有命令都應只在自有或明確授權的測試環境使用。
xp_cmdshell 是什麼
xp_cmdshell 接收一段 Windows 命令字串、建立同步子程序,並把標準輸出逐列傳回。呼叫端在命令完成前會等待,因此它不是一般應用程式工作排程器,也不適合作為新系統的整合介面。
安全上的關鍵不是「能不能執行一條命令」,而是命令最後以哪個 Windows 身分執行。如果高權限 SQL 登入、SQL Injection 或錯誤授權能觸發它,資料庫層的問題就可能擴張成主機層事件。
檢查 xp_cmdshell 狀態
先同時查看設定值與目前生效值,不要只看 Management Studio 畫面:
SELECT
name,
value AS configured_value,
value_in_use
FROM sys.configurations
WHERE name IN ('show advanced options', 'xp_cmdshell');
value_in_use = 0 代表目前未啟用,1 代表已生效。若 configured value 與 value in use 不同,表示設定尚未完成重新配置,應先釐清變更來源與維運窗口。
如何啟用 xp_cmdshell
Microsoft 建議新程式不要依賴 xp_cmdshell。若舊系統確實無法替代,應先取得變更核准、限定維運時段並準備停用步驟,再由具備適當伺服器權限的管理者執行:
USE master;
GO
EXECUTE sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
EXECUTE sp_configure 'xp_cmdshell', 1;
GO
RECONFIGURE;
GO
EXECUTE sp_configure 'show advanced options', 0;
GO
RECONFIGURE;
GO
啟用後可用無副作用的身分查核確認執行上下文:
EXECUTE xp_cmdshell 'whoami';
不要把密碼、存取權杖或使用者輸入直接串入命令字串。更不能把 xp_cmdshell 當成修補 SQL Injection 的捷徑;應先修正輸入到查詢之間的信任邊界。可延伸閱讀:
如何停用 xp_cmdshell
工作完成後立即停用,並把 advanced options 恢復為關閉。停用功能不會自動移除過去建立的 proxy credential,因此仍要另外盤點憑證與授權。
USE master;
GO
EXECUTE sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
EXECUTE sp_configure 'xp_cmdshell', 0;
GO
RECONFIGURE;
GO
EXECUTE sp_configure 'show advanced options', 0;
GO
RECONFIGURE;
GO
最後重跑狀態查詢,確認 value_in_use 已回到 0,並在變更單記錄啟用者、原因、開始與結束時間。
執行身分與權限模型
sysadmin 呼叫時
當呼叫者屬於 sysadmin 固定伺服器角色時,子程序會沿用 SQL Server 服務帳號的 Windows 權限。這也是最危險的組合:若服務帳號擁有不必要的本機、網路分享或網域權限,資料庫入侵可能直接擴大。
非 sysadmin 呼叫時
非 sysadmin 使用者需要被明確授予執行權限,且 SQL Server 會使用名為 ##xp_cmdshell_proxy_account## 的 credential。若 proxy credential 不存在,呼叫應失敗。不要為了讓功能「先跑起來」就擴大到 sysadmin。
xp_cmdshell proxy account 最小權限設計
sp_xp_cmdshell_proxy_account 用來建立或刪除 proxy credential,操作本身需要 CONTROL SERVER。正式環境的 proxy account 應遵守:
- 使用獨立受管的 Windows 服務帳號,不共用 DBA 或 SQL Server 服務帳號。
- 拒絕互動式登入,不加入本機 Administrators。
- 只授予必要目錄、分享與執行檔權限。
- 密碼交由企業祕密管理系統或受管服務帳號生命週期管理。
- 定期檢查 credential 是否仍存在、由誰使用,以及需求是否已消失。
建立 credential 時必須以安全管道提供密碼,不能把真實密碼寫進工單、文章、原始碼或 SQL 歷程。需求結束後可用官方程序的 NULL 模式移除 credential,並再次確認非 sysadmin 呼叫已失敗。
風險模型:為什麼 xp_cmdshell 會放大 SQL Server 事件
xp_cmdshell 本身不是 SQL Injection,但它常成為攻擊鏈的放大器。典型路徑是:應用程式可注入查詢或憑證遭竊,攻擊者取得足以改變伺服器設定的權限,接著把資料庫存取轉成作業系統命令執行。
應評估的影響包括:
- 機密性:服務帳號可讀取的設定檔、備份、分享與祕密可能外洩。
- 完整性:檔案、排程、服務與應用程式部署內容可能被變更。
- 可用性:同步命令可能耗盡 SQL 工作執行緒或破壞主機資源。
- 橫向移動:若服務帳號具網域或遠端資源權限,事件可能離開資料庫主機。
- 稽核缺口:只記錄 SQL 登入成功不足以還原子程序實際做了什麼。
因此,單純「預設關閉」不是完整控制。仍要限制誰能取得 CONTROL SERVER、誰能修改設定、SQL Server 服務帳號可存取什麼,以及應用程式是否存在 SQL Injection。
偵測與監控
1. 監控設定漂移
定期擷取 sys.configurations,針對 xp_cmdshell 從 0 變成 1 立即告警。設定漂移應與核准變更單、操作者及時間窗口關聯,而不是只做每日報表。
2. 記錄 SQL 層活動
使用 SQL Server Audit、Extended Events 或既有資料庫活動監控,追蹤:
sp_configure對 advanced options 與xp_cmdshell的變更。xp_cmdshell的執行者、來源主機、應用程式名稱、時間及查詢文字。- proxy credential 的建立、變更與刪除。
- 短時間內出現的授權變更、模擬登入與高權限角色異動。
3. 關聯端點程序
在 EDR 或 Sysmon 端監看 sqlservr.exe 建立命令殼層或腳本直譯器的程序樹。真正有辨識力的是「SQL 事件、父子程序、帳號、網路連線與檔案異動」的時間關聯;只比對單一程序名稱容易產生誤報,也可能漏掉改名或間接呼叫。
4. 建立允許清單基準
若業務確實需要此功能,先定義允許的 SQL 登入、proxy account、命令目的、主機、時段與輸出位置。任何偏離基準的事件都應升級調查。
強化檢查清單
- 新系統維持
xp_cmdshell停用,先尋找外部工作排程或受控服務替代。 - 移除應用程式帳號的 sysadmin、CONTROL SERVER 與不必要 EXECUTE 權限。
- 使用參數化查詢修補 SQL Injection,不依賴字元黑名單。
- 降低 SQL Server 服務帳號的本機、網路與網域權限。
- 必要時使用獨立低權限 proxy account,並限制檔案系統與網路存取。
- 只在核准窗口暫時啟用,工作結束立即停用並驗證。
- 集中保存 SQL Audit、Windows 事件與 EDR 遙測,避免攻擊者只清除單一主機紀錄。
- 對設定啟用、credential 變更與異常子程序建立即時告警。
事件應變:發現未授權 xp_cmdshell 活動怎麼辦
- 保全證據:保存 SQL Audit、查詢遙測、SQL error log、Windows 事件、EDR 程序樹、網路與檔案時間軸。
- 確認範圍:識別呼叫登入、來源應用程式、執行 Windows 身分、開始時間與所有子程序。
- 限制擴散:依應變程序隔離主機或帳號;若仍能安全操作,停用功能並撤銷非必要權限。
- 輪替祕密:處理 SQL 登入、服務帳號、proxy credential,以及主機可讀取的其他憑證。
- 找出初始入口:檢查 SQL Injection、外洩密碼、錯誤角色授權、惡意 DBA 操作與遠端管理入口。
- 復原與監控:從可信狀態復原、修補根因,並提高同帳號、同來源與相鄰主機的監控強度。
主機端調查可搭配本站的 Windows 安全事件應急響應。
替代方案
替代方案要依工作性質選擇,不能只是把同一個高權限命令換個入口:
- 外部工作排程/自動化平台:把作業系統工作移到有審批、祕密管理、逾時與稽核的工具。
- SQL Server Agent 與受限 proxy:適合可預先定義、可排程的維運工作,但仍須最小權限與完整稽核。
- 應用程式服務或佇列:讓資料庫只寫入工作要求,由受控服務驗證後執行。
- SQLCLR:只在經過程式碼審查、簽章與嚴格權限設計時考慮;它不是自動安全的替代品。
- 原生 T-SQL/SSIS:資料搬移與轉換優先使用資料庫或整合服務既有能力。
常見問題
xp_cmdshell 預設有開啟嗎?
新版 SQL Server 安裝預設停用。升級、舊系統或人工變更後仍可能是啟用狀態,所以應查詢 sys.configurations,不要只憑版本判斷。
enable xp_cmdshell 需要什麼權限?
變更伺服器設定通常需要高權限;實際執行者與命令身分則取決於 sysadmin 身分或 proxy account。不要為了啟用功能把應用程式帳號提升為 sysadmin。
xp_cmdshell enable 後如何確認?
先確認 value_in_use = 1,再於授權測試環境執行無副作用的 whoami,核對 Windows 身分是否符合設計。
disable xp_cmdshell 就安全了嗎?
停用能縮小攻擊面,但仍要修補 SQL Injection、撤銷過度授權、檢查服務帳號與 proxy credential,並調查過去是否已有未授權執行。
MySQL 有 xp_cmdshell 嗎?
沒有。xp_cmdshell 是 Microsoft SQL Server 的功能;看到「mysql xp_cmdshell」通常是把不同資料庫產品與攻擊技術混在一起。
最推薦的 xp_cmdshell alternative 是什麼?
多數情況優先使用外部自動化平台、受控應用程式服務或 SQL Server Agent 的最小權限工作。正確選擇取決於是否需要排程、檔案操作、網路存取與人工審批。
參考資料
- Microsoft Learn:Server configuration: xp_cmdshell
- Microsoft Learn:xp_cmdshell (Transact-SQL)
- Microsoft Learn:sp_xp_cmdshell_proxy_account
- Microsoft Learn:SQL Server security best practices
最後檢閱:2026 年 7 月。產品行為與安全建議可能更新,正式變更前請再次核對對應 SQL Server 版本的官方文件。














