xp_cmdshell (Transact-SQL)
Se aplica a: SQL Server
Genera un shell de comandos de Windows y lo pasa a una cadena para ejecutarlo. Los resultados se devuelven como filas de texto.
Convenciones de sintaxis de Transact-SQL
Sintaxis
xp_cmdshell { 'command_string' } [ , NO_OUTPUT ]
Argumentos
"command_string"
Cadena que contiene un comando que se va a pasar al sistema operativo. command_string es varchar(8000) o nvarchar(4000), sin ningún valor predeterminado. command_string no puede contener más de un conjunto de comillas dobles. Se requiere un solo par de comillas si hay espacios presentes en las rutas de acceso de archivo o los nombres de programa a los que se hace referencia en command_string. Si tiene problemas con espacios incrustados, considere el uso de nombres de archivo de tipo FAT 8.3 como solución.
salida de NO_
Parámetro opcional, que especifica que no se debe devolver ninguna salida al cliente.
Valores de código de retorno
0
(correcto) o 1
(erróneo).
Conjunto de resultados
La ejecución de la instrucción xp_cmdshell
devuelve una lista de directorios del directorio actual.
EXEC xp_cmdshell 'dir *.exe';
GO
Las filas se devuelven en una columna nvarchar(255). Si se usa la NO_OUTPUT
opción , solo se devuelve la salida siguiente:
The command(s) completed successfully.
Comentarios
El proceso de Windows generado por xp_cmdshell
tiene los mismos derechos de seguridad que la cuenta de servicio de SQL Server.
Precaución
xp_cmdshell
es una característica eficaz y deshabilitada de forma predeterminada. xp_cmdshell
se puede habilitar y deshabilitar mediante la administración basada en directivas o ejecutando sp_configure
. Para obtener más información, consulta Configuración de área expuesta y xp_cmdshell (opción de configuración del servidor). El uso de xp_cmdshell
puede desencadenar herramientas de auditoría de seguridad.
xp_cmdshell
funciona sincrónicamente. El control no se devuelve al autor de la llamada hasta que se completa el comando command-shell. Si xp_cmdshell
se ejecuta dentro de un lote y devuelve un error, se producirá un error en el lote.
cuenta de proxy de xp_cmdshell
Cuando lo llama un usuario que no es miembro del rol fijo de servidor sysadmin , xp_cmdshell
se conecta a Windows mediante el nombre de cuenta y la contraseña almacenados en la credencial denominada ##xp_cmdshell_proxy_account###. Si no existe esta credencial de proxy, xp_cmdshell
se produce un error.
La credencial de la cuenta de proxy se puede crear ejecutando sp_xp_cmdshell_proxy_account
. Como argumentos, este procedimiento almacenado utiliza un nombre de usuario y una contraseña de Windows. Por ejemplo, el siguiente comando crea una credencial de proxy para el usuario de dominio de Windows SHIPPING\KobeR
que tiene la contraseña de Windows sdfh%dkc93vcMt0
.
EXEC sp_xp_cmdshell_proxy_account 'SHIPPING\KobeR', 'sdfh%dkc93vcMt0';
Para obtener más información, consulte sp_xp_cmdshell_proxy_account.
Permisos
Dado que los usuarios malintencionados a veces intentan elevar sus privilegios mediante xp_cmdshell
, xp_cmdshell
está deshabilitado de forma predeterminada. Use sp_configure
o administración basada en directivas para habilitarla. Para más información, vea xp_cmdshell (opción de configuración del servidor).
Cuando se habilita por primera vez, xp_cmdshell
requiere el permiso CONTROL SERVER para ejecutar y el proceso de Windows creado por xp_cmdshell
tiene el mismo contexto de seguridad que la cuenta de servicio de SQL Server. La cuenta de servicio de SQL Server suele tener más permisos de los necesarios para el trabajo realizado por el proceso creado por xp_cmdshell
. Para mejorar la seguridad, el acceso a debe restringirse a xp_cmdshell
usuarios con privilegios elevados.
Para permitir que los no administradores usen xp_cmdshell
y permitir que SQL Server cree procesos secundarios con el token de seguridad de una cuenta con menos privilegios, siga estos pasos:
Cree y personalice una cuenta de usuario local de Windows o una cuenta de dominio con los permisos mínimos que los procesos requieran.
Use el procedimiento del
sp_xp_cmdshell_proxy_account
sistema para configurarxp_cmdshell
para usar esa cuenta con privilegios mínimos.Nota:
También puede configurar esta cuenta de proxy con SQL Server Management Studio si hace clic con el botón derecho en Propiedades en el nombre del servidor en Explorador de objetos y busca en la pestaña Seguridad de la sección Cuenta de proxy del servidor.
En Management Studio, con la
master
base de datos, ejecute la siguiente instrucción Transact-SQL para proporcionar a los usuarios no sysadmin específicos la capacidad de ejecutarxp_cmdshell
. El usuario especificado debe existir en lamaster
base de datos.GRANT exec ON xp_cmdshell TO N'<some_user>';
Ahora los no administradores pueden iniciar procesos de sistema operativo con xp_cmdshell
y esos procesos se ejecutan con los permisos de la cuenta de proxy que configuró. Los usuarios con el permiso CONTROL SERVER (miembros del rol fijo de servidor sysadmin ) siguen recibiendo los permisos de la cuenta de servicio de SQL Server para los procesos secundarios que inicia xp_cmdshell
.
Para determinar la cuenta de Windows que se usa xp_cmdshell
al iniciar procesos del sistema operativo, ejecute la siguiente instrucción:
EXEC xp_cmdshell 'whoami.exe';
Para determinar el contexto de seguridad de otro inicio de sesión, ejecute el siguiente código de Transact-SQL:
EXEC AS LOGIN = '<other_login>';
GO
xp_cmdshell 'whoami.exe';
REVERT;
Ejemplos
A Devolver una lista de archivos ejecutables
En el siguiente ejemplo se muestra el procedimiento almacenado extendido xp_cmdshell
ejecutando un comando de directorio.
EXEC master..xp_cmdshell 'dir *.exe'
B. No se devuelve ninguna salida
En el siguiente ejemplo se utiliza xp_cmdshell
para ejecutar una cadena de comandos sin devolver los resultados al cliente.
USE master;
EXEC xp_cmdshell 'copy c:\SQLbcks\AdvWorks.bck
\\server2\backups\SQLbcks', NO_OUTPUT;
GO
C. Uso del estado de devolución
En el ejemplo siguiente, el xp_cmdshell
procedimiento almacenado extendido también sugiere el estado devuelto. El valor del código de retorno se almacena en la variable @result
.
DECLARE @result INT;
EXEC @result = xp_cmdshell 'dir *.exe';
IF (@result = 0)
PRINT 'Success'
ELSE
PRINT 'Failure';
D. Escribir contenido de variables en un archivo
En el siguiente ejemplo se escribe el contenido de la variable @var
en un archivo denominado var_out.txt
en el directorio actual del servidor.
DECLARE @cmd SYSNAME,
@var SYSNAME;
SET @var = 'Hello world';
SET @cmd = 'echo ' + @var + ' > var_out.txt';
EXEC master..xp_cmdshell @cmd;
E. Capturar el resultado de un comando en un archivo
En el siguiente ejemplo se escribe el contenido del directorio actual en un archivo denominado dir_out.txt
en el directorio actual del servidor.
DECLARE @cmd SYSNAME,
@var SYSNAME;
SET @var = 'dir /p';
SET @cmd = @var + ' > dir_out.txt';
EXEC master..xp_cmdshell @cmd;