Windows PowerShellSichern der Shell

Don Jones

Als sich das Windows PowerShell-Team zusammensetzte, um eine neue Shell zu erstellen und das Wort „Skripterstellung“ erwähnt wurde, war die Betroffenheit groß. Schließlich waren die vorherigen Microsoft-Bemühungen bei administrativen Skripts (ich meine damit VBScript) nicht gerade problemfrei. Ein

übermäßig freizügiges Ausführungsmodell in Verbindung mit der Neigung der meisten Benutzer, sich als Administratoren anzumelden, war ein Rezept für Katastrophen.

Die Teilnehmer bei dieser ersten Windows PowerShell™-Besprechung haben mit Sicherheit innerlich gefleht, nicht noch einmal hier durchzumüssen. Und sie wurden erhört. Microsoft hat seinen Ruf in Bezug auf die Sicherheit stark verbessert, was zum größten Teil darauf zurückzuführen ist, dass die Sicherheit zuerst und nicht erst später im Entwicklungszyklus des Produkts bedacht wurde. Diese Philosophie ist bei Windows PowerShell sehr offensichtlich.

Warum laufen Skripts nicht einfach?

Installieren Sie Windows PowerShell auf einem neuen Computer, und doppelklicken Sie auf eine .ps1-Datei: anstelle von Windows PowerShell öffnet sich der Editor. Das ist darauf zurückzuführen, dass die .ps1-Dateinamenerweiterung, also die für Windows PowerShell-Skripts verwendete Erweiterung, der Shell selbst nicht zugeordnet ist. Das heißt, Sie können ein Skript nicht einfach durch Doppelklicken ausführen. Die einzige Möglichkeit zum Ausführen eines Skripts besteht darin, Windows PowerShell zu öffnen, den Skriptnamen einzugeben und dann die Eingabetaste zu drücken.

Tatsächlich reicht auch das Eingeben des Skriptnamens nicht aus. Sie sehen in Abbildung 1, dass die Datei „Demo1.ps1“ im aktuellen Ordner vorhanden ist, doch das Eingeben von „demo1“ und das Drücken der Eingabetaste führt zu einem Fehler: „The term 'demo1' is not recognized as a cmdlet, function, operable program, or script file.“ (Der Begriff „demo1“ wird nicht als Cmdlet, Funktion, betriebsfähiges Programm oder Skriptdatei erkannt.) Woran liegt das? Schließlich ist die Datei doch vorhanden.

Abbildung 1 Um Befehlsaneignungen zu vermeiden, ist für Windows PowerShell ein Pfad zu Ihrem Skript erforderlich.

Abbildung 1** Um Befehlsaneignungen zu vermeiden, ist für Windows PowerShell ein Pfad zu Ihrem Skript erforderlich. **(Klicken Sie zum Vergrößern auf das Bild)

Dies ist ein weiterer Aspekt des Windows PowerShell-Sicherheitsmodells. Ein gebräuchlicher Trick böswilliger Benutzer bei anderen Shells ist die Erstellung eines Skripts mit dem gleichen Dateinamen wie ein integrierter Befehl. Wenn ein Benutzer beispielsweise Ihr Skript ausführen soll, könnten Sie es „Dir.ps1“ nennen und in einen Ordner stellen. Wenn Sie den Benutzer davon überzeugt haben, „Dir“ einzugeben und die Eingabetaste zu drücken, könnte Ihr Skript und nicht der vom Benutzer erwartete Dir-Befehl ausgeführt werden. Dieses Verfahren wird als Befehlsaneignung bezeichnet. In Windows PowerShell muss immer ein Pfad zu einem solchen Skript angegeben werden, sodass Windows PowerShell vor Befehlsaneignungen recht gut geschützt ist.

Das Ausführen von „demo1“ funktioniert nicht, da kein Pfad angegeben wurde. Im Gegensatz dazu wird „./demo1“ ausgeführt. Dies liegt daran, dass ein Pfad – der aktuelle Ordner – angegeben wurde. Es ist weniger wahrscheinlich, dass diese Befehlszeile mit einem integrierten Befehl verwechselt wird, da Sie nie einen Pfad eingeben würden, wenn Sie auf einen integrierten Befehl verweisen. Durch die Anforderung, einen Pfad anzugeben, vermeidet Windows PowerShell Befehlsaneignungen und Verwirrung darüber, was bei Drücken der Eingabetaste geschehen könnte.

