Codesignatur für PowerShell Scriptdateien

Nachfolgend wird beschrieben, welche Optionen es für die Ausführung von PowerShell Skriptdateien gibt, und welche Möglichkeiten sich durch das Signieren dieser ergibt.

Zum Testen wurde ein simples PowerShell Skript erstellt und auf einem frisch installierten Windows 10 Client ausgeführt.

In der Standardeinstellung eines Windows 10 Client wird die Ausführung verhindert, da die Ausführungsrichtlinie für die Windows PowerShell auf "Restricted" gesetzt ist, d.h. es dürfen generell keine Scripts ausgeführt werden.

File C:\Users\rudi.INTRA\Desktop\HelloWorld.ps1 cannot be loaded because running scripts is disabled on this system.

Die PowerShell Ausführungsrichtlinie

Kennen Sie TameMyCerts? TameMyCerts ist ein Add-On für die Microsoft Zertifizierungsstelle (Active Directory Certificate Services). Es erweitert die Funktion der Zertifizierungsstelle und ermöglicht die Anwendung von Regelwerken, um die sichere Automatisierung von Zertifikat-Ausstellungen zu realisieren. TameMyCerts ist einzigartig im Microsoft-Ökosystem und steht unter einer freien Lizenz. Es kann über GitHub heruntergeladen und kostenlos verwendet werden.

Für die Windows PowerShell gibt es eine Ausführungsrichtlinie (engl. "Execution Policy"), die das Verhalten betreffend der Ausführung von Scripts festlegt. Diese unterscheidet sich je nach Betriebssystem-Variante:

Betriebssystem-VarianteStandardmäßig gesetzte Ausführungsrichtlinie
Windows ClientsRestricted
Windows ServerRemoteSigned

Die für das weitere Vorgehen relevanten Einstellungen kurz erklärt:

EinstellungBeschreibung
RestrictedEs dürfen keine PowerShell Scripts jedweder Art ausgeführt werden.
RemoteSignedLokal gespeicherte PowerShell Scripts dürfen ausgeführt werden, auch wenn sie nicht signiert sind. PowerShell Scripts, die sich auf Netzwerkspeicherorten befinden, dürfen nur ausgeführt werden, wenn sie signiert sind.
AllSignedPowerShell Scripts, dürfen nur ausgeführt werden, wenn sie signiert sind, egal ob sie lokal oder auf Netzwerkspeicherorten gespeichert sind.

Ausführungsrichtlinie manuell konfigurieren

Unser Ziel ist, dass nur signierte Scripts ausgeführt werden dürfen. Daher wird die Ausführungsrichtlinie mit folgendem Befehl auf "AllSigned" gesetzt.

Set-ExecutionPolicy AllSigned

Ausführungsrichtlinie über Gruppenrichtlinien konfigurieren

Der gleiche Effekt kann über Gruppenrichtlinien über folgende Einstellung erreicht werden: Computer Configuration" – "Administrative Templates" – "Windows Components" – "Windows PowerShell" – "Turn on Script Execution" – "Allow only signed scripts"

Das Script digital signieren

Die Ausführung des Scripts wird immer noch nicht gelingen, da es noch keine digitale Signatur besitzt.

File C:\Users\rudi.INTRA\Desktop\HelloWorld.ps1 cannot be loaded. The file C:\Users\rudi.INTRA\Desktop\HelloWorld.ps1 is not digitally signed. You cannot run this script on the current system.

Codesignaturzertifikat

Zum signieren einer Scriptdatei benötigt man ein Zertifikat mit der Extended Key Usage (EKU) für Codesignatur. Dieser Umstand wird für den weiteren Verlauf des Artikels als gegeben vorausgesetzt und nicht näher behandelt.

Die Signatur durchführen

Zum digitalen signieren von PowerShell Scripts kann der Set-AuthenticodeSignature Befehl verwendet werden.

Zunächst wird das Codesignaturzertifikat im lokalen Zertifikatspeicher identifiziert und in eine Variable geladen.

$SigningCertificate = (Get-ChildItem -Path Cert:\CurrentUser\My\26716942D0BDBB2D3825C2469C611C59AAE11DE6)

Optional aber sehr sinnvoll ist die Verwendung eines Zeitstempels (engl. Timestamp) nach RFC 3161. Ist die Codesignatur mit einem Zeitstempel versehen, wird die Signatur auch nach Ablauf des Signaturzertifikats weiterhin als gültig erkannt. In diesem Beispiel wird der öffentlich zugängliche Zeitstempelserver von Sectigo verwendet.

$TimeStampingAuthority = 'http://timestamp.sectigo.com'

Nun liegen alle Informationen vor, und das Script kann signiert werden.

Set-AuthenticodeSignature `
-FilePath .\HelloWorld.ps1 `
-Certificate $SigningCertificate `
-TimestampServer $TimeStampingAuthority

Sieht man sich nun die Eigenschaften der Scriptdatei an, erkennt man, dass sie nun über eine digitale Signatur verfügt.

Ein Blick in die Details der Sigatur offenbart außerdem, dass auch eine Gegensignatur (Zeitstempel) vorliegt.

Öffnet man das Script mit einem Texteditor, sieht man, dass die digitale Signatur an den Scriptcode in BASE64 kodierter Form angehängt wurde.

Eintragen in den Speicher für "Vertrauenswürdige Herausgeber" (oder auch nicht)

Man sollte nun meinen, dass man das Script endlich ausführen könnte. Nun wird jedoch angemerkt, dass dem Herausgeber nicht vertraut wird.

Do you want to run software from this untrusted publisher?
File C:\Users\rudi.INTRA\Desktop\HelloWorld.ps1 is published by CN=Rudi Ratlos, OU=Benutzerkonten, OU=ADCSLabor Benutzer, DC=intra, DC=adcslabor, DC=de and is not trusted on your system. Only run scripts from trusted  publishers.

Man hat nun die Option, die Ausführung nicht vorzunehmen, sie einmalig durchzuführen, sie immer durchzuführen, oder sie niemals durchzuführen.

Die Auswahl von "Always run" bewirkt, dass das Signaturzertifikat in den Speicher für "Vertrauenswürdige Herausgeber" im Zertifikatspeicher des Benutzters importiert wird.

Aushebeln des Schutzes

Dass die Ausführungsrichtlinie nur signierte Scripts akzeptiert ist allerdings in keinem Fall ein Garant dafür, dass keine unsignierten Scripts ausgeführt werden können. Es gibt vielfältige Möglichkeiten, die Ausführungsrichtline zu untergraben, und unsignierte Scripts dennoch auszuführen.

Hier ein einfaches Beispiel:

type .\HelloWorld.ps1 | powershell -

Weiterführende Links

Externe Quellen

Ein Gedanke zu „Codesignatur für PowerShell Scriptdateien“

Kommentare sind geschlossen.

de_DEDeutsch