Signer les scripts PowerShell

I ❤️ PowerShell. C’est un outil vraiment utile pour automatiser ces tâches que vous faites plusieurs fois. Mais il peut aussi être un trou de sécurité béant si vous le laissez faire.

PowerShell vous permet d’administrer presque tout sur votre machine, il y a donc beaucoup de dégâts qui pourraient être faits par quelqu’un capable d’exécuter des scripts malveillants dans vos environnements.

Auparavant confiné au seul Windows, depuis la version 6 et maintenant avec la sortie de PowerShell 7.0, il peut également être déployé sur Linux et MacOS. Cependant, cet article parle des politiques d’exécution qui ne peuvent pas être modifiées dans les environnements non Windows et qui n’apporteront donc aucun avantage aux utilisateurs de Linux/MacOS (désolé).

Politiques d’exécution

Une façon de restreindre la possibilité d’exécuter des scripts dans vos environnements Windows est d’utiliser les politiques d’exécution de PowerShell. Le tldr est qu’elles peuvent être utilisées pour restreindre les scripts qui s’exécuteront dans l’environnement. Les options disponibles, de la moins sûre à la plus sûre, sont :

Bypass

Rien n’est bloqué.

Unrestricted (s’applique toujours sur les machines non Windows)

Même chose que ByPass mais invite l’utilisateur avant d’exécuter des scripts depuis Internet.

RemoteSigned (par défaut pour les serveurs Windows)

Les scripts qui ont été téléchargés depuis Internet ne peuvent être exécutés que s’ils sont signés. Les scripts écrits sur la machine peuvent être exécutés

AllSigned

Tous les scripts doivent être signés avant d’être exécutés

Restricted (par défaut pour les clients Windows)

Empêche l’exécution des scripts. Peut seulement exécuter des commandes individuelles.

Exécution de scripts

Donc vous voulez exécuter vos propres scripts PowerShell sur votre serveur. Mais vous obtenez un PSSecurityException comme le suivant.

PS C:\Users\Administrator\Downloads> .\wibble.ps1.\wibble.ps1 : File .\wibble.ps1 cannot be loaded. The file.\wibble.ps1 is not digitally signed. You cannot run this script on the current system.For more information about running scripts and setting execution policy, see about_Execution_Policies athttp://go.microsoft.com/fwlink/?LinkID=135170.At line:1 char:1+ .\wibble.ps1+ ~~~~~~~~~~~~ + CategoryInfo : SecurityError: (:) , PSSecurityException + FullyQualifiedErrorId : UnauthorizedAccess
Entrer en mode plein écran Quitter le mode plein écran

Une façon de résoudre ce problème est de changer la politique d’exécution en utilisant la commande Set-ExecutionPolicy et de réduire la sécurité de la machine. C’est une mauvaise idée en général.

Personnellement, je n’utiliserais jamais quelque chose de moins sécurisé que RemoteSigned sur un serveur, mais AllSigned idéalement.

Qu’est-ce qu’une signature de script ?

Presumablement, vous voulez maintenir la sécurité de la machine et ne pas ouvrir une vulnérabilité, donc l’option qui vous reste est de signer vos scripts.

Signer un script signifie que quelqu’un ayant accès à la clé privée d’un certificat de signature de code a ajouté un bloc de signature à la fin du fichier de script.

function Get-Wibble { return "Wibble"}# SIG # Begin signature block# vpnIUpm2XxLRhU1no0iuA62xKxYzR6m95z9Ax21ppeTC9NoRd8ocoSGr1zAd# qlMOlz4lZoVWR4ZmtdCgzde1dVxzv4jjHb6ziDiY2o05UXswD2bl6XaOrUpd# Li0Qjg3d3y2r1nrpO8hos906bgXQswysvouegUJcpt8ftmqBKfEYNeBgnBFm# SIG # End signature block
Entrer en mode plein écran Sortir en mode plein écran

(Exemple seulement. Le bloc de signature est généralement beaucoup plus long)

Le bloc de signature contiendra un hachage du script qui a été crypté en utilisant la clé privée. Lors de la tentative d’exécution du script, celui-ci est décrypté à l’aide de la clé publique et comparé au hachage réel. S’il correspond, alors nous pouvons confirmer que le script n’a pas été altéré car le hachage changerait dès que cela se produirait.