Richtlinie für die Skriptausführung

Sie haben eine neu installierte Kopie von Windows PowerShell, Sie verwenden die richtige Syntax, und Sie versuchen, ein Skript auszuführen. Zu Ihrer Überraschung wird eine weitere Fehlermeldung angezeigt, in der Sie informiert werden, dass Windows PowerShell keine Skripts ausführen darf. Warum das? Willkommen bei der Ausführungsrichtlinie der Shell.

Sie können sich die aktuelle Ausführungsrichtlinie anzeigen lassen, indem Sie „Get-ExecutionPolicy“ in der Shell ausführen. Standardmäßig ist sie auf „Restricted“ (Eingeschränkt) eingestellt, sodass Skripts für niemanden und nie ausgeführt werden. Standardmäßig kann Windows PowerShell nur interaktiv statt zum Ausführen von Skripts verwendet werden. Sie können das Set-ExecutionPolicy-Cmdlet verwenden, um eine von vier möglichen Einstellungen der Ausführungsrichtlinie auszuwählen:

  • Bei „Restricted“ als Standardeinstellung werden keinerlei Skripts ausgeführt.
  • „AllSigned“ führt nur vertrauenswürdige Skripts aus (mehr dazu gleich).
  • „RemoteSigned“ führt lokale Skripts aus, ohne dass diese vertrauenswürdig sein müssen. Aus dem Internet heruntergeladene Skripts müssen jedoch vertrauenswürdig sein, bevor sie ausgeführt werden können.
  • „Unrestricted“ ermöglicht das Ausführen aller Skripts, selbst wenn diese nicht vertrauenswürdig sind.

Es empfiehlt sich als Mindesteinstellung auf einem Produktionscomputer „AllSigned“ zu wählen. „RemoteSigned“ ist nützlich in Entwicklungs- und Testumgebungen, aber nicht notwendig für den typischen Benutzer. Für „Unrestricted“ besteht eigentlich keinerlei Bedarf, und es wäre nicht schade, wenn diese übermäßig freizügige Einstellung in einer zukünftigen Version von Windows PowerShell ausgelassen würde.

Eine Frage des Vertrauens

Ihr Computer ist vorkonfiguriert, bestimmten Stamm-Zertifizierungsstellen (Certification Authorities, CAs), also Servern, die digitale Zertifikate ausstellen, zu vertrauen. Abbildung 2 zeigt die Systemsteuerungsanwendung „Internetoptionen“, in der als vertrauenswürdig eingestufte Stammzertifizierungsstellen aufgeführt sind. In Windows Vista® ist diese Liste ziemlich kurz und umfasst nur ein paar größere, gewerbliche Stammzertifizierungsstellen. Im Gegensatz dazu ist die Standardliste in Windows® XP groß und umfasst viele Stammzertifizierungsstellen, die relativ unbekannt sind. Wenn eine Stammzertifizierungsstelle in dieser Liste enthalten ist, wird damit im Grunde Folgendes ausgedrückt: Sie vertrauen dem Unternehmen, das die Stammzertifizierungsstelle betreibt, dass es beim Überprüfen der Identität einer Person gute Arbeit leistet, bevor dem Betreffenden ein digitales Zertifikat ausgestellt wird.

Wenn Sie ein digitales Zertifikat der Klasse III erhalten (allgemein als codesigniertes Zertifikat bezeichnet), muss die CA, bei der es sich um eine gewerbliche CA oder eine private CA in Ihrer Organisation handeln kann, Ihre Identität überprüfen. Dieses digitale Zertifikat entspricht praktisch einem elektronischen Ausweis. Bevor ich einen Ausweis erhalte, der angibt, dass ich Don Jones bin, muss die CA einige Schritte unternehmen, um sicherzustellen, dass das wirklich stimmt. Wenn Sie Ihr Zertifikat zum digitalen Signieren eines Windows PowerShell-Skripts verwenden, was mithilfe des Set-AuthenticodeSignature-Cmdlet geschehen kann, signieren Sie das Skript mit Ihrem Namen. Doch wenn Sie ein falsches Zertifikat mit dem Namen einer anderen Person erhalten können, können Sie ihr Skript mit deren Namen signieren. Aus diesem Grund ist es so wichtig, dass nur vertrauenswürdige CAs auf der Liste in Abbildung 2 enthalten sind.

Abbildung 2 In Windows Vista standardmäßig als vertrauenswürdig eingestufte Stammzertifizierungsstellen

