Windows PowerShellHier signieren, bitte

Don Jones

Im Artikel vom Januar 2008 zu Windows PowerShell wurde hervorgehoben, wie wichtig das digitale Signieren Ihrer Windows PowerShell-Skripts ist. Außerdem wurden einige Szenarios beschrieben, in denen eine beliebige Ausführungsrichtlinie, außer AllSigned, zu erheblichen Sicherheitsrisiken in Ihrer Umgebung führen kann.

Ein Thema, das nicht ausführlich behandelt wurde, ist das Signieren Ihrer Skripts. Den Artikel vom Januar finden Sie unter technetmagazine.com/issues/2008/01/PowerShell. Erraten Sie, welches Thema in diesem Monat behandelt wird?

Mehr als nur eine Signatur

Das Wort „Signatur“ ist der richtige technische Begriff für das, was hier behandelt werden soll, obwohl das Wort selbst keine wirklich gute Beschreibung dafür ist, was dabei tatsächlich vor sich geht. Ein Skript zu signieren, heißt nicht, dass Sie es genehmigen oder autorisieren, wie das bei einem Vertrag oder einer Kreditkartenquittung der Fall ist. In der Welt der digitalen Sicherheit steht das Signieren für den Prozess, bei dem Ihre Identität an etwas angefügt wird, um sicherzustellen, dass der Status oder Zustand dieses „etwas“ in keiner Weise geändert wurde. All das beruht auf Kryptografie, und Kryptografie beginnt (zumindest in diesem Fall) mit einem Paar von Verschlüsselungsschlüsseln.

Diese Schlüssel werden als asymmetrische Schlüssel bezeichnet, weil sie sich voneinander unterscheiden. Das Paar besteht aus einem privaten Schlüssel, der nur Ihnen zugänglich ist, und einem öffentlichen Schlüssel, der allen zugänglich ist. Das ist etwas vereinfacht dargestellt, doch grundsätzlich kann etwas, was mit dem privaten Schlüssel verschlüsselt wurde, nur mit dem passenden öffentlichen Schlüssel entschlüsselt werden.

Das geschieht folgendermaßen. Der Einfachheit halber soll hier wieder etwas vereinfacht werden, um mit der Behandlung des Themas voranzukommen. Ich habe ein Windows PowerShell®-Skript, das ich signieren möchte, sowie ein Zertifikat, das meinen privaten Schlüssel enthält, den ich zum Signieren des Skripts verwenden will. Windows PowerShell selbst enthält ein Cmdlet (wird in Kürze besprochen), das mit dem Skript und dem Zertifikat das eigentliche Signieren durchführen kann. Dabei verschlüsselt Windows PowerShell das Skript mithilfe meines privaten Schlüssels. Die verschlüsselte Kopie wird als unverständlicher Text angezeigt, der unten im Skript als eine Reihe von Kommentaren hinzugefügt wird (siehe Abbildung 1). Meine Identität ist ebenfalls in die Kommentare eincodiert, aber nicht verschlüsselt. Die Identität selbst kann gelesen werden, ohne zur Kryptografie zu greifen.

Abbildung 1 Signaturblock, der unten in Ihrem Skript gespeichert ist

Abbildung 1** Signaturblock, der unten in Ihrem Skript gespeichert ist **(Klicken Sie zum Vergrößern auf das Bild)

Später, wenn Windows PowerShell die Signatur untersucht, decodiert es meine Identität und verwendet sie, um meinen öffentlichen Schlüssel zu erhalten. Da nur mein öffentlicher Schlüssel die restliche Signatur entschlüsseln kann, weiß Windows PowerShell: Wenn es die Signatur entschlüsseln kann, muss sie von mir stammen. Wenn jemand anderes signiert hätte, könnte mein öffentlicher Schlüssel die Signatur nicht entschlüsseln. Nachdem die Signatur entschlüsselt wurde, vergleicht Windows PowerShell das Skript mit der Kopie, die in die Signatur verschlüsselt wurde. Wenn sie übereinstimmen, wird die Signatur als unversehrt angesehen. Wenn die beiden Skripts voneinander abweichen, ist die Signatur nicht in Ordnung und wird als ungültig angesehen.

So schützt eine Signatur ein Klartextskript und verhindert, dass unbemerkt Änderungen daran vorgenommen werden. Denken Sie daran, dass das Skript selbst zwar leicht geändert werden kann, dass die Signatur aber ohne meinen privaten Schlüssel (den nur ich besitze) nicht so geändert werden kann, dass sie mit dem veränderten Skript übereinstimmt.

