xp_cmdshell (Transact-SQL)
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 "
Es la cadena que contiene un comando que se pasa al sistema operativo. El parámetro command_string es de tipo varchar(8000) o nvarchar(4000) y no tiene valor predeterminado. El parámetro command_string no puede contener más de un conjunto de comillas dobles. Es necesario un único par de comillas dobles si hay espacios en las rutas de acceso a archivos o en los nombres de programa a los que hace referencia command_string. Si tiene problemas con espacios incrustados, considere el uso de nombres de archivo de tipo FAT 8.3 como solución.no_output
Es un parámetro opcional que especifica que no se devuelven resultados al cliente.
Valores de código de retorno
0 (correcto) o 1 (error)
Conjuntos 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 de tipo nvarchar(255). Si se utiliza la opción no_output, solo se devolverá lo siguiente:
The command(s) completed successfully.
Comentarios
El proceso de Windows creado por xp_cmdshell dispone de los mismos derechos de seguridad que la cuenta de servicio de SQL Server.
xp_cmdshell opera de forma sincrónica. No se devolverá el control al llamador hasta que el comando del shell de comandos esté completo.
Es posible habilitar y deshabilitar xp_cmdshell con Administración basada en directivas o ejecutando sp_configure. Para obtener más información, vea Configuración de Área expuesta y xp_cmdshell (opción de configuración del servidor).
Importante |
---|
Si se ejecuta xp_cmdshell en un lote y devuelve un error, se producirán errores en el lote. Es un cambio de comportamiento. En versiones anteriores de Microsoft SQL Server, el lote continuaría su ejecución. |
Cuenta de proxy xp_cmdshell
Cuando es llamada por un usuario que no pertenece al rol fijo de servidor sysadmin, xp_cmdshell se conecta a Windows con el nombre de cuenta y la contraseña almacenados en la credencial con el nombre ##xp_cmdshell_proxy_account##. Si no existe esta credencial de proxy, xp_cmdshell registrará errores.
Para crear la credencial de cuenta de proxy, debe ejecutar 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, vea sp_xp_cmdshell_proxy_account (Transact-SQL).
Permisos
Dado que, a veces, usuarios malintencionados intentan elevar sus privilegios utilizando xp_cmdshell, xp_cmdshell está deshabilitado de forma predeterminada. Utilice sp_configure o la administración basada en directivas para habilitarlo. Para obtener 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 la ejecución 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 a menudo tiene más permisos de los necesarios para el trabajo que realiza el proceso creado por xp_cmdshell. Para mejorar la seguridad, el acceso a xp_cmdshell debería estar restringido a usuarios con permisos elevados.
Para permitir a los usuarios que no son administradores utilizar xp_cmdshell y permitir que SQL Server cree procesos secundarios con el token de seguridad de una cuenta con menos permisos, 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.
Utilice el procedimiento de sistema sp_xp_cmdshell_proxy_account para configurar xp_cmdshell de modo que use esa cuenta con permisos mínimos.
[!NOTA]
También puede configurar esta cuenta de proxy utilizando SQL Server Management Studio haciendo clic con el botón secundario en Propiedades en su nombre del servidor en el Explorador de objetos, y buscando en la pestaña Seguridad la sección Cuenta de proxy del servidor.
En Management Studio, utilizando la base de datos master, ejecute la instrucción GRANT exec ON xp_cmdshell TO '<somelogin>' para proporcionar a usuarios concretos que no sean sysadmin la capacidad de ejecutar xp_cmdshell. El inicio de sesión especificado debe asignarse a un usuario en la base de datos master.
Ahora, los usuarios que no son administradores pueden iniciar los procesos del sistema operativo con xp_cmdshell y esos procesos se ejecutan con los permisos de la cuenta de proxy que se haya configurado. Los usuarios con el permiso CONTROL SERVER (miembros del rol fijo de servidor sysadmin) seguirán 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 va a usar xp_cmdshell al iniciar los procesos del sistema operativo, ejecute la siguiente instrucción:
xp_cmdshell 'whoami.exe'
Para determinar el contexto de seguridad de otro inicio de sesión, ejecute lo siguiente:
EXECUTE 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 devuelven resultados
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. Usar el estado de devolución
En el siguiente ejemplo, el procedimiento almacenado extendido xp_cmdshell también sugiere el estado de retorno. 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 variable 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
Vea también
Referencia
Procedimientos almacenados extendidos generales (Transact-SQL)
sp_xp_cmdshell_proxy_account (Transact-SQL)