PowerShell ExecutionPolicy

Damit ein PowerShell Skript vertrauenswürdig ist, kann der Autor das Skript digital signieren. In Verbindung mit einer entsprechenden Richtlinie auf ihren Computern können Sie damit die Ausführung von fremden, unbekannten oder nicht verifizierte Skripte unterbinden.

Set-ExecutionPolicy

Die meisten Administratoren werden mit der Codesignatur in Berührung gekommen sein, wenn Sie ein Skript aus dem Internet auf einem Client einfach ausführen wollten und dies verhindert wurde. Die Standardeinstellungen eines Windows PCs steht auf "Remote Signed". Starten Sie einfach eine PowerShell und führen sie folgendes Commandlet aus:

# Standardeinstellung auf einem Windows Client
Get-ExecutionPolicy -List | ft -AutoSize

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process       Undefined
  CurrentUser       Undefined
 LocalMachine       Undefined

Für ihre Umgebung gilt natürlich nur eine effektive Richtlinie, d.h. hier ist die Priorität zu beachten. Der Default Scope beim Setzen einer Richtline mit "Set-ExecutionPolicy" ist "Local Machine". Das geht natürlich nur als Administrator und die PowerShell informiert sie.

# PowerShell 2-5
Set-ExecutionPolicy : Access to the path 'C:\Program Files\PowerShell\6\powershell.config.json' is denied.
To change the execution policy for the default (LocalMachine) scope, start PowerShell with the "Run as administrator" 
option. To change the execution policy for the current user, run "Set-ExecutionPolicy -Scope CurrentUser".

#PowerShell 6-x
Set-ExecutionPolicy : Der Zugriff auf den Registrierungsschlüssel
"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell" wurde verweigert. Starten Sie zum
Ändern der Ausführungsrichtlinie für den Standardbereich (LocalMachine) Windows PowerShell mit der Option "Als
Administrator ausführen". Führen Sie zum Ändern der Ausführungsrichtlinie für den aktuellen Benutzer

Achtung:
Sie sehen schon am Fehler, dass die Speicherorte für die Richtlinien für Powershell 1-5 und 6-x an unterschiedlichen Stellen verwaltet werden. PowerShell Core läuft ja auch auf Linux u.a., wo es keine Registrierung gibt.

Der zweite Aspekt ist die Vererbung von Richtlinien. Sie können gerne eine Richtlinie auf "LocalMachine" setzen, aber eine Richtlinie per GPO gewinnt. Darauf weist Sie die PowerShell aber auch hin.

PS> Set-ExecutionPolicy -ExecutionPolicy Restricted -Scope LocalMachine 

Set-ExecutionPolicy : PowerShell updated your local preference successfully, but the 
setting is overridden by the Group Policy applied to your system. Due to the override, 
your shell will retain its current effective execution policy of "AllSigned". 
Contact your Group Policy administrator for more information.

Damit haben aber Administratoren eine sehr gute Kontrolle, welche Skripte wo ausgeführt werden. Speziell Clients mit "normalen Anwendern", die als Einfallstor für Malware genutzt werden können, sind so gut zu blocken.

Ausführung geblockt

Die Standardpolicy für Skripte eines Windows Clients lautet auf "Restricted" und verhindert den einfachen Start von PowerShell.

PS C:\End2End> .\end2end-http.ps1
.\end2end-http.ps1 : Die Datei "C:\End2End\end2end-http.ps1" kann nicht geladen werden, da die Ausführung von Skripts
auf diesem System deaktiviert ist. Weitere Informationen finden Sie unter "about_Execution_Policies"
(https:/go.microsoft.com/fwlink/?LinkID=135170).

Das ist aber kein 100% Schutz, denn der Anwender kann diese Blockade mit ein paar Handgriffen umgehen. Viele Firmen erlauben aber schon lokale Skripte, wenn diese nicht aus dem Internet heruntergeladen wurden oder von einem UNC-Pfad kommen. Dazu stellen Sie die Richtline dann auf "RemoteSigned" um. Sicherer ist das aber nicht. Interessanter ist da eher die Vorgabe "AllSigned"

Set-ExecutionPolicy -ExecutionPolicy AllSigned -scope LocalComputer

Wenn ein Anwender auf seinem Client dann versucht ein nicht signiertes Skript zu starten, dann kann er folgende Meldung sehen.