Dies ist sicherlich eine Vereinfachung des zugrunde liegenden technischen Prozesses. In der Realität können Signaturen mehr Informationen enthalten und enthalten sie auch, wie z. B. eine Kopie meines öffentlichen Schlüssels, Informationen zur Zertifizierungsstelle (certificate authority, CA), von der die Schlüssel veröffentlicht wurden, und so weiter. Die Beschreibung hier skizziert aber auf jeden Fall die wichtigen Teile des Prozesses und hebt die Tatsache hervor, dass eine Signatur Ihr Skript tatsächlich vor einer nicht autorisierten Änderung schützt.

Ein entscheidender Sicherheitsfaktor ist der absolute Schutz Ihres privaten Schlüssels. Er darf nicht in falsche Hände geraten. Wenn Sie Ihren Schlüssel in Windows installieren, sollten Sie ihn sofort mit einem Kennwortschutz versehen, damit Ihr Schlüssel nicht ohne Ihr Wissen von einem schädlichen Prozess verwendet werden kann. Smartcards bieten eine noch bessere Sicherheit, da sie Ihren privaten Schlüssel enthalten. Bei einer Smartcard bleibt Ihr privater Schlüssel immer auf der Karte. Stattdessen werden die Daten, die Sie verschlüsseln möchten, von der Kartenleserhardware an die Karte übermittelt, und die Schaltkreise der Karte selbst führen die Verschlüsselung durch und senden das Ergebnis zurück.

Erhalten eines Zertifikats

Cmdlet des Monats: Export-CSV

Die Teilnehmer in den Foren von PowerShellCommunity.org fragen oft, ob Windows PowerShell nach Microsoft Excel® exportieren kann. Selbstverständlich kann es das. Dies geschieht mithilfe des Export-CSV-Cmdlet, da Excel standardmäßig CSV-Dateien öffnen, bearbeiten und speichern kann. Wenn Sie zum Beispiel eine Liste von Diensten exportieren möchten, führen Sie einfach nur „Get-Service“ | „Export-CSV MyServices.csv“ aus. Eigentlich können Sie Export-CSV ans Ende einer beliebigen Pipeline setzen, und alle Objekte in dieser Pipeline landen in der angegebenen CSV-Datei. Standardmäßig fügt Export-CSV oben in der Datei eine Headerzeile hinzu, die sie dazu verwendet, den Typ des Objekts anzugeben, das exportiert wurde. Diese Zeile wird mit einem Kommentar versehen, um zu verhindern, dass Excel die Datei öffnet. Wenn Sie diese Typinformationen nicht exportieren möchten, können Sie einfach den Parameter „-notype“ der Export-CSV hinzufügen. Außerdem können Sie den Parameter „-force“ hinzufügen, um zu erzwingen, dass eine vorhandene CSV-Datei, die den gleichen Namen hat, überschrieben wird, ohne dass um eine Bestätigung gebeten wird (standardmäßig wird darum gebeten), oder Sie können den Parameter „-noClobber“ hinzufügen, um zu verhindern, dass eine vorhandene Datei überschrieben wird.

Zum Signieren von Skripts benötigen Sie eine bestimmte Art von Zertifikat, ein Authenticode-Codesignaturzertifikat der Klasse III, das Sie auf dreierlei Weise erhalten können. Die erste Möglichkeit besteht darin, die interne Public Key-Infrastruktur (PKI) Ihrer Organisation zu verwenden, falls vorhanden. In einer gut implementierten PKI wird die zugehörige Stammzertifizierungsstelle von allen Computern in Ihrer Organisation als vertrauenswürdig eingestuft. Das ist unerlässlich, damit die Zertifikate, die von der Zertifizierungsstelle ausgegeben werden, in der Organisation eingesetzt werden können.

Windows Server® wird seit Windows® 2000 mit seiner eigenen Zertifikatserversoftware geliefert, und Sie können diese Software verwenden, um Ihre eigene PKI zu erstellen. Eine vollständige PKI-Implementierung erfordert viel Planung, doch wenn Sie eine PKI nur für das Ausstellen von Codesignaturzertifikaten benötigen, erfordert dies nicht endlos viel Arbeit. Sie können einfach Gruppenrichtlinien verwenden, um das Stammzertifikat Ihrer CA mittels Push auf Ihre Computer zu übertragen, damit sie ihm vertrauen.

