Windows PowerShellSécurisation de l'environnement de ligne de commande

Don Jones

Lorsque l'équipe de Windows PowerShell s'est réunie pour créer un nouvel environnement de ligne de commande et que le terme « script » a été prononcé, les cris de consternation ont sans doute été entendus dans tout Redmond. Après tout, les précédents efforts de Microsoft en matière de scripts d'administration (je parle ici de VBScript), étaient loin d'être exempts de problèmes. Un

modèle d'exécution trop permissif, allié à la tendance de la plupart des utilisateurs à ouvrir une session en tant qu'administrateurs complets, a ouvert la boîte de Pandore.

« Toute de même », doivent avoir imploré les personnes participant à cette première réunion de Windows PowerShell™ « on va pas remettre ça ». Elles ont été exaucées. Microsoft a fortement amélioré sa réputation en matière de sécurité, en grande partie parce qu'il a commencé à penser à la sécurité au début du cycle de développement du produit plutôt qu'à la fin. Cette philosophie est tout à fait évidente dans Windows PowerShell.

Pourquoi mes scripts ne s'exécutent-ils pas ?

Installez Windows PowerShell sur un ordinateur propre et double-cliquez sur un fichier .ps1 : voici qu'apparaît le Bloc-notes, pas Windows PowerShell. C'est parce que l'extension de nom de fichier .ps1 (l'extension utilisée pour les scripts Windows PowerShell), n'a pas d'association avec l'environnement de ligne de commande même. En d'autres termes, vous ne pouvez pas exécuter un script simplement en double-cliquant sur celui-ci. Le seul moyen d'exécuter un script est d'ouvrir Windows PowerShell, de taper le nom du script, puis d'appuyer sur Entrée.

En fait, il ne suffit pas de taper le nom de script, non plus. Vous pouvez voir à la figure 1 que le fichier Demo1.ps1 existe dans le dossier actuel, pourtant lorsque vous tapez sur demo1 et que vous appuyez sur Entrée, une erreur est générée : « The term « demo1 » is not recognized as a cmdlet, function, operable program, or script file. » (« Le terme « demo1 » n'est pas reconnu en tant qu'applet de commande, fonction, programme exécutable ou fichier de script. ») Pourquoi ? Après tout, le fichier se trouve juste là.

Figure 1 Pour éviter le détournement de commande, Windows PowerShell a besoin du chemin de votre script.

Figure 1** Pour éviter le détournement de commande, Windows PowerShell a besoin du chemin de votre script. **(Cliquer sur l'image pour l'agrandir)

C'est un autre aspect du modèle de sécurité de Windows PowerShell. Une astuce fréquemment tentée par les utilisateurs malveillants dans d'autres environnements de ligne de commande consiste en effet à créer un script avec le même nom de fichier qu'une commande intégrée. Ainsi, par exemple, si vous souhaitez qu'un utilisateur exécute votre script, vous pouvez le nommer Dir.ps1 et le déposer dans un dossier. Si vous avez convaincu l'utilisateur de taper Dir et d'appuyer sur Entrée, votre script peut s'exécuter, pas la commande Dir que l'utilisateur attendait. Cette technique est appelée détournement de commande. Dans Windows PowerShell, vous devez toujours fournir un chemin pour un tel script, ce qui protège Windows PowerShell contre tout détournement de commande.

L'exécution de demo1 ne fonctionne pas, puisqu'il n'y a pas de chemin, mais ./demo1 fonctionne. C'est parce que j'ai maintenant spécifié le chemin, le dossier actuel. Cette ligne de commande est moins susceptible d'être confondue avec une commande intégrée puisque vous ne taperiez jamais aucun chemin si vous faisiez référence à une commande intégrée. Ainsi, la nécessité d'un chemin aide Windows PowerShell à éviter tout détournement de commande et toute confusion sur ce qui peut se produire lorsque vous appuyez sur Entrée.

