Dans ce tutoriel, je vais vous expliquer comment signer vos scripts. Avant de rentrer dans le sujet, on va voir pourquoi signer les scripts, la principale raison est la sécurité. Si votre environnement (ordinateurs + serveurs) est configuré pour exécuter que des scripts signés et que dans un fichier malveillant un script PowerShell est lancé, celui-ci sera neutralisé car il ne sera pas signer.
Pas mal de Ransomware se sont déployés par des scripts PowerShell qui ont été appelés par des macros.
Cela va aussi permettre de limiter l’exécution de scripts par des attaquants si votre SI est compromis, car pour exécuter des scripts sur vos machines, ils devront également être signer.
Pour signer les scripts, on va utiliser un certificat dédié à la signature de code que l’on va obtenir auprès d’une autorité de certification. Vous l’aurez donc compris, vous avez d’une autorité de certification en interne.
Je le précise au cas où, on se trouve bien évidement dans un environnement Active Directory.
Pour la réalisation de ce tutoriel, j’ai utilisé 3 ordinateurs :
- Un serveur contrôleur de domaine qui héberge aussi l’autorité de certification
- Un ordinateur client Windows 10 que j’utilise pour la réalisation des scripts
- Un serveur joint au domaine pour tester l’exécution des scripts.
Générer un certificat de signature de code sur l’autorité de certification
La première étape afin de pouvoir signer des scripts va être de générer un certificat de signature de code, ce certificat va être utilisé pour signer les scripts mais aussi permettre aux clients de valider la signature.
Par défaut, le modèle du certificat n’est pas disponible, ouvrir la console de l’autorité de certification.
Déplier les éléments pour afficher les différents « dossiers » et aller sur Modèles de certificats 1. Sur la capture, on peut voir que le modèle n’est pas présent.
Faire un clic droit sur Modèles de certificats, puis aller sur Nouveau 1 et cliquer sur Modèle de certificat à délivrer 2.
Sélectionner le modèle Signature de code 1 et cliquer sur le bouton OK 2 pour l’ajouter.
Le modèle est ajouté à la liste.
Pour des raisons de sécurité, ce modèle de certificat ne peut être délivré qu’aux Administrateurs du domaine et aux Administrateurs de l’entreprise.
Maintenant on va faire la demande de certificat, toujours sur le serveur de l’autorité de certification, nous allons ouvrir le magasin de certificats de l’utilisateur connecté.
Depuis une fenêtre exécutée, entrer la commande mmc. Dans la nouvelle console, cliquer sur Fichier 1 puis sur Ajouter/Supprimer un composant logiciel enfichable 2.
Sélectionner Certificats 1 et cliquer sur Ajouter 2.
Choisir Mon compte d’utilisateur 1 et cliquer sur Terminer 2.
Une fois le composant Certificats ajouté, cliquer sur OK 1.
Le magasin de certificat s’affiche, on va faire maintenant notre demande, faire un clic droit sur Personnel, aller sur Toutes les tâches 1 et cliquer sur Demander un nouveau certificat 2.
Au lancement de l’assistant de demande de certificat, cliquer sur Suivant 1.
A la seconde étape de l’assistant, il faut sélectionner l’autorité de certification, par défaut, il n’y a rien à faire, cliquer sur le bouton Suivant 1.
Ensuite s’affiche, la liste des certificats qui peuvent être demandés, cocher le certificat Signature de code 1 puis cliquer sur Détail 2. On va rendre la clé privée exportable.
Cliquer sur le bouton Propriétés 1.
Aller sur l’onglet Clé privée 1, puis cocher la casa Permettre l’exportation de la clé privée 2. Valider ensuite en cliquant sur Appliquer 3 et fermer la fenêtre en cliquant sur le bouton OK 4.
De retour à l’assistant de demande de certificat, cliquer sur le bouton Inscription 1.
Le certificat de signature de code a été généré, cliquer sur Terminer pour fermer l’assistant 1.
Si on regarde dans le magasin Personnel, on retrouve le certificat signature de code 1.
Nous avons maintenant notre certificat pour signer des scripts.
Le certificat ayant été générer directement depuis un serveur, je vous conseille de l’exporter avec la clé privée, de le réimporter sur un autre ordinateur où vous faites vos scripts. Une fois l’importation faites, supprimer le certificat du magasin personnel du serveur.
Pour limiter les risques de fuite du certificat, je signe mes scripts sur un ordinateur qui n’est pas dans le domaine et qui est chiffré afin que l’on ne puisse pas l’extraire.
Vous allez aussi devoir exporter le certificat sans la clé privée, qui devra être déployé sur les ordinateurs où les scripts seront exécutés.
Signer un script PowerShell
Afin de voir son fonctionnement, je vais procéder par étape afin que vous puissiez voir ce qui se passe en détail.
Pour rappel, j’écris les scripts sur un PC Windows 10 et je les exécute sur un serveur Windows.
J’ai créé un script PowerShell simple qui affiche la liste des cartes réseaux dont voici le code ;
Write-Host "List of network cards :"
Get-NetAdapter
Sur la capture qui suit, le script exécuté sur le serveur (où nous allons activer la signature obligatoire ensuite).
Pour le moment, script s’exécute parfaite bien et affiche bien les cartes réseaux disponibles.
Maintenant, on va activer la signature obligatoire des scripts.
Pour forcer la signature obligatoire des scripts, il faut changer la stratégie d’exécution.
Set-ExecutionPolicy AllSigned
Cette commande permet de rentre obligatoire la signature des scripts PowerShell
Si je relance le script sur le serveur, j’obtiens une erreur indiquant que le script n’est pas signé.
Pour résoudre cette erreur, nous allons passer à la signature du script.
Retourner sur l’ordinateur où vous avez créé le script et qui contient le certificat avec la clé privée.
Pour signer notre script, nous allons utiliser la CmdLet Set-AuthenticodeSignature qui va prendre 3 paramètres :
- Le chemin complet du script
- -Certificate qui va indiquer le certificat à utiliser pour signer le script
- -TimestampServer qui permet d’horodater la signature et de continuer à utiliser le certificat et le script même si celui-ci est expiré.
Ce qui donne pour l’exemple du tutoriel :
$Cert4Sign= Get-ChildItem Cert:\CurrentUser\My\ -CodeSigningCert
$ScriptSign = "C:\Users\administrateur\Desktop\PowerShellScript.ps1"
$TimestampServer = "https://timestamp.comodoca.com/authenticode"
Set-AuthenticodeSignature $ScriptSign -Certificate $Cert4Sign -TimestampServer $TimestampServer
Une fois la commande exécutée, si on regarde notre script, on voit la signature qui a été ajoutée à la fin.
Sur l’ordinateur où la stratégie d’exécution des scripts a été modifiée, coller le nouveau fichier. Avant de pouvoir exécuter le script, il faut installer le certificat qui a servi à la signature dans le magasin Editeurs approuvés de l’ordinateur, le certificat doit être exporté sans la clé privée cette fois ci.
Quand le certificat est installé, exécuter de nouveau le script, celui-ci doit fonctionné.
Que se passe t il si vous modifier le script ? Celui-ci ne sera plus exécuté.
Sur la capture ci-dessous, j’ai modifié le script en ajoutant un bloc de commentaire.
Lors de l’exécution du script, une erreur s’affiche indiquant que le hachage du fichier n’est pas en adéquation avec le hachage du fichier en signature.
Vous savez maintenant comment signer un script PowerShell
Déploiement de la signature des scripts PowerShell en entreprise
Si vous souhaitez déployer la signature des scripts dans votre entreprise, il faut déployer le certificat par GPO et configurer les ordinateurs pour forcer la stratégie d’exécution des scripts PowerShell.
Pour déployer le certificat, vous pouvez suivre ce tutoriel : GPO : déployer un certificat, il faut placer le certificat dans le magasin Editeurs approuvés.
Pour forcer la signature des scripts, il faut configurer le paramètres Activer l’exécution des scripts avec la sélection : Autoriser uniquement signés qui se trouve dans Configuration ordinateur / Stratégies / Modèles d’administration / Composant Windows / Windows PowerShell.
Conclusion
Forcer la signature des scripts signées permet d’augmenter le niveau de sécurité en évitant que des scripts malveillant soient exécutés et aussi de protéger les scripts existants de toute altération.