Die zweite Möglichkeit besteht darin, eine kommerzielle CA zu verwenden. Die Verwendung einer kommerziellen CA, die zu den führenden Zertifizierungsstellen gehört, bietet den Vorteil, dass die Computer in Ihrer Organisation wahrscheinlich bereits so konfiguriert sind, dass sie den Zertifikaten dieser CA vertrauen. (Beachten Sie, dass Windows XP viele CAs standardmäßig als vertrauenswürdig einstuft, während dies bei Windows Vista® standardmäßig bei einer weit geringeren Anzahl von CAs der Fall ist.) Eine beliebte kommerzielle Zertifizierungsstelle ist VeriSign (verisign.com). Es gibt andere, die ebenfalls in Erwägung gezogen werden sollten, wie z. B. CyberTrust (cybertrust.com) und Thawte (thawte.com).

Die dritte Möglichkeit, wie Sie ein Codesignaturzertifikat erhalten können, besteht im Erstellen eines eigenen selbstsignierten Zertifikats mithilfe eines Tools wie Makecert.exe. Es wird mit dem Windows Plattform-SDK geliefert, wird in einigen Editionen von Microsoft® Office installiert und kann an vielen anderen Orten gefunden werden. Der Vorteil eines selbstsignierten Zertifikats besteht darin, dass es kostenlos ist und keine Infrastruktur erfordert. Der Nachteil besteht jedoch darin, dass es wirklich nur auf Ihrem Computer eingesetzt werden kann. Wenn Sie es aber nur zur Skriptausführung auf Ihrem Computer benötigen, um die Codesignierung zu testen oder allgemein damit zu experimentieren, ist Makecert.exe eine hervorragende Option. Die Dokumentation zu diesem Tool finden Sie unter go.microsoft.com/fwlink/?LinkId=108538. Denken Sie aber daran, dass im Laufe der Jahre viele Versionen dieses Tools herausgegeben wurden. Es ist also möglich, dass Ihr Computer eine ältere Version ausführt, die nicht so funktioniert, wie in der Dokumentation beschrieben.

Mit Makecert.exe können Sie dann ein selbstsigniertes Zertifikat erstellen, indem Sie etwa Folgendes in der Windows PowerShell-Befehlszeile ausführen (ich hoffe, dass niemand, der diesen Artikel liest, womöglich cmd.exe verwendet):

makecert -n "CN=MyRoot" -a sha1 –eku
1.3.6.1.5.5.7.3.3 -r -sv root.pvk root.cer 
–ss Root -sr localMachine

Führen Sie anschließend den folgenden Befehl aus:

makecert -pe -n "CN=MyCertificate" -ss MY 
–a sh1 -eku 1.3.6.1.5.5.7.3.3 -iv root.pvk 
–c root.cer

Makecert.exe fordert Sie dann zur Kennworteingabe auf, um den Schlüssel zu schützen, und erstellt dann das Zertifikat. Sie können die Installation durch Ausführen dieses Codes in Windows PowerShell überprüfen:

gci cert:\CurrentUser\My -codesigning

Mit folgendem Befehl wird eine Liste aller Elemente im Laufwerk CERT: angezeigt (das ist Ihr Windows-Zertifikatspeicher), bei denen es sich um Codesignaturzertifikate handelt. Übrigens ist all dies auch in Windows PowerShell selbst dokumentiert. Sie finden diese Dokumentation, indem Sie einfach „help About_Signing" ausführen und einige Seiten nach unten blättern.

Signieren von Skripts

Sie verfügen jetzt über ein Zertifikat und ein Skript (zum Testen können Sie schnell ein einfaches Skript schreiben, wenn nötig), und sind bereit, das Skript zu signieren. Dies ist mit Windows PowerShell unglaublich einfach. Sie müssen einfach nur Folgendes eingeben:

$cert = @(gci cert:\currentuser\my
-codesigning)[0]
Set-AuthenticodeSignature myscript.ps1 $cert

Der erste Teil ruft das erste installierte Codesignaturzertifikat ab. (Wenn mehrere Zertifikate installiert wurden und Sie nicht das erste verwenden möchten, ändern Sie die „0“ einfach in die entsprechende Zahl). Der zweite Teil signiert die Datei (selbstverständlich müssen Sie den Dateinamen entsprechend ändern). Es ist wirklich so einfach. Aber meiner Meinung nach ist der Name des Set-AuthenticodeSignature-Cmdlet etwas zu lang. Deshalb habe ich ein Alias namens „Sign“ erstellt. Jetzt muss ich nur Folgendes ausführen:

