Tags: PowerShell, Sicherheit
PowerShell ist ein mächtiges Werkzeug, das fast alle Komponenten von Windows und Anwendungen wie Exchange steuern kann. In den Händen von Angreifern kann sie daher große Schäden anrichten. Der Constrained Language Mode sperrt gefährliche Features und verhindert so deren Missbrauch.
Standardmäßig operiert PowerShell im FullLanguage Mode, in dem alle Funktionen verfügbar sind. Dazu zählt der Zugriff auf alle Sprachelemente, Cmdlets und Module, aber auch auf das Dateisystem und das Netzwerk.
Geblockte Funktionen
Besonders gefährlich für die missbräuchliche Verwendung von PowerShell ist die Fähigkeit, COM- und .NET-Objekte zu instanziieren oder das Erzeugen von beliebigen Datentypen (mit Add-Type), die in anderen Sprachen definiert wurden.
Der Constrained Language Mode blockiert diese Möglichkeiten (mit Ausnahme des Zugriffs auf zulässige .NET-Klassen). Darüber hinaus verhindert er die Verwendung von Klassen, das Configuration Management mit DSC und XAML-basierte Workflows (für eine komplette Liste siehe Microsoft Docs).
Constrained Language Mode aktivieren
Eine einfache Variante, um in den Constrained Language Mode zu schalten, besteht darin, die zuständige Variable auf den gewünschten Wert zu setzen:
$ExecutionContext.SessionState.LanguageMode = "ConstrainedLanguage"
Es liegt auf der Hand, dass das Setzen dieser Variable noch keinen wirklichen Schutz bringt. Man kann sie zwar in der gleichen Sitzung nicht wieder auf FullLanguage ändern, aber eine neue PowerShell-Session bietet dann wieder den vollen Sprachumfang.
In eingeschränkten Modus schalten mit Umgebungsvariable
Weniger leicht zu überwinden ist die (undokumentierte) System-Umgebungsvariable __PSLockDownPolicy, wenn man diese auf den Wert 4 setzt. In der Folge startet PowerShell, egal ob bloße Kommandozeile oder die ISE, im eingeschränkten Modus.
In zentral verwalteten Umgebungen wird man die Systemvariable per Gruppenrichtlinien setzen (siehe dazu Gruppenrichtlinien: Umgebungsvariablen setzen und abfragen).
Ein Nachteil dieses Verfahrens besteht darin, dass es sich immer auf alle Benutzer eines Computers auswirkt, auch auf Administratoren. Letztere können die Umgebungsvariable aber temporär entfernen, bis das GPO wieder wirksam wird.
Darüber hinaus ist es in dieser Form kein von Microsoft unterstütztes Sicherheits-Feature und es lässt sich relativ leicht umgehen, wie Matt Graeber in diesem Tweet zeigt. Trotzdem könnte es auch so einige opportunistische Angriffe vereiteln.
Eine verbindliche Durchsetzung des beschränkten Sprachmodus auf einem lokalen Rechner erfordert somit die Mithilfe einer Ausführungsbeschränkung wie AppLocker oder Windows Defender Application Control (vormals ein Feature von Device Guard). Dagegen kann man ihn in einer Remote-Sitzung über eine Session Configuration erzwingen.
Automatische Erkennung einer Ausführungsbeschränkung
Seit der Version 5 erkennt PowerShell selbständig, ob es anhand von Skriptregeln in den Constrained Language Mode wechseln soll. Dazu legt es ein Modul und ein Script (mit einem Namen nach dem Muster __PSSCRIPTPOLICYTEST_LQU1DAME.3DD.PS1) unter $env:temp an und versucht, diese auszuführen. Wenn AppLocker oder ein anderes Tool das verhindert, startet PowerShell im eingeschränkten Sprachmodus.
Das Wirken dieses Mechanismus kann man bei AppLocker recht leicht in der Ereignisanzeige nachvollziehen. Das Anlegen und Ausführen dieser Testdateien protokolliert AppLocker mit der ID 8005 (Erfolg) bzw. 8007 (Ausführung blockiert) unter Anwendungs- und Diensteprotokoll => Microsoft => Windows => AppLocker => MSI und Script.
AppLocker konfigurieren
Setzt man für diese Aufgabe AppLocker ein, dann legt man ein neues GPO an und bearbeitet es anschließend im GPO-Editor. Dort wechselt man zu Computerkonfiguration => Richtlinien => Windows-Einstellungen => Sicherheitseinstellungen => Anwendungssteuerungsrichtlinien => AppLocker und folgt dem Link Regelerzwingung konfigurieren. Im darauf angezeigten Dialog aktiviert man die Option Skriptregeln.
Damit AppLocker Anwendungen auf den Zielsystemen blockieren kann, muss dort der Service Anwendungsidentität laufen. Er ist standardmäßig nicht aktiv und startet nicht zusammen mit dem System. Man kann ihn entweder interaktiv über das MMC-Snapin Dienste oder über die Kommandozeile auf den Starttyp automatisch ändern:
sc config AppIDSvc start=auto
Für ein zentrales Management dieses Windows-Dienstes empfiehlt sich der Einsatz von Gruppenrichtlinien.
Regeln definieren
Nun ist es noch notwendig, Regeln zu definieren, die den Start von Scripts im Temp-Verzeichnis blockieren. Dazu reicht es aus, unterhalb von AppLocker zu Skriptregeln zu wechseln und dort aus dem Kontextmenü den Befehl Standardregeln erstellen auszuführen.
Sie bewirken, dass normale User Scripts nur starten dürfen, wenn sie in den Verzeichnissen Windows oder Programme gespeichert sind, also an Orten, wo sie selbst keine Dateien ablegen können. Administratoren sind über eine eigene Regel explizit von dieser Einschränkung ausgenommen.
Constrained Language Mode über SRP aktivieren
AppLocker ist bekanntlich ein Feature, das den Editionen Enterprise und Education vorbehalten ist. Daher kann man in der Pro Edition stattdessen auf die Richtlinien für Softwareeinschränkung (Software Restriction Policies, SRP) zurückgreifen.
Auch damit muss man nur sicherstellen, dass sich die beiden Test-Scripts im %temp%-Verzeichnis nicht ausführen lassen. Dazu erstellt man ein GPO und bearbeitet es im Editor unter Computer- bzw. Benutzerkonfiguration => Richtlinien => Windows-Einstellungen => Sicherheitseinstellungen => Richtlinien für Softwareeinschränkungen.
Hier legt man eine neue Richtlinie an und ergänzt im ersten Schritt die Liste der designierten Dateitypen um die Endungen ps1 und psm1.
Anschließend erstellt man unter Zusätzliche Regeln eine neue Pfadregel. Dort gibt man als Pfad %temp% ein und belässt die Einstellung für Sicherheitsstufe auf Nicht erlaubt.
Umgehung durch PowerShell 2.0 verhindern
Unabhängig davon, ob man sich für die Umgebungsvariable, AppLocker oder Application Control entscheidet, muss man in jedem Fall PowerShell 2.0 auf den Rechnern entfernen, auf denen man den Constrained Language Mode erzwingen will.
Dieser Sprachmodus wurde nämlich erst mit PowerShell 3.0 eingeführt und lässt sich von einem Angreifer leicht unterlaufen, indem er auf eine ältere Version wechselt. Dazu gibt man bloß
powershell.exe -version 2.0
ein. Ob diese alte Version auf einem PC noch aktiviert ist, kann man mit
Get-WindowsOptionalFeature -Online -FeatureName MicrosoftWindowsPowerShellV2
feststellen. Die Deinstallation funktioniert aber erst ab Windows 8 und Server 2012, wo PowerShell 2.0 als optionales Feature vorhanden ist.
Täglich Know-how für IT-Pros mit unserem Newsletter
Verwandte Beiträge
- Security- und Health-Checks für Active Directory mit PowerShell-Scripts
- PowerShell als Hacking-Tool: Missbrauch von Scripts verhindern
- Deep Scriptblock Logging: PowerShell-Kommandos im Eventlog aufzeichnen
- PowerShell-Logging: Befehle in Transcript-Datei aufzeichnen
- PowerShell-Scripts signieren mit Zertifikaten einer AD-Zertifizierungsstelle
Weitere Links
2 Kommentare
Hi,
Achtung: wenn das Vorgehen im Abschnitt "Constrained Language Mode über SRP aktivieren" umgesetzt wird wird u. a. auch das Ausführen von .EXE-Dateien im %temp%-Verzeichnis verhindert. Damit haben diverse Software Produkte Probleme bei Updates, auch TeamViewer in der Quick Support Variante kann nicht mehr ausgeführt werden. Das ist etwas übers Ziel hinaus geschossen.
LG
Timbo
Normalerweise sollten nur Admins Software installieren, und die kann man mit SRP ohnehin nicht davon abhalten, beliebige Programme auszuführen. Daher ist die beschriebene Maßnahme primär für Standardbenutzer gedacht, die generell keine .exe-Dateien in %temp% starten sollten.
Wenn man dort aber trotzdem das Ausführen von .exe-Dateien erlauben und gleichzeitig den Constrained Language Mode erzwingen möchte, dann kann man zusätzlich eine Regel für die betroffenen Programme mit der Sicherheitsstufe "Nicht eingeschränkt" definieren. Alternativ entfernt man einfach ".exe" bei den designierten Dateitypen. Aber ein Beitrag zu mehr Sicherheit ist das garantiert nicht.