Stratégie pour l'exécution de scripts

Vous disposez donc d'une copie fraîchement installée de Windows PowerShell, vous utilisez la syntaxe correcte et vous tentez d'exécuter un script. À votre grande surprise, vous êtes accueilli avec un autre message d'erreur, vous informant que Windows PowerShell n'est pas autorisé à exécuter des scripts. Pardon ??? Bienvenue dans la stratégie d'exécution de l'environnement de ligne de commande.

Vous pouvez afficher la stratégie d'exécution actuelle en exécutant Get-ExecutionPolicy dans l'environnement de ligne de commande. Par défaut, il est défini sur Restricted, ce qui signifie tout simplement que les scripts ne s'exécuteront pas. Jamais. Pour personne. Par défaut, Windows PowerShell ne peut être utilisé que de manière interactive, plutôt que pour exécuter des scripts. Vous pouvez utiliser l'applet de commande Set-ExecutionPolicy pour choisir un des quatre paramètres de stratégie d'exécution possibles :

  • Restricted, le paramètre par défaut, n'autorise pas l'exécution des scripts.
  • AllSigned n'exécute que les scripts de confiance (plus d'informations sur cette question dans un instant).
  • RemoteSigned exécute les scripts locaux sans qu'ils doivent être approuvés, mais les scripts téléchargés à partir d'Internet doivent être approuvés avant de pouvoir être exécutés.
  • Unrestricted autorise l'exécution de tous les scripts, même les scripts non approuvés.

En fait, AllSigned est le paramètre le plus bas sur lequel tout ordinateur de production devrait être défini. Je trouve RemoteSigned utile dans les environnements de développement et de test, mais ce n'est pas nécessaire pour l'utilisateur type. Unrestricted me paraît inutile et je n'aurais aucune objection si une version future de Windows PowerShell omettait ce paramètre trop permissif.

Une question de confiance

Votre ordinateur est préconfiguré pour approuver certaines autorités de certification racines (CA), c'est-à-dire des serveurs qui émettent des certificats numériques. La figure 2 affiche l'application du Panneau de configuration Options Internet, qui énumère les autorités de certification racines de confiance. Dans Windows Vista®, cette liste est assez courte et inclut seulement quelques autorités de certification racines commerciales majeures. Par contre, dans Windows® XP, la liste par défaut est longue et inclut de nombreuses autorités de certification racines dont je n'ai jamais entendu parler. Lorsqu'une autorité de certification racine figure sur cette liste, cela signifie essentiellement que vous approuvez l'entreprise qui utilise cette autorité de certification pour vérifier l'identité d'une personne avant d'émettre un certificat numérique.

Lorsque vous obtenez un certificat numérique de Classe III, couramment appelé certificat de signature de code, l'autorité de certification (qui peut être une autorité de certification commerciale ou privée existant dans votre organisation) doit vérifier votre identité. Ce certificat numérique est comme un passeport ou une carte d'identité électronique. Avant de me donner un ID indiquant que je suis Don Jones, par exemple, l'autorité de certification doit prendre certaines mesures pour s'assurer que je suis vraiment Don Jones. Lorsque vous utilisez votre certificat pour signer numériquement un script Windows PowerShell, ce que vous pouvez faire en utilisant l'applet de commande Set-AuthenticodeSignature, vous signez votre nom sur le script. Bien sûr, si vous pouvez obtenir un faux certificat contenant le nom d'une autre personne, vous pouvez signer son nom sur le script, c'est pourquoi il est si important que seules les autorités de certification dignes de confiance figurent dans la liste de la figure 2.

Figure 2 Autorités de certification racines par défaut dans Windows Vista

Figure 2** Autorités de certification racines par défaut dans Windows Vista **(Cliquer sur l'image pour l'agrandir)