Certificats autosignés

Si vos scripts ne vont être exécutés que par des machines dans votre organisation, alors vous serez très probablement en mesure d’autosigner les certificats. L’alternative est de dépenser $$$ et d’acheter un certificat de signature de code chaque année.

L’auto-signature signifie que vous allez générer le certificat vous-même et signer les scripts en utilisant cela.

Comment créer un certificat d’auto-signature

PowerShell a la commande New-SelfSignedCertificate très utile pour produire des certificats auto-signés. Nous pouvons ensuite les exporter et les placer dans différents magasins.

Par défaut, la commande crée un certificat qui expire après 1 an. Vous pouvez changer cela en utilisant le paramètre -NotAfter et en lui fournissant la date à laquelle vous souhaitez que le certificat expire.

Pour créer un certificat, lancez une session PowerShell et exécutez ce qui suit

$CertificateName = Read-Host "Input your certificate name"$OutputPFXPath = "$CertificateName.pfx"$OutputCERPath = "$CertificateName.cer"$Password = Get-Credential -UserName Certificate -Message "Enter a secure password:"$certificate = New-SelfSignedCertificate -subject $CertificateName -Type CodeSigning -CertStoreLocation "cert:\CurrentUser\My"$pfxCertificate = Export-PfxCertificate $certificate -FilePath $OutputPFXPath -password $Password.passwordExport-Certificate -Cert $certificate -FilePath $OutputCERPathImport-PfxCertificate $pfxCertificate -CertStoreLocation cert:\CurrentUser\Root -Password $password.passwordWrite-Output "Private Certificate '$CertificateName' exported to $OutputPFXPath"Write-Output "Public Certificate '$CertificateName' exported to $OutputCERPath"
Entrer dans le mode plein écran Quitter le mode plein écran

Cela créera le certificat et l’exportera vers deux fichiers séparés avec les extensions .pfx et .cer.

PFX

Le certificat PFX est celui qui devra être installé sur les machines qui feront la signature. Dans notre cas, il s’agit de chacune de nos machines de développeurs.

Il doit être installé dans le magasin cert:\CurrentUser\Root, également connu sous le nom de magasin « Autorités de certification racine de confiance ».

Ce fichier doit être conservé dans un endroit sûr. Le mot de passe doit ensuite être sécurisé séparément (utilisez un gestionnaire de mots de passe). Si un mauvais acteur met la main sur les deux, alors il peut signer ses scripts malveillants comme s’il était vous.

CER

Le fichier de certificat CER est ce que vous allez devoir installer sur les machines qui vont exécuter les scripts. Cela ne nécessitera pas de mot de passe pour l’installation mais ne pourra pas être utilisé pour signer les scripts. Il ne contient que la clé publique utilisée pour décrypter la signature.

Parce qu’il ne contient pas la clé privée, ce certificat peut être distribué librement à tous les environnements qui exécuteront les scripts.

Il devra être installé dans deux magasins de certificats sur les machines qui exécuteront les scripts ; Les magasins cert:\LocalMachine\Root et cert:\LocalMachine\TrustedPublisher.

Signer un script

La fonction Set-AuthenticodeSignature est fournie pour signer les scripts. Nous devons passer le chemin vers le script et le certificat du magasin. Nous avons écrit une fonction wrapper qui peut signer les scripts.

function Set-ScriptSignatures { param ( $pathToScripts = "." ) $certificateName = "PowerShell Signing Certificate" $scripts = Get-ChildItem -Path "$pathToScripts\*" -Include *.ps1, *.psm1 -Recurse $certificate = @(Get-ChildItem cert:\CurrentUser\My -codesign | Where-Object { $_.issuer -like "*$certificateName*" } ) foreach ($script in $scripts) { Write-Host "Signing $script" Set-AuthenticodeSignature $script -Certificate $certificate }}
Entrer en mode plein écran Quitter le mode plein écran

La variable $certificateName doit contenir le nom utilisé lors de la création du certificat.

Vous pouvez utiliser la fonction en fournissant un chemin vers le répertoire qui contient les scripts et elle les parcourra en boucle en les signant tous.

Une fois que vous avez installé les scripts sur la machine cible, vous devriez maintenant être en mesure d’exécuter les scripts sans problème.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.