Dans cet article, nous verrons un moyen simple et efficace de stocker un mot de passe sensible de manière chiffrée afin de s'en servir dans un script sans pour autant l'enregistrer de manière lisible.
Certaines fois, des mots de passe tels que celui de l'administrateur du domaine ou d'un compte précis sont nécessaires pour l'utilisation d'un script. Autant Linux permet d’empêcher la lecture de certains documents n'ayant pas les droits nécessaires, autant Windows est bien plus laxiste concernant cela. Le moindre fichier contenant le mot de passe peut être lu, et compromettre de manière extrêmement grave l'intégralité du système informatique, ainsi que la pérennité des données du domaine.
Pour cela, nous allons d'abord expliquer ce qu'il se passe lorsqu'une demande d'identifiants est faite depuis Powershell, à l'aide de la commande Get-Credential. Lorsque cette commande est lancée, nous obtenons une fenêtre, sécurisée, demandant un identifiant et un mot de passe. Depuis la commande Get-Credential, nous pouvons préciser d'abord un Login, mais aucunement un mot de passe.
Le mot de passe, comme vous le voyez, est invisible, bien évidemment pour des raisons de sécurité. Si nous enregistrons dans une variable le résultat de la commande, nous obtenons des informations intéressantes.
Nous voyons par exemple, que le type de notre Get-Credential est un [System.Management.Automation.PSCredential], un type crée expressément pour contenir de manière sécurisée des identifiants... Mais nous voyons également une propriété à cet objet nommée Password! Plus qu'à s'en servir, et récupérer le mot de passe, hm?
Et bien non! La commande, comme vous le voyez, renvoie non pas le mot de passe, mais le type de l'objet, toujours pour des raisons de sécurité.
En fait Powershell, étant bien dressé, sait qu'on lui donne des clés importantes -à savoir un mot de passe- et qu'il ne doit pas les laisser traîner. Alors avant même de les stocker en mémoire, il les crypte, il les modifie, et les rends illisibles pour n'importe qui d'autre!
Mais comment faire pour stocker des identifiants de manière à les présenter à un script sans avoir à les entrer de manière manuelle?
Voici la première procédure, dangereuse QUE JE DÉCONSEILLE FORTEMENT :
Il suffit de créer un objet du même type que celui obtenu lors d'un Get-Credential, et y passer deux arguments (login et password). Le mot de passe étant crypté, nous devons le transformer au préalable à l'aide de la commande Convertto-SecureString
$password = "M0T2pass!" | Convertto-SecureString -AsPlainText -Force
En utilisant "AsPlainText" nous précisons que cela est un mot de passe non crypté, et que Powershell doit le considérer comme du texte. Et comme Powershell n'est pas content (ET MOI NON PLUS è_é ) de votre façon de faire, il faut le forcer à accepter cette façon de travailler non sécurisée à l'aide de "Force".
$login = "Domaine\Toto"
$password = "M0T2pass!" | Convertto-SecureString -AsPlainText -Force
$credentials = New-Object System.Management.Automation.Pscredential -Argumentlist $login,$password
Ainsi, vous avez une variable $credentials qui contient le "package" nécessaire à présenter à certaines commandes le nécessitant... et dans le script votre mot de passe en CLAIR.
Deuxième procédure, sécurisée, QUE JE CONSEILLE :
Avant de lancer notre script, il faut ouvrir une fenêtre powershell pour créer la version cryptée de notre mot de passe administrateur. Nous allons donc saisir cette fois (et cette fois seulement) le mot de passe administrateur en clair.
"MOT2pass!" | Convertto-SecureString -AsPlainText -Force | ConvertFrom-SecureString | Out-file C:\Temp\Cred.txt
Ceci fait, rendons nous dans notre fichier C:\Temp\Cred.txt pour en voir le contenu, et la, à notre grande surprise...
Plus rien n'y est lisible! Powershell aura entièrement chiffré la chaîne de caractères "MOT2pass!" pour la transformer en ceci. Il la transforme en chaîne sécurisée chiffrée d'abord (commande Convertto-Securestring) puis la transforme en chaîne de caractères (ConvertFrom-SecureString), à l'aide d'une clé qui est propre à chaque ordinateur (Ce qui rend l'utilisation de ce fichier sur d'autres postes impossible), avant de l'envoyer vers le fichier texte.
Ainsi, depuis un script, il suffit de faire :
$password = Get-Content C:\Temp\Cred.txt | Convertto-SecureString
Pour obtenir un objet de type System.Security.SecureString permettant d’être envoyée vers une demande de credentials comme dans la première manière de faire :
$login = "Domaine\Toto"
$credentials = New-Object System.Management.Automation.Pscredential -Argumentlist $login,$password
Ainsi, notre mot de passe n'est lisible nul part, criffré et sécurisé.
Comme je l'ai dit, la clé de chiffrement est propre à chaque pc, et le contenu du fichier ne sera lisible que par l'ordinateur qui l'a crypté. Pour rendre tout cela lisible, il suffit d'abord de générer une clé de cryptage lors de la génération du mot de passe. Cette clé peut être de 16, 24 ou 32 bits. Voici un exemple d'utilisation :
$Key = [byte]35,31,32,45,55,11,09,08,11,34,67,99,12,20,09,98
"MOT2pass!" | Convertto-SecureString -AsPlainText -Force | ConvertFrom-SecureString -key $key| Out-file C:\Temp\Cred.txt
Et à l'identique, la conversion pour l'import lors d'un script (bien entendu, la clé $KEY devra être créée comme précedemment dans ce script) :
$password = Get-Content C:\Temp\Cred.txt | Convertto-SecureString -Key $key