Lorsque Windows PowerShell vérifie si un script est approuvé, ce qu'il fait sous les paramètres de stratégie d'exécution AllSigned et RemoteSigned, il pose trois questions :

  • Ce script est-il signé ? Si non, le script est non approuvé.
  • La signature est-elle intacte ? En d'autres termes, le script a-t-il été modifié depuis sa signature ? Si la signature n'est pas intacte, le script est non approuvé.
  • La signature a-t-elle été créée à l'aide d'un certificat numérique émis par une autorité de certification racine de confiance ? Si non, le script est non approuvé.

Applet de commande du mois : Set-AuthenticodeSignature

Set-AuthenticodeSignature est essentiel pour signer numériquement vos scripts Windows PowerShell, ce qui vous permet d'utiliser la stratégie d'exécution de l'environnement de ligne de commande la plus sûre, AllSigned. Pour utiliser cette applet de commande, vous démarrez avec une autre applet de commande, Get-ChildItem, qui extrait un certificat de signature de code installé :

$cert = Get-ChildItem –Path cert:\CurrentUser\my –codeSigningCert

Vous devez remplacer le chemin d'accès de ce fichier par un chemin qui pointe vers un certificat installé, tout certificat installé étant accessible via le lecteur cert: . Une fois le certificat chargé, exécutez la commande suivante pour signer un script :

Set-AuthenticodeSignature MyScript.ps1

–cert $cert

Bien sûr, vous devez fournir le chemin complet de votre fichier script .ps1. L'environnement de ligne de commande ajoute un bloc de signature au fichier.

