xp_cmdshell (Transact-SQL)
S'applique à : SQL Server
Engendre une commande d'environnement Windows et lui transmet une chaîne à traiter. Toute sortie est retournée sous forme de lignes de texte.
Conventions de la syntaxe Transact-SQL
Syntaxe
xp_cmdshell { 'command_string' } [ , NO_OUTPUT ]
Arguments
'command_string'
Chaîne qui contient une commande à passer au système d’exploitation. command_string est varchar(8000) ou nvarchar(4000), sans valeur par défaut. command_string ne peut pas contenir plusieurs guillemets doubles. Une paire unique de guillemets est requise si des espaces sont présents dans les chemins de fichier ou les noms de programme référencés dans command_string. Si l'incorporation d'espaces est source de problèmes, recourez à des noms de fichiers FAT 8.3.
sortie NO_
Paramètre facultatif, spécifiant qu’aucune sortie ne doit être retournée au client.
Valeurs des codes de retour
0
(réussite) or 1
(échec).
Jeu de résultats
L'exécution de l'instruction xp_cmdshell
ci-dessous retourne le contenu du répertoire en cours.
EXEC xp_cmdshell 'dir *.exe';
GO
Les lignes sont retournées dans une colonne nvarchar(255). Si l’option NO_OUTPUT
est utilisée, seule la sortie suivante est retournée :
The command(s) completed successfully.
Notes
Le processus Windows généré par xp_cmdshell
a les mêmes droits de sécurité que le compte de service SQL Server.
Attention
xp_cmdshell
est une fonctionnalité puissante et désactivée par défaut. xp_cmdshell
peut être activé et désactivé à l’aide de la gestion basée sur des stratégies ou en exécutant sp_configure
. Pour plus d’informations, consultez configuration de surface Surface et xp_cmdshell (option de configuration de serveur). L’utilisation de xp_cmdshell
peut déclencher des outils d’audit de sécurité.
xp_cmdshell
fonctionne de manière synchrone. Le contrôle n’est pas retourné à l’appelant tant que la commande command-shell n’est pas terminée. S’il xp_cmdshell
est exécuté dans un lot et retourne une erreur, le lot échoue.
compte proxy xp_cmdshell
Lorsqu’il est appelé par un utilisateur qui n’est pas membre du rôle serveur fixe sysadmin , xp_cmdshell
se connecte à Windows à l’aide du nom du compte et du mot de passe stockés dans les informations d’identification nommées ##xp_cmdshell_proxy_account###. Si ces informations d’identification de proxy n’existent pas, xp_cmdshell
échoue.
Les informations d’identification du compte proxy peuvent être créées en exécutant sp_xp_cmdshell_proxy_account
. Cette procédure stockée accepte comme arguments un nom d'utilisateur et un mot de passe Windows. Par exemple, la commande ci-dessous crée des informations d'identification de proxy pour l'utilisateur de domaine Windows SHIPPING\KobeR
qui possède le mot de passe Windows sdfh%dkc93vcMt0
.
EXEC sp_xp_cmdshell_proxy_account 'SHIPPING\KobeR', 'sdfh%dkc93vcMt0';
Pour plus d’informations, consultez sp_xp_cmdshell_proxy_account.
autorisations
Étant donné que les utilisateurs malveillants tentent parfois d’élever leurs privilèges à l’aide xp_cmdshell
de , xp_cmdshell
sont désactivés par défaut. Utilisez sp_configure
ou gestion basée sur des stratégies pour l’activer. Pour plus d’informations, consultez xp_cmdshell (option de configuration de serveur).
Quand elle est activée pour la première fois, xp_cmdshell
vous devez disposer de l’autorisation CONTROL SERVER pour s’exécuter et le processus Windows créé par xp_cmdshell
le même contexte de sécurité que le compte de service SQL Server. Le compte de service SQL Server a souvent plus d’autorisations que nécessaire pour le travail effectué par le processus créé par xp_cmdshell
. Pour améliorer la sécurité, l’accès doit xp_cmdshell
être limité aux utilisateurs hautement privilégiés.
Pour autoriser les non-administrateurs à utiliser xp_cmdshell
et autoriser SQL Server à créer des processus enfants avec le jeton de sécurité d’un compte moins privilégié, procédez comme suit :
Créez et personnalisez un compte d'utilisateur local Windows ou un compte de domaine avec les privilèges minimaux requis par vos processus.
Utilisez la
sp_xp_cmdshell_proxy_account
procédure système pour configurerxp_cmdshell
pour utiliser ce compte à privilèges minimum.Remarque
Vous pouvez également configurer ce compte proxy à l’aide de SQL Server Management Studio en cliquant avec le bouton droit sur Les propriétés de votre nom de serveur dans l’Explorateur d’objets et en recherchant l’onglet Sécurité de la section Compte proxy serveur.
Dans Management Studio, à l’aide de la
master
base de données, exécutez l’instruction Transact-SQL suivante pour donner aux utilisateurs non sysadmin spécifiques la possibilité d’exécuterxp_cmdshell
. L’utilisateur spécifié doit exister dans lamaster
base de données.GRANT exec ON xp_cmdshell TO N'<some_user>';
Désormais, les non-administrateurs peuvent lancer des processus de système d’exploitation avec xp_cmdshell
utilisant et ces processus s’exécutent avec les autorisations du compte proxy que vous avez configuré. Les utilisateurs disposant de l’autorisation CONTROL SERVER (membres du rôle serveur fixe sysadmin ) continuent de recevoir les autorisations du compte de service SQL Server pour les processus enfants lancés par xp_cmdshell
.
Pour déterminer le compte Windows utilisé lors xp_cmdshell
du lancement des processus du système d’exploitation, exécutez l’instruction suivante :
EXEC xp_cmdshell 'whoami.exe';
Pour déterminer le contexte de sécurité d’une autre connexion, exécutez le code Transact-SQL suivant :
EXEC AS LOGIN = '<other_login>';
GO
xp_cmdshell 'whoami.exe';
REVERT;
Exemples
R. Retourner une liste de fichiers exécutables
L'exemple ci-dessous montre la procédure stockée étendue xp_cmdshell
exécutant une commande de répertoire.
EXEC master..xp_cmdshell 'dir *.exe'
B. Retourner aucune sortie
L'exemple ci-dessous utilise xp_cmdshell
pour exécuter une chaîne de commande sans retourner les informations en sortie au client.
USE master;
EXEC xp_cmdshell 'copy c:\SQLbcks\AdvWorks.bck
\\server2\backups\SQLbcks', NO_OUTPUT;
GO
C. Utiliser l’état de retour
Dans l’exemple suivant, la xp_cmdshell
procédure stockée étendue suggère également l’état de retour. La valeur du code de retour est stockée dans la variable @result
.
DECLARE @result INT;
EXEC @result = xp_cmdshell 'dir *.exe';
IF (@result = 0)
PRINT 'Success'
ELSE
PRINT 'Failure';
D. Écrire le contenu des variables dans un fichier
Dans l'exemple ci-dessous, le contenu de la variable @var
est écrit dans un fichier nommé var_out.txt
dans le répertoire actif sur le serveur.
DECLARE @cmd SYSNAME,
@var SYSNAME;
SET @var = 'Hello world';
SET @cmd = 'echo ' + @var + ' > var_out.txt';
EXEC master..xp_cmdshell @cmd;
E. Capturer le résultat d’une commande dans un fichier
Dans l'exemple ci-dessous, le contenu du répertoire actif est écrit dans un fichier nommé dir_out.txt
dans le répertoire actif du serveur.
DECLARE @cmd SYSNAME,
@var SYSNAME;
SET @var = 'dir /p';
SET @cmd = @var + ' > dir_out.txt';
EXEC master..xp_cmdshell @cmd;