Sign myscript.ps1 $cert

Wenn Sie dieses Skript jetzt öffnen, sehen Sie den unten eingefügten Signaturblock. Versuchen Sie, das Skript mit der Ausführungsrichtlinieneinstellung „AllSigned“ (Set-ExecutionPolicy AllSigned) auszuführen. Das müsste funktionieren. Jetzt werden Sie das Skript vermutlich ändern und speichern wollen. Stellen Sie dabei aber sicher, dass Sie es nicht erneut signieren. Windows PowerShell verweigert jetzt einfach die Ausführung der geänderten Version, weil die Signatur nicht mehr in Ordnung ist.

Lohnt sich der Aufwand?

Ist der ganze Aufwand wirklich gerechtfertigt? Ist es zuviel erwartet, ein Skript für einige administrative Aufgaben erstellen zu können, ohne 300 € für ein Zertifikat auszugeben oder ein ganz neues Infrastrukturelement implementieren zu müssen? Da ich selbst Administrator bin, verstehe ich Ihre Bedenken. Doch die Antwort ist schlicht und einfach ja. Es ist ganz sicher die Anstrengung wert.

Tatsache ist, dass Sicherheit immer bestimmte Umstände erfordert. Antivirussoftware kann große Umstände bereiten, doch Sie werden nicht darauf verzichten. Firewallsoftware bereitet ganz eindeutig Umstände, doch wie Sie wissen, ist es nicht sicher, ohne eine Firewall zu arbeiten. Auch die Windows Vista-Benutzerkontensteuerung kann Umstände bereiten, doch sie macht Ihren Computer sicherer. Ist diese verbesserte Sicherheit nicht das, wonach wir alle streben?

Windows PowerShell ist ein leistungsfähiges Tool, und wie bei jedem anderen Tool ist immer die Möglichkeit vorhanden, dass es durch einen böswilligen Benutzer in ein Sicherheitsrisiko verwandelt wird. Deshalb ist es für Sie wichtig, die böswilligen Benutzer abzufangen.

Die Codesignatur ist dabei der beste Schritt, und sie erfordert nicht viel Aufwand. Ich verwende zum Beispiel einen grafischen Skripteditor, der meine Skripts bei jedem Klick auf „Speichern“ automatisch signiert, sodass die Codesignatur für mich eine recht transparente Angelegenheit ist.

Sie können das Ganze selbst ohne solch einen Editor noch transparenter gestalten. Zum Beispiel können Sie ein Windows PowerShell-Profil für sich erstellen (erstellen Sie die Datei „Microsoft.PowerShell_profile.ps1“ in einem Ordner namens „WindowsPowerShell“, der sich in Ihrem Dokumentenordner befindet), und fügen Sie diese Funktion hinzu:

function sign ($filename) {
  $cert = @(gci cert:\currentuser\my 
-codesigning)[0]
Set-AuthenticodeSignature $filename $cert
}

Jetzt können Sie Ihr Skript signieren, indem Sie einfach Folgendes eingeben:

Sign c:\scripts\myscript.ps1

Selbstverständlich muss das Profilskript das erste sein, was Sie signieren. Der Gedanke dabei ist, die Skriptsignierung so bequem wie möglich zu gestalten, sodass sie keinen großen Aufwand darstellt.

Eine Einserver-PKI bereitzustellen, nur um ein Codesignaturzertifikat auszustellen, ist nicht viel Arbeit. (Bedenken Sie jedoch, dass Sie Ihre PKI sorgfältig untersuchen und planen müssen. Dazu gehört auch der Schutz der Stammzertifizierungsstelle und das Bereitstellen einer Notfallwiederherstellung, vor allem wenn noch andere Verwendungszwecke vorgesehen sind.) Ihnen steht immer Makecert.exe zur Verfügung, wenn Sie der einzige sind, der in Ihrer Umgebung Skripts ausführen muss. Beachten Sie, dass das Windows PowerShell-Hilfethema zum Signieren auch Informationen zum Sichern des von Makecert.exe erstellten Zertifikats enthält.

Don Jones ist der Autor von Windows PowerShell: TFM and VBScript, WMI, and ADSI Unleashed. Sie können ihn über die Website PowerShellCommunity.org kontaktieren.

© 2008 Microsoft Corporation und CMP Media, LLC. Alle Rechte vorbehalten. Die nicht genehmigte teilweise oder vollständige Vervielfältigung ist nicht zulässig.