Comment la confiance améliore-t-elle la sécurité ? Bien sûr, un pirate informatique pourrait potentiellement écrire un script malveillant, le signer et convaincre un utilisateur de votre environnement de l'exécuter. Puisque le script a été signé, il s'exécutera. Mais comme il a été signé, vous pouvez utiliser la signature pour découvrir l'identité de l'auteur et prendre les mesures nécessaires (comme appeler les autorités chargées de l'application de la loi). Il faudrait toutefois qu'une personne soit extrêmement stupide pour créer un script malveillant, puis y apposer son vrai nom !

Bien sûr, si un utilisateur malveillant peut obtenir, par exemple d'une autorité de certification qui ne dispose pas d'un processus de vérification d'identité fiable, un certificat pour l'identité d'une autre personne, vous ne pourrez pas utiliser la signature pour identifier le véritable coupable. C'est pourquoi les autorités de certification racines que vous approuvez doivent avoir un processus de vérification d'identité que vous jugez satisfaisant.

Si vous utilisez le paramètre de stratégie d'exécution AllSigned, vous devez même signer numériquement chaque script que vous créez vous-même pour qu'il puisse s'exécuter. L'applet de commande Set-AuthenticodeSignature est assez facile à utiliser, mais elle peut être un peu embêtante. C'est là que les logiciels tiers peuvent s'avérer utiles. Je vous recommande de sélectionner un éditeur de script ou un environnement de développement visuel qui signera automatiquement vos scripts en utilisant le certificat que vous spécifiez. Ainsi, l'utilisation des signatures est transparente et ne nécessite aucun effort supplémentaire. Si vous souhaitez des suggestions d'éditeurs et d'environnements de développement prenant en charge ces éléments, visitez quelques-uns des forums d'écriture de script en ligne (tels que mon site à l'adresse SscriptingAnswers.com) et publiez un message pour demander aux autres fans de Windows PowerShell ce qu'ils utilisent.

Une fois que vous possédez un certificat, vous pouvez également exécuter le code uniligne suivant pour signer tous les scripts d'un emplacement particulier :

Get-Childitem *.ps1 | %{Set-AuthenticodeSignature $_.fullname $cert}

Sécurisation centralisée

La stratégie d'exécution de Windows PowerShell peut, évidemment, être configurée ordinateur par ordinateur. Mais cela n'est pas une bonne solution pour les environnements d'entreprise. Au lieu de cela, vous pouvez utiliser la stratégie de groupe. (Vous pouvez télécharger les modèles d'administration de Windows PowerShell sur le site go.microsoft.com/fwlink/?LinkId=93675.) Il suffit de déposer le fichier dans un objet de stratégie de groupe (GPO) qui affecte l'ensemble de votre domaine et de le définir sur Restricted. Ainsi, quel que soit l'endroit où Windows PowerShell est installé, vous pouvez être sûr que les scripts ne s'exécuteront pas. Vous pouvez ensuite appliquer un paramètre plus permissif (par exemple, AllSigned) uniquement sur les ordinateurs qui doivent exécuter des scripts (comme votre propre poste de travail).

Informations d'identification alternatives

Contrairement aux précédents langages de script administratifs pour Windows, Windows PowerShell est même conçu pour traiter des informations d'identification alternatives de façon sécurisée. Par exemple, l'applet de commande Get-WMIObject possède un paramètre d'informations d'identification qui vous permet de spécifier des informations d'identification alternatives pour les connexions WMI distantes. Le paramètre acceptera un nom d'utilisateur mais pas un mot de passe, vous empêchant ainsi de coder en dur des mots de passe sensibles dans un script en texte clair. Au lieu de cela, lorsque vous fournissez le nom d'utilisateur, Windows PowerShell vous invite à saisir un mot de passe à l'aide d'une boîte de dialogue. Si vous envisagez d'utiliser à nouveau les informations d'identification alternatives, vous pouvez stocker ces informations à l'aide de l'applet de commande Get-Credential :

$cred = Get-Credential DOMAIN\USER

Vous serez immédiatement invité à entrer un mot de passe et les informations d'identification finales seront stockées dans la variable $cred. La variable $cred peut ensuite être transmise au paramètre d'informations d'identification aussi souvent que nécessaire. Vous pouvez même utiliser les applets de commande de ConvertTo-SecureString et ConvertFrom-SecureString pour convertir les informations d'identification en chaîne chiffrée ou convertir une chaîne chiffrée précédemment en informations d'identification.

Le problème c'est que votre clé de chiffrement se retrouve stockée dans un script en texte brut, ce qui va à l'encontre de la sécurité. Donc au lieu de cela, vous pouvez ajouter un appel à Get-Credential dans votre profil Windows PowerShell. Lorsque Windows PowerShell s'exécute, vous êtes alors immédiatement invité à saisir un nom d'utilisateur et un mot de passe, qui sont ensuite stockés dans une variable nommée $cred. Ainsi, vous disposez toujours d'une variable $cred disponible dans l'environnement de ligne de commande représentant un compte d'administrateur de domaine. Vous ne devez en outre pas vous soucier d'enregistrer de ces informations d'identification. Comme celles-ci sont recréées chaque fois que vous ouvrez l'environnement de ligne de commande, il n'est pas nécessaire de les stocker.

Sécurisation par défaut

Par défaut, Windows PowerShell est installé et configuré avec les paramètres probablement les plus sûrs que vous puissiez imaginer pour un environnement de ligne de commande d'administration prenant en charge l'écriture de scripts. Á moins que vous ne modifiez ces paramètres, Windows PowerShell restera aussi sûr que possible. En d'autres termes, tout ce qui réduit la sécurité dans Windows PowerShell résulte de votre décision et de votre action. Donc avant de modifier les valeurs par défaut (par exemple reconfigurer les associations d'extension de fichier, modifier la stratégie d'exécution, etc.), assurez-vous que vous comprenez les conséquences de vos actions et que vous êtes prêt à assumer la responsabilité de vos modifications.

Don Jones est le gourou principal des scripts chez SAPIEN Technologies et formateur pour Scriptingtraining Com. Vous pouvez le joindre par le biais de son site Web à l’adresse suivante : scriptingAnswers.com.

© 2008 Microsoft Corporation et CMP Media, LLC. Tous droits réservés. Toute reproduction, totale ou partielle, est interdite sans autorisation préalable.