PS C:\End2End> .\end2end-http.ps1
.\end2end-http.ps1 : Die Datei "C:\End2End\end2end-http.ps1" kann nicht geladen werden. Die Datei "C:\End2End\end2end-http.ps1"
ist nicht digital signiert. Sie können dieses Skript im aktuellen System nicht ausführen. Weitere Informationen zum Ausführen von
Skripts und Festlegen der Ausführungsrichtlinie erhalten Sie unter "about_Execution_Policies"

Sie können die Ausführung z.B. auf signierte Skripte beschränken, und ihre eigenen Skripte durch eine eigenes Codesigning-Zertifikat ihrer eigenen PKI signieren. Das ist schon ein guter Schutz aber kein 100% Schutz, da auch Malware-Autoren z.B. CodeSigning-Zertifikate mit gefälschten Identitäten kaufen und ihre Malware signieren können. Aber es ist dennoch eine Überlegung wert.

Allerdings kann ein Anwender je nach Kenntnisstand die Richtlinien auch umgehen. Sie gelten nämlich nur, wenn die PowerShell den Code interpretiert. Es gibt aber zwei sehr einfache Optionen, die Mitarbeiter nutzen können.

  • Powershell ISE
    Sie starten einfach die ISE und öffnen dort die PS1-Datei. In der ISE können Sie das Skript auch ausführen und hier kommt die Default Execution-Policy nicht zur Anwendung.
  • Powershell.exe mit "-executionpolicy remoteSigned" oder "-executionpolicy bypass" starten
    Für die dann geöffnete PowerShell gilt die Execution Policy, die auf der Kommandozeile mit übergeben wurde
  • Zeilenweises Ausführen
    Nicht verhindern können sie, dass ein Anwender das Skript einfach per Zwischenablage in ein PowerShell Fenster einfügt. Dann wird jede Zeile einzeln ausgeführt. Es ist dann kein "Skript"

Wobei beide Optionen nur eine für den Anwender oder lokal gesetzte Richtline überstimmen. Wenn Sie per Kommandozeile einen von per Gruppenrichtlinien vorgegebenen Policy abweichen, dann greift diese nicht. Aber dann gibt es noch mindestens 13 andere Wege.

Wenn Sie hier "dicht" sein wollen, dann sollten Sie sie sich mal Applocker und SmartScreen anschauen.

Ausführen von Skripten

Als Administrator können Sie die Policy mit "Set-ExecutionPolicy" setzen. Dabei gibt es nicht nur ein "Aus, Signiert, Ein", sondern Windows kann sich pro Datei auch merken, aus welcher Quelle Sie kommt. Eine Datei kann auf einer lokalen Festplatte oder einem UNC-Pfad liegen oder aus der Internet heruntergeladen worden sein. Je nach Policy werden Skripte also ausgeführt oder nicht:

Policy lokal unsigniert Lokal signiert Remote unsigniert Remote signiert Internet unsigniert Remote signiert Beschreibung

Unrestricted

Diese Einstellung gilt für "nicht Windows-Systeme" seit PowerShell 6 und kann wohl nicht geändert werden. Es werden alle Skripte ausgeführt aber unsignierte Skripte aus dem Internet erzeugen eine Rückfrage

RemoteSigned

Lokale Skripte werden unabhängig von einer Signatur ausgeführt. Skripte über UNC-Pfade oder mit der "Internet-Zone" müssen signiert sein. Dies ist die Standardeinstellung für Windows Server

AllSigned

Alle Skripte müssen signiert werden. Unsignierte Skripte werden nicht ausgeführt. Dies ist eine sehr gute Policy für Desktops und Server, auf denen Administratoren Skript aus vielleicht unbekannten Quellen einsetzen. Es kann aber bei Produktinstallationen wie Exchange störend sein, da hier auch PowerShell zum Einsatz kommt

Restricted

Es werden keine Skripte ausgeführt. Dies ist der Default für Windows Clients

Default

Setzt die Standardeinstellung des Betriebssystems. (Server = RemoteSigned, Client=Restricted

Bypass

Keine Warnungen oder Prompts

Undefined

Entfernt eine eventuell manuell gesetzte Richtlinie. Es kommt die Richtline gemäß der Vererbung zum Tragen. Wenn alle Richtlinien "undefined" sind, dann ist der Default wieder "Restricted

Eine Datei, die aus dem Internet herunter geladen wurde, können Sie einfach über die Eigenschaften der Datei mit dem Windows Explorer wieder "freigeben".

Alternativ geht es auch per "Unblock-File" in der PowerShell.

  • Unblock-File
    https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/unblock-file?view=powershell-6

Weitere Links