不能直接删除 xp_cmdshell,因其是系统级动态加载功能,须通过 sp_configure 配置禁用并 RECONFIGURE 生效;仅 sysadmin 可重新启用;还需同步禁用 sp_OACreate、CmdExec 作业及限制链接服务器 RPC。

为什么不能直接删掉 xp_cmdshell?
很多人第一反应是“删了就安全”,但 xp_cmdshell 是系统扩展存储过程,无法用 DROP PROCEDURE 删除——SQL Server 会报错 The object 'xp_cmdshell' does not exist or is not a valid object for this operation.。它由 sqlservr.exe 动态加载,属于服务器级功能开关,控制权在配置层面,不是数据库对象。
禁用 xp_cmdshell 的唯一可靠方式
必须通过 sp_configure 关闭,且需配合 RECONFIGURE 生效。仅改配置不执行重载,重启服务也不自动生效。
- 先启用高级选项:
EXEC sp_configure 'show advanced options', 1; RECONFIGURE; - 再禁用命令外壳:
EXEC sp_configure 'xp_cmdshell', 0; RECONFIGURE; - 验证是否生效:
SELECT * FROM sys.configurations WHERE name = 'xp_cmdshell';——value_in_use列必须为0
注意:这两步必须分开执行,合并在一个批次里会报错 Ad hoc update to system catalogs is not supported.
谁还能绕过禁用重新启用它?
只要拥有 sysadmin 角色权限的登录名(包括 Windows 管理员组映射的账户),就能随时重新启用 xp_cmdshell。这不是漏洞,而是 SQL Server 的设计逻辑:sysadmin 拥有全部服务器级控制权。
- 检查高权限账户:
SELECT name, type_desc FROM sys.server_principals WHERE IS_SRVROLEMEMBER('sysadmin', name) = 1; - 临时禁用高危账户比禁用
xp_cmdshell更有效,例如:ALTER LOGIN [BUILTIN\Administrators] DISABLE; - 应用账号绝不能加
sysadmin,哪怕只读也要用最小权限角色(如db_datareader+ 显式授权)
禁用后仍有命令执行痕迹?查这几个地方
禁用 xp_cmdshell 不等于清除了所有命令执行能力。攻击者可能已通过其他路径落地:
-
sp_OACreate/sp_OAMethod:OLE 自动化过程,同样可执行系统命令,需一并禁用:EXEC sp_configure 'Ole Automation Procedures', 0; RECONFIGURE; - SQL Server Agent 作业:
CmdExec类型的步骤仍可运行命令,检查:SELECT * FROM msdb.dbo.sysjobsteps WHERE subsystem = 'CmdExec'; - 链接服务器(Linked Server):若配置了
rpc out = true,可能被用于远程命令中继,检查:SELECT name, rpc_out_enabled FROM sys.servers;
真正安全的边界不在某个开关是否关闭,而在于 sysadmin 账户是否严格受限、服务账户是否降权、以及是否有未审计的 Agent 作业或链接服务器暴露了执行面。