Abbildung 2** In Windows Vista standardmäßig als vertrauenswürdig eingestufte Stammzertifizierungsstellen **(Klicken Sie zum Vergrößern auf das Bild)

Wenn Windows PowerShell prüft, ob ein Skript vertrauenswürdig ist, was bei der Einstellung „AllSigned“ und „RemoteSigned“ geschieht, werden drei Fragen gestellt:

  • Ist dieses Skript signiert? Wenn nicht, ist das Skript nicht vertrauenswürdig.
  • Ist die Signatur unversehrt? Das heißt, wurde das Skript geändert, seit es signiert wurde? Bei nicht unversehrter Signatur ist das Skript nicht vertrauenswürdig.
  • Wurde die Signatur mithilfe eines digitalen Zertifikats erstellt, das von einer vertrauenswürdigen Stammzertifizierungsstelle ausgestellt wurde? Wenn nicht, ist das Skript nicht vertrauenswürdig.

CMDLET des Monats: Set-AuthenticodeSignature

Set-AuthenticodeSignature ist der Schlüssel zum digitalen Signieren Ihrer Windows PowerShell-Skripts, sodass Sie die sicherste Ausführungsrichtlinie der Shell (AllSigned) verwenden können. Um dieses Cmdlet zu verwenden, beginnen Sie mit einem anderen (Get-ChildItem), das ein installiertes codesigniertes Zertifikat abruft:

$cert = Get-ChildItem –Path cert:\CurrentUser\my –codeSigningCert

Der Dateipfad muss durch einen Pfad ersetzt werden, der auf ein installiertes Zertifikat verweist. Alle installierten Zertifikate sind über das Laufwerk „cert:“ zugänglich. Nach Laden des Zertifikats wird es zum Signieren eines Skripts ausgeführt:

Set-AuthenticodeSignature MyScript.ps1

–cert $cert

Natürlich geben Sie den vollständigen Pfad zu Ihrer .ps1-Skriptdatei an. Die Shell fügt der Datei eine Signatursperre hinzu.

Wie verbessert Vertrauen die Sicherheit? Natürlich könnte ein Hacker ein potenziell schädliches Skript schreiben, es signieren und jemanden in Ihrer Umgebung überzeugen, es auszuführen. Da das Skript signiert wurde, wird es ausgeführt. Doch da es signiert wurde, können Sie mithilfe der Signatur die Identität des Autors feststellen und entsprechende Maßnahmen ergreifen (indem Sie beispielsweise die Strafverfolgungsbehörden einschalten). Der Betreffende müsste jedoch sehr dumm sein, ein schädliches Skript zu erstellen und es mit seinem Namen zu signieren!

Doch wenn ein böswilliger Benutzer in der Lage wäre, ein Zertifikat mit der Identität einer anderen Person zu erlangen (beispielsweise von einer CA, die nicht über einen guten Prozess zur Identitätsprüfung verfügt), könnte der eigentliche Schuldige nicht anhand der Signatur ermittelt werden. Daher sollten die Stammzertifizierungsstellen, denen Sie vertrauen, einen Identitätsprüfungsprozess einsetzen, den Sie als befriedigend empfinden.

Wenn Sie die Einstellung „AllSigned“ der Ausführungsrichtlinie verwenden, müssen Sie sogar selbst jedes von Ihnen produzierte Skript digital signieren, bevor es ausgeführt werden kann. Die Verwendung des Set-AuthenticodeSignature-Cmdlet ist recht einfach, kann sich jedoch dennoch recht mühsam gestalten. Dabei könnte Drittanbietersoftware hilfreich sein. Es ist empfehlenswert, einen Skripteditor oder eine visuelle Entwicklungsumgebung auszuwählen, die Ihre Skripts automatisch mit dem von Ihnen angegebenen Zertifikat signiert. Auf diese Weise ist die Verwendung von Signaturen transparent und erfordert keinen zusätzlichen Aufwand. Wenn Sie Vorschläge für Editoren und Entwicklungsumgebungen wünschen, die dies unterstützen, besuchen Sie einige Onlineforen für die Skripterstellung (beispielsweise ScriptingAnswers.com) und fragen nach, was andere Anhänger von Windows PowerShell verwenden.

Wenn Sie ein Zertifikat haben, können Sie auch folgenden Einzeiler zum Signieren aller Skripts an einem bestimmten Speicherort verwenden:

