Tags: PowerShell, Zertifikate, Sicherheit
Um die Authentizität von Scripts zu gewährleisten, kann PowerShell sie mit einer Signatur versehen. Eine solche benötigen sie, wenn man Richtlinien vorgeben möchte, die nur das Ausführen vertrauenswürdiger Scripts erlauben. Das erforderliche Zertifikat kann man bei intern entwickelten Scripts über eine AD-basierte CA ausstellen.
Durch das Signieren eines Scripts bestätigt sein Entwickler, dass es von ihm stammt und stellt so auch sicher, dass es nicht nachträglich verändert wurde. Anwender, die aus Sicherheitsgründen keinen PowerShell-Code aus unbekannter Quelle ausführen möchten, können so die zulässigen Scripts auf bestimmte Hersteller einschränken.
Einschränkung über Execution Policy, CLM, AppLocker
Ein Mechanismus, um unsignierte Scripts abzuweisen, ist die Execution Policy. Setzt man diese auf AllSigned, dann müssen sowohl lokale als auch aus dem Internet heruntergeladene Scripts mit einer Signatur versehen sein. Eine echte Sicherheitsfunktion ist das aber nicht, weil User zum Beispiel den Inhalt des Scripts an den Prompt oder in die ISE kopieren und dort starten können.
Mehr Schutz bietet hier der Constrained Language Mode (CLM), bei dem nur signierte Scripts den vollen Funktionsumfang von PowerShell nutzen können. Unsignierten dagegen bleibt der Zugriff auf Features verwehrt, die besonderes Schadenpotenzial haben.
Die stärkste Wirkung beim Blockieren nicht vertrauenswürdiger Scripts haben schließlich Lösungen für das Whitelisting von Anwendungen. Mit AppLocker kann man etwa das Ausführen auf solche Scripts beschränken, die von bestimmten Herstellern stammen.
Zertifikatsvorlage freigeben
Im ersten Schritt muss man dafür sorgen, dass die Zertifikatsvorlage für das Code Signing den Benutzern zugänglich ist, die damit ein Zertifikat für ihre Scripts anfordern wollen. Dazu öffnet man das MMC-Tool Zertifizierungsstelle (certsrv.msc) und verbindet sich mit der internen CA.
Aus dem Kontextmenü von Zertifikatvorlagen führt man den Befehl Verwalten aus. Dies öffnet das Snap-in für Zertifikatvorlagen.
Dort wählt man Eigenschaften aus dem Kontextmenü von Codesignatur und wechselt dort zur Registerkarte Sicherheit. Hier fügt man die Gruppe hinzu, welche Zertifikate auf Basis dieses Templates anfordern soll und verleiht ihr die Rechte Lesen und Registrieren.
Nach dem Bestätigen dieses Dialogs kehrt man wieder zu certsrv.msc zurück und führt aus dem Kontextmenü von Zertifikatvorlagen den Befehl Neu => Auszustellende Zertifikatvorlage aus. Im nachfolgenden Dialog markiert man Codesignatur und bestätigt mit Ok.
Zertifikat zur Code-Signierung anfordern
Nun kann der Entwickler von Scripts zur Tat schreiten und auf Grundlage dieses Templates ein Zertifikat anfordern. Dazu startet er mmc.exe und fügt unter Datei das Snapin Zertifikate hinzu. Bei Anwendern, die keine erhöhten Rechte besitzen, öffnet das Tool automatisch im Kontext von Aktueller Benutzer.
Hier klickt man mit der rechten Maustaste auf Meine Zertifikate und führt dann Alle Aufgaben => Neues Zertifikat anfordern aus. Dies startet einen Wizard, wo man im ersten Dialog die Zertifikatregistrierungsrichtlinie auswählt (in der Regel die vorgegebene für das AD).
Anschließend aktiviert man die Vorlage Codesignatur, öffnet dort die Details und klickt auf Eigenschaften. Im daraufhin angezeigten Dialog wechselt man zum Reiter Privater Schlüssel und hakt die Option Privaten Schlüssel exportierbar machen an.
Nach dem Bestätigen dieses Dialogs klickt man, zurück im Hauptfenster, auf Registrieren. Nun erhält man das Ergebnis der Operation angezeigt und schließt den Vorgang mit Fertig stellen ab.
Script signieren
Das Zertifikat befindet sich nun im lokalen Store des Benutzers unter Eigene Zertifikate => Zertifikate. Dieses kann man in PowerShell über den entsprechenden Provider anzeigen:
Get-ChildItem Cert:\CurrentUser\My -CodeSigningCert
Diese Tatsache macht man sich zunutze, um so das Zertifikat beim Signieren mit Set-AuthenticodeSignature anzugeben:
Set-AuthenticodeSignature myScript.ps1 (dir Cert:\CurrentUser\My -CodeSigningCert)
PowerShell fügt die Signatur im Base64-Format einfach am Ende des Scripts als einen eigenen Block ein.
Startet man das Script nach dem Signieren zum ersten Mal auf einem Rechner, dann muss der Benutzer das Ausführen bestätigen, weil der Herausgeber nicht als vertrauenswürdig gilt. Wählt man hier die Option Immer ausführen, dann erscheint dieser Prompt in Zukunft nicht mehr.
Signatur mit Zeitstempel versehen
Es liegt in der Natur der Sache, dass PowerShell die Ausführung des Scripts verweigert, wenn man es auch nur geringfügig ändert. Abhilfe schafft dann nur das erneute Signieren.
Ähnliches gilt, wenn das Zertifikat abläuft. Auch dann lässt sich das Script nicht mehr nutzen. Dem kann man aber vorbeugen, indem man beim Signieren einen Timestamp-Server einbezieht.
Dieses Beispiel greift auf den kostenlosen Dienst von Globalsign zurück:
Set-AuthenticodeSignature myScript.ps1 (gci Cert:\CurrentUser\My -CodeSigningCert)`
-TimestampServer http://timestamp.globalsign.com/scripts/timstamp.dll `
-HashAlgorithm "SHA256"
Damit wird belegt, dass das Zertifikat zum Zeitpunkt des Signierens gültig war.
Täglich Know-how für IT-Pros mit unserem Newsletter
Ähnliche Beiträge
- Ausführungsrichtlinien (Execution Policy) für PowerShell-Scripts über GPO setzen
- AD-Zertifikatsdienste (AD CS) von SHA-1 auf SHA-2 migrieren: Gründe und Hindernisse
- Lets Encrypt-Zertifikat mit ACME2-Client ausstellen, installieren, automatisch erneuern
- Alle Windows-Server auf ablaufende Zertifikate prüfen mit PowerShell
- PowerShell als Hacking-Tool: Missbrauch von Scripts verhindern
Weitere Links