xp_cmdshell (Transact-SQL)
Crea un shell de comandos de Windows y lo pasa a una cadena para ejecutarlo. Los resultados se devuelven como filas de texto.
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, sólo se devolverá lo siguiente:
The command(s) completed successfully.
Notas
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 directiva o ejecutando sp_configure. Para obtener más información, vea Descripción de la configuración del área expuesta y xp_cmdshell (opción).
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 MicrosoftSQL Server, el lote continuaría su ejecución. |
Cuenta de proxy xp_cmdshell
Cuando es llamada por un usuario que no pertenece a la función fija 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).
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 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 xp_cmdshell debe estar restringido a usuarios con privilegios 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 privilegios, siga estos pasos:
Cree y personalice una cuenta de usuario local o una cuenta de dominio de Windows con los privilegios 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 privilegios mínimos.
[!NOTA]
También puede configurar esta cuenta de proxy utilizando SQL Server Management Studio si hace clic con el botón secundario en Propiedades en su nombre del servidor en el Explorador de objetos y busca en la ficha 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 hayan configurado. Los usuarios con el permiso CONTROL SERVER (miembros de la función fija de servidor sysadmin) seguirán recibiendo los permisos de la cuenta de servicio de SQL Server para los procesos secundarios iniciados por xp_cmdshell.
Para determinar la cuenta de Windows que xp_cmdshell va a usar 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. Usar comandos de red de Windows
En el siguiente ejemplo se muestra el uso de xp_cmdshell en un procedimiento almacenado. En este ejemplo se notifica a los usuarios mediante net send que una instancia de SQL Server va a cerrarse, interrumpe el servidor mediante net pause y cierra el servidor utilizando net stop.
CREATE PROC shutdown10
AS
EXEC xp_cmdshell 'net send /domain:SQL_USERS ''SQL Server
shutting down in 10 minutes. No more connections
allowed.', no_output
EXEC xp_cmdshell 'net pause sqlserver'
WAITFOR DELAY '00:05:00'
EXEC xp_cmdshell 'net send /domain: SQL_USERS ''SQL Server
shutting down in 5 minutes.', no_output
WAITFOR DELAY '00:04:00'
EXEC xp_cmdshell 'net send /domain:SQL_USERS ''SQL Server
shutting down in 1 minute. Log off now.', no_output
WAITFOR DELAY '00:01:00'
EXEC xp_cmdshell 'net stop sqlserver', no_output
C. No devolver 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
D. Utilizar el estado de retorno
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'
E. Escribir el 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
F. 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
Historial de cambios
Contenido actualizado |
---|
Se ha mejorado la sección sobre permisos. |