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 (Transact-SQL).

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_cmdshelly permitir que SQL Server cree procesos secundarios con el token de seguridad de una cuenta con menos privilegios, siga estos pasos:

  1. Cree y personalice una cuenta de usuario local de Windows o una cuenta de dominio con los permisos mínimos que los procesos requieran.

  2. Use el procedimiento del sp_xp_cmdshell_proxy_account sistema para configurar xp_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.

  3. 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 ejecutar xp_cmdshell. El usuario especificado debe existir en la master 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;