PowerShell-Scripts signieren mit Zertifikaten einer AD-Zertifizierungsstelle

    Zertifikate mit PowerShell verwaltenUm die Authen­tizität von Scripts zu gewähr­leisten, kann sie PowerShell mit einer Signatur versehen. Dies ist eine Voraus­setzung dafür, um stren­gere Richt­linien für die Aus­führung von PowerShell-Code vorzu­geben. Das erfor­derliche Zerti­fikat kann man bei intern ent­wickel­ten Scripts über eine AD-basierte CA aus­stellen.

    Durch das Signieren eines Scripts bestätigt sein Entwickler, dass es von ihm stammt und stellt so auch sicher, dass es nicht nach­träglich verändert wurde. Anwender, die aus Sicherheits­gründen keinen PowerShell-Code aus unbe­kannter 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 herunter­geladene Scripts mit einer Signatur versehen sein. Eine echte Sicherheits­funktion 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 Funktions­umfang von PowerShell nutzen können. Unsignierten dagegen bleibt der Zugriff auf Features verwehrt, die besonderes Schaden­potenzial haben.

    Die stärkste Wirkung beim Blockieren nicht vertrauens­wü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 Zertifikats­vorlage 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 Zertifizierungs­stelle (certsrv.msc) und verbindet sich mit der internen CA.

    Zertifikatsvorlagen aus dem MMC-Tool Zertifizierungs­stelle (certsrv.msc) öffnen

    Aus dem Kontextmenü von Zertifikat­vorlagen führt man den Befehl Verwalten aus. Dies öffnet das Snapin für Zertifikat­vorlagen.

    Rechte auf das Template für Codesignatur vergeben

    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 ausstellen soll und verleiht ihr die Rechte Lesen und Registrieren.

    Dialog zum Aktivieren von Zertifikatvorlagen öffnen

    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 nach­folgenden Dialog markiert man Codesignatur und bestätigt mit Ok.

    Die Zertifikatvorlage für Code-Signierung aktivieren

    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.

    Neues Zertifikat zur Signierung von Code anfordern

    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 Zertifikat­registrierungs­richtlinie 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 angezeigt Dialog wechseln man zum Reiter Privater Schlüssel und hakt die Option Privaten Schlüssel exportierbar machen an.

    Vorlage Codesignatur auswählen und privaten Schlüssel exportierbar machen

    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.

    Erfolgreicher Abschluss der Zertifikatsanforderung

    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-Authenticode­Signature anzugeben:

    Set-AuthenticodeSignature myScript.ps1 (dir Cert:\CurrentUser\My -CodeSigningCert)

    Script signieren mit dem Cmdlet Set-AuthenticodeSignature

    PowerShell fügt die Signatur im Base64-Format einfach am Ende des Scripts als einen eigenen Block ein.

    Das erste Ausführen eines Scripts, das von einem unbekannten Herausgeber signiert wurde, muss der User bestätigen.

    Startet man das Script nach dem Signieren zum ersten Mal auf einem Rechner, dann muss der Benutzer das Ausführen bestätigen, weil der Heraus­geber nicht als vertrauens­wü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 aber man vorbeugen, indem man beim Signieren einen Timestamp-Server einbezieht.

    Signatur mit einem Zeitstempel versehen

    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.

    Keine Kommentare