Get-Childitem *.ps1 | %{Set-AuthenticodeSignature $_.fullname $cert}

Zentral gesichert

Die Windows PowerShell-Ausführungsrichtlinie kann selbstverständlich auf jedem Computer für sich konfiguriert werden. Doch das ist keine gute Lösung für Unternehmensumgebungen. Stattdessen können Sie die Gruppenrichtlinie verwenden. (Die administrativen Vorlagen für Windows PowerShell stehen unter go.microsoft.com/fwlink/?LinkId=93675 als Download zur Verfügung.) Sichern Sie die Datei einfach in einem Gruppenrichtlinienobjekt (Group Policy Object, GPO), das sich auf Ihre ganze Domäne auswirkt, und verwenden Sie die Einstellung „Restricted“. So können Sie sichergehen, dass unabhängig davon, wo Windows PowerShell installiert ist, keine Skripts ausgeführt werden. Dann können Sie eine freizügigere Einstellung (etwa „AllSigned“) nur für die Computer verwenden, auf denen Skripts ausgeführt werden sollen (beispielsweise Ihre eigene Arbeitsstation).

Alternative Anmeldeinformationen

Im Gegensatz zu vorherigen administrativen Skriptsprachen für Windows kann Windows PowerShell sogar alternative Anmeldeinformationen auf sichere Weise behandeln. Das Get-WMIObject-Cmdlet hat beispielsweise einen -credential-Parameter, der es Ihnen ermöglicht, alternative Anmeldeinformationen für WMI-Remoteverbindungen anzugeben. Der Parameter akzeptiert einen Benutzernamen, aber kein Kennwort, wodurch verhindert wird, dass vertrauliche Kennwörter in einem klaren Textskript hart codiert werden. Wenn Sie den Benutzernamen angeben, werden Sie von Windows PowerShell stattdessen über ein Dialogfeld zur Kennworteingabe aufgefordert. Wenn Sie planen, ein solches Alternativkonto erneut zu verwenden, können Sie die Anmeldeinformationen mithilfe des Get-Credential-Cmdlet speichern:

$cred = Get-Credential DOMAIN\USER

Sie werden sofort zur Eingabe des Kennworts aufgefordert, und die endgültigen Anmeldeinformationen werden in der Variablen „$cred“ gespeichert. Die $cred-Variable kann dann beliebig oft an den -credential-Parameter übergeben werden. Sie können sogar das ConvertTo-SecureString- und das ConvertFrom-SecureString-Cmdlet verwenden, um die Anmeldeinformationen in eine verschlüsselte Zeichenfolge zu konvertieren oder eine zuvor verschlüsselte Zeichenfolge wieder in die Anmeldeinformationen zu konvertieren.

Das Problem dabei besteht darin, dass Ihr Verschlüsselungsschlüssel in einem Klartextskript gespeichert wird, was die Sicherheit völlig untergräbt. Stattdessen können Sie Ihrem Windows PowerShell-Profil den Aufruf „Get-Credential“ hinzufügen. Dann werden Sie beim Ausführen von Windows PowerShell sofort zur Eingabe eines Benutzernamens und Kennworts aufgefordert, die dann in einer $cred-Variablen gespeichert werden. Damit steht Ihnen immer eine $cred-Variable in der Shell zur Verfügung, die ein Domänenadministratorkonto repräsentiert. Diese Anmeldeinformationen müssen Sie überdies nirgendwo speichern, da sie jedes Mal beim Öffnen der Shell neu erstellt werden.

Sicherheit als Standard

Standardmäßig wird Windows PowerShell mit den sichersten Einstellungen installiert und konfiguriert, die man sich für eine administrative Shell, die die Skripterstellung unterstützt, vorstellen kann. Wenn Sie diese Einstellungen nicht ändern, bietet Windows PowerShell höchstmögliche Sicherheit. Das heißt, alles, was die Sicherheit in Windows PowerShell verringert, ist das Ergebnis Ihrer Entscheidungen und Aktionen. Bevor Sie also Standardeinstellungen ändern (und beispielsweise die Zuordnungen von Dateierweiterungen neu konfigurieren, die Ausführungsrichtlinie ändern und so weiter), sollten Sie die Auswirkungen Ihrer Änderungen genauestens prüfen.

Don Jones ist der führende Scripting-Guru bei SAPIEN Technologies und Ausbilder für ScriptingTraining.com. Sie können ihn über seine Website ScriptingAnswers.com erreichen.

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