Skripte
Jeder Powershell-Befehl, der in einer Textdatei mit der Endung .ps1 gespeichert wird, kann als Skript aufgerufen werden. Dabei gibt es allerdings eine Reihe von Sicherheitsfeatures, die die Ausführung von Skripten blockieren können.
Jeder Powershell-Befehl, der in einer Textdatei mit der Endung .ps1 gespeichert wird, kann als Skript aufgerufen werden. Dabei gibt es allerdings eine Reihe von Sicherheitsfeatures, die die Ausführung von Skripten blockieren können.
Cmdlets und Befehle können jederzeit interaktiv in der Konsole ausgeführt werden, aber die Ausführung von Skripten wird standardmäßig blockiert. Hierfür verantwortlich ist die sogenannte Ausführungsrichtlinie, die bestimmt, welche Skripte ausgeführt werden dürfen. Die Ausführungsrichtlinie einer Powershell-Konsole kann man mit Get-Executionpolicy aus geben.
Get-ExecutionPolicy
Es gibt 5 verschiedene Richtlinien:
|
Richtlinie |
Bedeutung |
|
Restricted (Default) |
Verhindert das Ausführen jeglicher Skripte |
|
AllSigned |
Skripte müssen digital signiert sein, damit sie ausgeführt werden können |
|
RemoteSigned |
Skripte, die aus dem Internet heruntergeladen wurden oder aus einer Freigabe gestartet werden, müssen digital signiert sein |
|
Unrestricted |
Alle Skripte können ohne Einschränkungen ausgeführt werden, aber bei aus dem Internet heruntergeladenen Skripten wird gewarnt |
|
Bypass |
Powershell deaktiviert sämtliche Sicherheitsprüfungen, es werden keine Warnungen ausgegeben |
Um die Standeinstellung von Restricted auf eine andere Richtlinie umzustellen, verwendet man das Cmdlet Set-ExecutionPolicy:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned
Tatsächlich können mehrere Ausführungsrichtlinien gleichzeitig in unterschiedlichen Geltungsbereichen (Scopes) zugewiesen sein. Das obige Beispiel setzt den Gültigkeitsbereich für den Computer, der standardmäßig für alle Benutzer gilt.
Ein Benutzerprofil hat aber eine eigene Ausführungsrichtlinie. Außerdem gibt es noch die drei Bereiche Process, die die Einstellungen für einen spezifischen Powershell-Prozess festlegen, sowie UserPolicy und MachinePolicy, die beide über Gruppenrichtlinien gesteuert werden.
|
Priorität |
Scope (Geltungsbereich) |
Konfiguriert über |
|
1 (höchste) |
MachinePolicy |
Gruppenrichtlinien (Computer) |
|
2 |
UserPolicy |
Gruppenrichtlinien (Benutzer) |
|
3 |
Process |
Powershell.exe -ExecutionPolicy |
|
4 |
CurrentUser |
Set-Executionpolicy -Scope CurrentUser |
|
5 (niedrigste) |
LocalMachine |
Set-ExecutionPolicy -Scope LocalMachine |
Normalerweise ist nur die Computerrichtlinie gesetzt, und die anderen vier Bereiche (Scopes) sind undefiniert. Dadurch gilt die Computerrichtlinie für alle Benutzer. Man kann aber Benutzerspezifisch die Einstellungen überschreiben. Die Benutzereinstellungen haben, wie man in der Tabelle sehen kann, Vorrang vor den Computereinstellungen. Um die Benutzerkonfiguration zu ändern, muss man Set-ExecutionPolicy mit dem Parameter -Scope aufrufen und einen Bereich angeben:
Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope CurrentUser
Die anderen drei Gültigkeitsbereich können nicht über Set-Executionpolicy gesetzt werden. Um den Prozess-Scope zu setzen, starten Sie die Powershell.exe mit dem Parameter /Executionpolicy und geben als Argument die gewünschte Ausführungsrichtlinie an:
powershell.exe /ExecutionPolicy Unrestricted -file C:\skripte\skript.ps1
Die Gültigkeitsbereiche UserPolicy und MachinePolicy können nur über Gruppenrichtlinien konfiguriert werden und überschreiben alle anderen Einstellungen. So ist es prinzipiell möglich, die Ausführung von Skripten auf einem Computer grundsätzlich zu unterbinden. Die Konfiguration der Ausführungsrichtlinien über Gruppenrichtlinien wird im Abschnitt Ausführungsrichtlinien setzen beschrieben.
Get-Executionpolicy -List zeigt alle konfigurierten Ausführungsrichtlinien. Grundsätzlich gilt die Richtlinie, die von oben gesehen als erste eine definierte Richtlinie hat.
Get-ExecutionPolicy -List
Scope ExecutionPolicy
----- ---------------
MachinePolicy Undefined
UserPolicy Undefined
Process Bypass
CurrentUser Undefined
LocalMachine Bypass
Der Sinn der Ausführungsrichtlinien ist es, das versehentliche Starten von Skripten zu verhindern. Sicherheitsrichtlinien sind explizit kein Sicherheitsfeature und können das Ausführen von Powershell-Skripten nicht verhindern! Zum einen kann die globale Computerrichtlinie von einem Benutzer auch ohne administrative Berechtigungen durch Set-Executionpolicy -Scope <Bereich> überschrieben oder mit dem Powershell-Prozess umgangen werden, zum anderen kann durch Aktivieren eines einzigen Bits im laufenden Powershell-Prozess die Ausführungsrichtlinie manipuliert werden – auch ohne administrative Berechtigungen.
Es geht aber noch viel einfacher, denn ein Benutzer kann den Inhalt eines Skripts auch einfach in einer interaktiven Konsole einlesen und per Pipeline zur Ausführung bringen.
Get-Content -Path c:\MySkript.ps1 | powershell.exe /command -
Leitet man ein Text-Array (hier also den Inhalt einer .ps1-Datei) in die Powershell.exe und verwendet den Parameter /command, führt Powershell die Zeilen wie Einzelkommandos aus und umgeht so die Ausführungsrichtlinie. Sehen Sie Ausführungsrichtlinien also nicht als Sicherheitsfeature, sondern eher als Basisschutz für Ihre Benutzer vor sich selbst.
Grundsätzlich gilt, dass Ausführungsrichtlinien in erster Linie stören, da sie die erwünschte Ausführung von Skripten mehr behindern als schädlichen Code. Um die Ausführungsrichtlinie unveränderbar festzulegen, muss man außerdem auf Gruppenrichtlinien zurückgreifen. Daher sollten Sie sich entscheiden, die Ausführung von Powershell entweder komplett zu unterbinden, die Ausführungsrichtline auf "Unrestricted" zu setzen und damit alle Skripte zuzulassen oder ausschließlich signierte Skripte zuzulassen (Allsigned). Das hat allerdings ein paar zusätzliche Implikationen, die genau wie der eigentliche Signaturvorgang im Abschnitt Skripte signieren beschrieben werden. Um Powershell sicher zu betreiben, sollten Sie stattdessen auf Skriptüberwachung setzen. Wie man das implementiert, finden Sie im Abschnitt Powershell per GPO konfigurieren.
Wie beschrieben, funktionieren die Powershell Ausführungsrichtlinien suboptimal. Die Ausführungs von Skripten lässt sich nur per Gruppenrichtlinie vollständig verhindern, aber dann ist auch die Ausführung administrativer Skripte blockiert, und außerdem ist auch diese Hürde für einen Angreifer umgehbar. Man kann die Powershell aber mit Hilfe von Applocker oder Application-Control Policies vollständig absichern. Powershell-Skripte können dann nur noch aus vertrauenswürdigen Ordnern uneingeschränkt ausgeführt werden. Alle anderen Skripte laufen im sogenannten Constrained Language Mode, der Skripte zwar zulässt, aber nur sichere Cmdlets erlaubt.
Es gibt verschiedene Wege, ein Powershell-Skript zu starten. Sie können Skriptdateien z.B. über das Kontextmenü ausführen lassen.

