xp_cmdshell (Transact-SQL)

Увеличивает число процессов командного ядра Windows в строке для выполнения. Любые выходные данные возвращаются в виде текстовых строк.

Значок ссылки на разделСинтаксические обозначения в Transact-SQL

Синтаксис

xp_cmdshell { 'command_string' } [ , no_output ]

Аргументы

  • 'command_string'
    Это строка, содержащая команду для передачи операционной системе. Аргумент command_string имеет тип varchar(8000) или nvarchar(4000) и не имеет значения по умолчанию. Аргумент command_string не может содержать более одного набора двойных кавычек. Если в путях к файлам или именах программ в аргументе command_string есть пробелы, то необходимо использовать одну пару кавычек. Если входящие пробелы вызывают неполадки, то следует присваивать файлам имена в формате FAT 8.3.

  • no_output
    Необязательный параметр, указывающий, что клиенту не следует возвращать выходные данные.

Значения кодов возврата

0 (успешное завершение) или 1 (неуспешное завершение)

Результирующие наборы

Выполнение следующей процедуры xp_cmdshell возвращает листинг текущего каталога.

EXEC xp_cmdshell 'dir *.exe';
GO

Строки возвращаются в столбце nvarchar(255). Если применяется параметр no_output, то возвращается только следующее:

The command(s) completed successfully.

Замечания

Процесс Windows, порожденный процедурой xp_cmdshell, имеет те же права защиты, что и учетная запись службы SQL Server.

Процедура xp_cmdshell работает синхронно. Управление не возвращается участнику до завершения команды ядра.

Процедуру xp_cmdshell можно включать и отключать с помощью управления политиками, а также с помощью процедуры sp_configure. Дополнительные сведения см. в разделах Основные сведения о настройке контактной зоны и Параметр xp_cmdshell.

Важное примечаниеВажно!

Если процедура xp_cmdshell выполняется в пакете и возвращает ошибку, то выполнение пакета завершается с ошибкой. Это изменение поведения. В более ранних версиях Microsoft SQL Server выполнение пакета продолжилось бы.

Учетная запись-посредник для процедуры xp_cmdshell

Когда ее вызывает пользователь, не являющийся членом предопределенной роли сервера sysadmin, процедура xp_cmdshell подключается к Windows с помощью имени учетной записи и пароля, которые хранятся в учетных данных с именем ##xp_cmdshell_proxy_account##. Если эти посреднические учетные данные не существуют, то процедура xp_cmdshell завершит выполнение с ошибкой.

Учетные данные учетной записи-посредника можно создать путем выполнения процедуры sp_xp_cmdshell_proxy_account. В качестве аргумента эта хранимая процедура обрабатывает имя пользователя Windows и пароль. Например, следующая команда создает посреднические учетные записи-посредники для пользователя домена Windows SHIPPING\KobeR с паролем Windows sdfh%dkc93vcMt0.

EXEC sp_xp_cmdshell_proxy_account 'SHIPPING\KobeR','sdfh%dkc93vcMt0'

Дополнительные сведения см. в разделе sp_xp_cmdshell_proxy_account (Transact-SQL).

Разрешения

Поскольку иногда злоумышленники пытаются повысить свои полномочия с помощью хранимой процедуры xp_cmdshell, по умолчанию процедура xp_cmdshell отключена. Включить ее можно с помощью хранимой процедуры sp_configure или управления на основе политик. Дополнительные сведения см. в разделе Параметр xp_cmdshell.

Когда включено первое, процедуре xp_cmdshell требуется разрешение CONTROL SERVER на выполнение. Процесс Windows, созданный процедурой xp_cmdshell, имеет тот же контекст безопасности, что и учетная запись службы SQL Server. Учетная запись службы SQL Server часто имеет гораздо больше разрешений, чем требуется для работы, выполняемой процессом, который создала процедура xp_cmdshell. Для повышения уровня безопасности доступ к процедуре xp_cmdshell должен иметь ограниченный круг пользователей с высокими правами доступа.

