SQL服务器中的xp_cmdshell和sp_xp_cmdshell_proxy_account存储过程

861 阅读5分钟

本文介绍了SQL Server中xp_cmdshell和sp_xp_cmdshell_proxy_account系统存储过程,以及开发人员如何使用它们来执行Windows命令。

什么是xp_cmdshell存储过程?

简而言之,xp_cmdshell是SQL Server中的一个系统存储过程。它允许从SQL Server环境中执行Windows shell命令。当命令被作为输入字符串传递时,shell的输出被作为文本行返回。

xp_cmdshell需要两个参数;一个是必需参数,一个是最佳参数。

  • Windows shell命令:(必填,方向:输入,数据类型。NVarchar(4000)或Varchar(8000))。将被传递给Windows操作系统的命令
  • no_output(可选,方向:输入):当这个关键字被传递给xp_cmdshell时,不会返回任何输出。

xp_cmdshell的默认目录是Windows system32文件夹。(C:\Windows\System32)。

让我们检查一下在Windows shell中执行命令和使用xp_cmdshell存储过程的区别。让我们执行dir命令,列出这个目录下的所有可执行文件。让我们首先从Windows命令壳中执行该命令。下面的图片显示了该命令的输出。

Windows cmd output

图1 - Windows cmd输出

现在,如果我们使用xp_cmdshell存储过程执行同样的命令,我们可以检查输出是否相同。

xp_cmdshell output

图2 - xp_cmdshell输出

现在,让我们尝试使用no_output关键字。如下面的图片所示,没有返回任何结果。

using no_ouptut parameter

图3 - 使用no_ouptut参数

xp_cmdshell是如何启用的?

默认情况下,当我们试图执行xp_cmdshell存储过程时,会抛出以下异常。

SQL Server阻止了对组件 "xp_cmdshell "的存储过程 "sys.xp_cmdshell "的访问,因为作为该服务器安全配置的一部分,这个组件已经关闭。系统管理员可以通过使用sp_configure来启用'xp_cmdshell'的使用。关于启用 "xp_cmdshell "的更多信息,请在SQL Server Books Online中搜索 "xp_cmdshell"。

根据微软的文档,这个功能被禁用,因为恶意用户有时会试图通过使用它来提升自己的权限。要启用这个功能,我们必须首先使用sp_configure存储过程来启用高级配置,然后启用xp_cmdshell的使用。

EXEC sp_configure 'show advanced options', 1;  
  GO  
  RECONFIGURE;  
  GO  
  EXEC sp_configure 'xp_cmdshell', 1;  
  GO   
  RECONFIGURE;  
  GO  

xp_cmdshell是如何执行Windows命令的?

我们可以想到一个问题,xp_cmdshell是如何执行Windows命令的?用户账户是用来做什么的?

当它被一个属于SysAdmin角色的用户调用时,xp_cmdshell使用SQL Server服务账户在Windows中执行命令。主要的漏洞是,服务账户的权限往往超过执行进程的要求,这意味着它应该只为一些特定的用户启用。

checking the windows user used to execute Windows commands

图4 - 检查用于执行Windows命令的windows用户

如果用户不是SysAdmin角色的成员,xp_cmdshell将使用存储在名为*##xp_cmdshell_proxy_account##*的凭证中的账户名和密码执行命令。如果这个代理凭证不存在,xp_cmdshell将失败。

使用sp_xp_cmdshell_proxy_account存储过程

假设我们需要从一个不属于SysAdmin角色的用户执行xp_cmdshell存储过程。在这种情况下,我们首先需要使用以下命令授予映射的数据库用户执行。

  GRANT EXECUTE ON xp_cmdshell TO TestUser

Granting the execution of xp_cmdshell stored procedure

图5 - 授予xp_cmdshell存储过程的执行权

或者抛出以下异常。

在对象'xp_cmdshell',数据库'mssqlsystemresource',模式'sys'上拒绝了EXECUTE权限。

The thrown exception when execution is not granted

图6 - 当执行权限未被授予时抛出的异常

当它被一个不属于sysadmin固定服务器角色的用户调用时,xp_cmdshell通过使用存储在名为*##xp_cmdshell_proxy_account##的凭证中的账户名和密码连接到Windows。*如果这个代理凭证不存在,xp_cmdshell将以下面的错误信息失败。

xp_cmdshell代理账户信息不能被检索到或者是无效的。验证'##xp_cmdshell_proxy_account##'凭证是否存在并包含有效信息。

创建一个代理账户凭证

为了配置*##xp_cmdshell_proxy_account##*,我们需要使用sp_xp_cmdshell_proxy_account系统存储过程。这个存储过程有两个使用情况:创建和删除一个代理账户凭证。

为了创建一个代理账户凭证,我们应该向sp_xp_cmdshell_proxy_account存储过程传递两个参数:windows用户名和密码,如下所示。

  EXEC sp_xp_cmdshell_proxy_account 'account_name' , 'password'

即使我们向sp_xp_cmdshell_proxy_account存储过程传递了正确的凭证,也会抛出一个 "访问被拒绝 "的异常。

在执行sp_xp_cmdshell_proxy_account的过程中发生了一个错误。可能的原因是:提供的账户无效,或者'##xp_cmdshell_proxy_account##'证书不能被创建。错误代码。5(访问被拒绝。),错误状态。0.

我们应该关闭SQL Server Management Studio,并以管理员身份再次启动它,以解决这个错误。

Starting SSMS as administrator

图7 - 以管理员身份启动SSMS

重新启动SQL Server Management Studio后,存储过程被成功执行。

Executing the sp_xp_cmdshell_proxy_account stored procedure

图8 - 命令成功执行

#xp_cmdshell_proxy_account#证书将被创建,并在服务器资源管理器的 "Credentials "文件夹中查看。

Credential created after the execution of sp_xp_cmdshell_proxy_account

图9 - 创建的代理账户凭证

现在,让我们尝试执行 "Whoami "命令,检查在Windows上执行xp_cmdshell命令的Windows用户。下面的图片显示,该命令是使用代理账户中定义的Windows凭证执行的。

xp_cmdshell executed using proxy account credentials

图10 - 执行Whoami命令

删除代理账户凭证

要删除现有的代理账户凭证,你应该给sp_xp_cmdshell_proxy_account存储过程传递一个NULL值。

  EXEC sp_xp_cmdshell_proxy_account NULL

总结

这篇文章解释了SQL Server中的xp_cmdshell系统存储过程以及如何使用它。此外,它还解释了如何使用存储过程sp_xp_cmdshell_proxy_account创建一个代理账户凭证。