Abbildung 6 - Ein Skript über das Kontextmenü starten
Sie können das Skript auch über die Powershell.exe starten.
powershell.exe -file C:\skripte\config.ps1
Der Powershell.exe können Sie eine Reihe von weiteren Parametern übergeben, die zum Starten des Skripts angewendet werden können.
|
Parameter |
Funktion |
|
-NoExit |
Das Powershell-Fenster wird nach Beendigung des Skripts nicht geschlossen |
|
-NoProfile |
Es werden beim Starten keine Profilskripte geladen |
|
-ExecutionPolicy |
Die Standard-Ausführungsrichtlinien des Computers und Benutzers können für diesen Aufruf überschrieben werden (benötigt Admin-Rechte) |
|
-WindowStyle |
Legt den Stil der Powershell-Konsole fest, wobei Hidden leider nicht funktioniert |
|
-File |
Der Pfad zur .ps1-Datei |
|
-Command |
Statt einer Datei kann auch ein Skriptblock direkt ausgeführt werden |
|
-EncodedCommand |
Base64-Codierte Scripte können direkt ausgeführt werden. ! Achtung ! Diese Option kann zur Verschleierung von Schadcode verwendet werden. |
Mehr Parameter werden Ihnen angezeigt, wenn Sie Powershell.exe /? an der Kommandozeile eingeben.
Mit geplanten Aufgaben können Sie Powershell-Skripte zeit- oder ereignisgesteuert starten. Geplante Aufgaben können sogar mit Powershell erstellt werden.
$trigger = New-ScheduledTaskTrigger -Once -At (get-date).AddSeconds(30)
$Args = "-ExecutionPolicy Bypass -Command get-date | set-Content -Path C:\demo.txt"
$Action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument $Args
Register-ScheduledTask -TaskName 'Demo' -User System -Action $Action -Trigger $trigger
Eine Aufgabe benötigt immer einen Auslöser (Trigger). Im Beispiel soll die Aufgabe einmalig in 30 Sekunden ausgelöst werden. Die auszuführende Aktion ist der Start der Powershell.exe mit den angegebenen Argumenten. Danach muss der Task registriert werden. Mit dem Parameter -User kann man ein Startkonto angeben, in diesem Fall das Systemkonto, das mit vollen Admin-Rechten läuft. Diese Variante des Startens von Skripten ist nicht nur hilfreich, wenn man ein Skript zeitgesteuert aufrufen will, sondern kann auch genutzt werden, um Skripte remote auszuführen.
Natürlich können Sie Powershell-Skripte auch aus einer Powershell-Konsole aufrufen. Achten Sie dabei auf ein weiteres Sicherheitsfeature von Powershell – Sie können Programme und Skripte immer nur mit qualifiziertem Namen (also mit Pfadangabe) starten, es sei denn, das Skript liegt in einem Ordner, derin der Pfadvariable hinterlegt sind. Wenn Sie also ein Skript demo.ps1 aus dem Ordner c:\Skripte starten wollen, müssen Sie einen der folgenden Aufrufe verwenden:
.\Demo.ps1
# Wenn Sie sich im Ordner C:\Skripte befinden
C:\Skripte\Demo.ps1 # von überall anders aus
Der direkte Doppelklick auf ein Skript zeigt das Skript im Notepad an, es wird nicht ausgeführt!
Zum Erstellen von Skripten gibt es von Microsoft gleich zwei Editoren, die das Schreiben von Powershell-Skripten erleichtern sollen. Der eine Editor ist seit Powershell 2.0 Bestandteil von Windows und wird als ISE (Integrated Scripting Environment) bezeichnet. Man kann ihn direkt aus dem Startmenü aufrufen, durch Eingabe von ISE in der Powershell-Konsole, oder über den Programmnamen Powershell_ise.exe.
Der zweite Editor nennt sich Visual Studio Code, und ist im Gegensatz zur ISE nicht auf die Entwicklung von Powershell-Skripten beschränkt. Visual Studio Code basiert auf Chromium und ist Open Source. Man kann ihn direkt bei Microsoft für Windows, Linux und MacOs (!) herunterladen: https://code.visualstudio.com/
Um Visual Studio Code mit Powershell einzusetzen, sollten Sie die Powershell-Erweiterungen installieren.

Abbildung 7 - Visual Studio Code benötigt eine Erweiterung, um Powershell vollständig zu unterstützen
Wählen Sie dafür nach dem Starten das Erweiterungen-Icon in der linken Symbolleiste aus (1) und geben im Eingabefenster für den Marketplace (2) Powershell ein. Die erste Erweiterung installiert die Unterstützung für Powershell, mit der Sie unter anderem Intellisense bekommen, also Vorschläge zur Ergänzung von Cmdlet- und Variablennamen. Eine ausführliche Anleitung zum Visual Studio Code finden Sie auf der Visual Studio Code Website.
Sie können Powershell-Skripte natürlich auch in einem einfachen Editor wie Notepad entwickeln, aber die ISE und Visual Studio bringen viele nützliche Features mit, die die Entwicklung deutlich beschleunigen.
Prinzipiell ist jede Textdatei, die Powershell-Befehle enthält und unter der Endung .ps1 endet, ein Powershell-Skript.