Чтобы разрешить пользователю, не являющемуся администратором, использовать процедуру xp_cmdshell и разрешить SQL Server создавать дочерние процессы с токеном безопасности учетной записи с меньшими правами доступа, выполните следующие шаги.

  1. Создайте и настройте локальную учетную запись Windows или учетную запись домена с меньшими правами доступа, чем требуется процессу.

  2. Используйте системную процедуру sp_xp_cmdshell_proxy_account, чтобы настроить процедуру xp_cmdshell на использование учетной записи с меньшими правами доступа.

    ПримечаниеПримечание

    Эту учетную запись-посредник можно также настроить в среде Среда SQL Server Management Studio, в обозревателе объектов выбрав в контекстном меню для имени сервера пункт Свойства и посмотрев вкладку Безопасность в разделе Серверная учетная запись-посредник.

  3. В среде Management Studio, открыв базу данных master, выполните инструкцию GRANT exec ON xp_cmdshell TO '<somelogin>', чтобы предоставить конкретным пользователям, не являющимся sysadmin, возможность вызывать процедуру xp_cmdshell. Указанное имя входа необходимо сопоставить с пользователем в базе данных master.

Теперь пользователи, не являющиеся администраторами, смогут запускать процессы операционной системы с помощью хранимой процедуры xp_cmdshell, и эти процессы будут запускаться с правами доступа созданной учетной записи-посредника. Пользователи с правами доступа CONTROL SERVER (члены предопределенной роли сервера sysadmin) по-прежнему будут иметь права доступа учетной записи службы SQL Server для дочерних процессов, запускаемых хранимой процедурой xp_cmdshell.

Чтобы определить учетную запись Windows, используемую процедурой xp_cmdshell при запуске процессов операционной системы, выполните следующую инструкцию:

xp_cmdshell 'whoami.exe'

Чтобы определить контекст безопасности для другого имени входа, выполните следующее:

EXECUTE AS LOGIN = '<other_login>' ;
GO
xp_cmdshell 'whoami.exe' ;
REVERT ; 

Примеры

A. Возвращение списка исполняемых файлов

В следующем примере показано, как расширенная хранимая процедура xp_cmdshell выполняет команду каталога.

EXEC master..xp_cmdshell 'dir *.exe'

Б. Применение команд net в Windows

В следующем примере показано применение процедуры xp_cmdshell в хранимой процедуре. Этот пример с помощью команды net send уведомляет пользователей о том, что работа экземпляра SQL Server скоро будет завершена, приостанавливает работу сервера с помощью команды net pause и завершает работу сервера с помощью команды 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

В. Применение без возврата данных

В следующем примере процедуры xp_cmdshell применяется для выполнения командной строки без возвращения данных клиенту.

USE master;
EXEC xp_cmdshell 'copy c:\SQLbcks\AdvWorks.bck
    \\server2\backups\SQLbcks, NO_OUTPUT';
GO

Г. Применение возвращаемого состояния

В следующем примере расширенная хранимая процедура xp_cmdshell также предлагает возвращаемое состояние. Значение кода возврата хранится в переменной @result.

DECLARE @result int
EXEC @result = xp_cmdshell 'dir *.exe'
IF (@result = 0)
   PRINT 'Success'
ELSE
   PRINT 'Failure'

Д. Запись содержимого переменной в файл

В следующем примере содержимое переменной @var записывается в файл с именем var_out.txt в текущем каталоге сервера.

DECLARE @cmd sysname, @var sysname
SET @var = 'Hello world'
SET @cmd = 'echo ' + @var + ' > var_out.txt'
EXEC master..xp_cmdshell @cmd

Е. Захват результата команды в файл

В следующем примере содержимое текущего каталога записывается в файл с именем dir_out.txt в текущем каталоге сервера.

DECLARE @cmd sysname, @var sysname
SET @var = 'dir/p'
SET @cmd = @var + ' > dir_out.txt'
EXEC master..xp_cmdshell @cmd