Zum Inhalt springen
09 · PowerShell-SicherheitTeil 1 von 4Fortgeschritten

PowerShell-Sicherheit: Logging, v2-Entfernung, CLM und JEA

PowerShell transparent und begrenzt machen: Skriptblock-, Modul- und Transkriptionsprotokollierung, PowerShell 2.0 entfernen, CLM per App Control, dazu JEA.

Florian Amette6 Min. Lesezeit

PowerShell ist die Verwaltungsschicht von Windows und ein Lieblingswerkzeug von Angreifern, weil es überall vorhanden ist, Code aus dem Speicher ausführt und fast jede API erreicht. Der Versuch, es zu blockieren, bricht meist Management-Werkzeuge, während motivierte Angreifer andere Hosts für die Engine finden. Der dauerhafte Ansatz ist ein anderer: jede PowerShell-Aktion sichtbar machen und die für nicht vertrauenswürdigen Code verfügbare Sprache einschränken.

1. Skriptblockprotokollierung

Die Skriptblockprotokollierung zeichnet den Inhalt jedes Skriptblocks auf, den PowerShell verarbeitet, und zwar nach der Entschleierung. Genau das hebelt die meisten codierten und verschleierten Payloads aus.

  • GPO: Computer Configuration > Administrative Templates > Windows Components > Windows PowerShell > Turn on PowerShell Script Block Logging = Enabled. Log script block invocation start / stop events nicht aktivieren (sehr laut).
  • Registrierung: HKLM\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging EnableScriptBlockLogging = 1.
  • Ereignisse: 4104 in Applications and Services Logs > Microsoft > Windows > PowerShell > Operational. Lange Skripte werden auf mehrere 4104-Ereignisse aufgeteilt, die über eine Skriptblock-ID verknüpft sind.

Auch ohne diese Richtlinie protokolliert PowerShell 5 Skriptblöcke, die es für verdächtig hält, automatisch als 4104-Ereignisse der Stufe Warnung. Die Richtlinie macht die Protokollierung vollständig.

2. Modulprotokollierung

Die Modulprotokollierung zeichnet Details der Pipeline-Ausführung einschließlich Parameterwerten für die gewählten Module auf.

  • GPO: Turn on Module Logging = Enabled, Modulnamen * (alle Module).
  • Ereignisse: 4103 im selben Protokoll.

Sie überschneidet sich mit der Skriptblockprotokollierung, erfasst aber Laufzeitwerte (etwa in einen Befehl expandierte Variablen), die der Skripttext allein nicht zeigt.

3. Transkription

Die Transkription schreibt einen Textmitschnitt der Ein- und Ausgaben jeder Sitzung in Dateien, praktisch für die Überprüfung interaktiver Admin-Tätigkeiten.

  • GPO: Turn on PowerShell Transcription = Enabled, Ausgabeverzeichnis eine nur beschreibbare Netzwerkfreigabe (zum Beispiel \\logsrv\pstranscripts$), Include invocation headers aktiviert.
  • Freigabeberechtigungen: Computer und Benutzer dürfen Dateien anlegen und schreiben, aber die Transkripte anderer weder lesen noch auflisten; nur das Sicherheitsteam darf lesen.

Behandeln Sie Transkripte und Skriptblockprotokolle als sensibel: Admins fügen manchmal Kennwörter in Konsolen ein. Ist dieses Risiko erheblich, verschlüsselt Protected Event Logging (Administrative Templates > Windows Components > Event Logging > Enable Protected Event Logging) den Inhalt des Ereignisprotokolls mit einem Zertifikat, sodass nur Ihr SIEM (mit dem privaten Schlüssel) ihn lesen kann.

4. Protokolle dimensionieren und weiterleiten

Das standardmäßige PowerShell-Operational-Protokoll ist klein und wird auf einem ausgelasteten Server binnen Stunden überschrieben. Vergrößern Sie es und leiten Sie es weiter:

PowerShell
wevtutil sl "Microsoft-Windows-PowerShell/Operational" /ms:268435456   # 256 MB

Leiten Sie 4103 und 4104 (sowie 400/403 aus dem klassischen Protokoll Windows PowerShell, die Start und Stopp der Engine mit der Hostversion festhalten) über Windows Event Forwarding oder Ihren Agent weiter. Siehe den Leitfaden zu Überwachungsrichtlinie und Sysmon.

5. PowerShell 2.0 entfernen

Die PowerShell-2.0-Engine ist älter als Skriptblockprotokollierung, AMSI und Constrained Language Mode. Ist sie installiert, kann ein Angreifer powershell.exe -Version 2 ausführen und all das oben Genannte umgehen. Sie hängt außerdem von .NET Framework 3.5 ab, das oft vorhanden ist.

PowerShell
Get-WindowsOptionalFeature -Online -FeatureName MicrosoftWindowsPowerShellV2Root
Disable-WindowsOptionalFeature -Online -FeatureName MicrosoftWindowsPowerShellV2Root -NoRestart
# Windows Server
Uninstall-WindowsFeature PowerShell-V2

Microsoft hat PowerShell 2.0 aus Windows 11 24H2 mit den Updates vom August 2025 und aus Windows Server 2025 ab September 2025 entfernt; ältere Versionen und Images enthalten es noch. Erkennen Sie Downgrade-Versuche über das Ereignis 400 im Protokoll Windows PowerShell, bei dem EngineVersion den Wert 2.0 hat.

6. AMSI

Das Antimalware Scan Interface ermöglicht PowerShell (sowie VBScript, JScript, Office VBA und anderen), Skriptinhalte vor der Ausführung an den Virenschutz zu übergeben, ebenfalls nach der Entschleierung. Mit Microsoft Defender oder jedem AMSI-fähigen Virenschutz ist es standardmäßig aktiv. Ihre Aufgabe ist es, dass das so bleibt:

  • Plattform- und Engine-Updates von Defender aktuell halten.
  • Bei Erkennungen, die AMSI-Umgehungsversuche erwähnen, und bei PowerShell-Ereignissen mit bekannten Umgehungsmustern alarmieren (zum Beispiel Verweise auf AmsiUtils oder amsiInitFailed).

7. Constrained Language Mode, richtig erzwungen

Constrained Language Mode (CLM) entfernt die Teile der Sprache, auf die Angreifer angewiesen sind: beliebige .NET-Typen, Add-Type, COM-Objekte außerhalb einer Zulassungsliste und direkte Win32-API-Aufrufe. Die Kern-Cmdlets funktionieren weiter, sodass die meisten Admin-Skripte, die nur Windows verwalten, problemlos laufen.

Den aktuellen Modus prüfen:

PowerShell
$ExecutionContext.SessionState.LanguageMode

Der einzige robuste Weg, CLM zu erzwingen, ist die Anwendungssteuerung. Wenn eine Skriptrichtlinie von App Control for Business (WDAC) oder AppLocker erzwungen wird, gilt in PowerShell automatisch:

  • Interaktive Sitzungen und Skripte, die die Richtlinie nicht zulässt, laufen im Constrained Language Mode;
  • Skripte, die die Richtlinie zulässt (zum Beispiel mit Ihrem internen Codesignaturzertifikat signierte), laufen im Full Language Mode.

Manchmal wird als Abkürzung vorgeschlagen, die Umgebungsvariable __PSLockdownPolicy auf 4 zu setzen. Das ist keine Sicherheitsgrenze: Ein Benutzer kann sie entfernen. Verwenden Sie sie nur im Labor, um die Skriptkompatibilität zu testen.

Signieren Sie Ihre Admin-Skripte mit einem internen Codesignaturzertifikat, damit sie unter der Richtlinie den vollen Sprachumfang behalten:

PowerShell
$cert = Get-ChildItem Cert:\CurrentUser\My -CodeSigningCert | Select-Object -First 1
Set-AuthenticodeSignature -FilePath .\Invoke-Maintenance.ps1 -Certificate $cert `
  -TimestampServer "http://timestamp.digicert.com"

Wie Sie die Richtlinie selbst aufbauen, zeigt App Control vs. AppLocker.

8. Just Enough Administration (JEA)

Viele Helpdesk- und Operator-Aufgaben brauchen keine vollständige Admin-Sitzung. JEA stellt einen PowerShell-Remoting-Endpunkt bereit, an dem Benutzer nur bestimmte Befehle ausführen können, und zwar als temporäres virtuelles Konto mit den nötigen Rechten, wobei jeder Befehl transkribiert wird.

Ein minimales Beispiel: Operatoren dürfen auf einem Server einen Dienst neu starten und seinen Status lesen.

PowerShell
# Rollenfunktion: was die Rolle darf
New-PSRoleCapabilityFile -Path "C:\Program Files\WindowsPowerShell\Modules\OpsJEA\RoleCapabilities\PrintOps.psrc" `
  -VisibleCmdlets @{ Name = 'Restart-Service'; Parameters = @{ Name = 'Name'; ValidateSet = 'Spooler' } },
                  'Get-Service'

# Sitzungskonfiguration: wer welche Rolle erhält, Ausführung als virtuelles Konto
New-PSSessionConfigurationFile -Path .\PrintOps.pssc -SessionType RestrictedRemoteServer `
  -RunAsVirtualAccount -TranscriptDirectory "C:\ProgramData\JEA\Transcripts" `
  -RoleDefinitions @{ 'CORP\Print-Operators' = @{ RoleCapabilities = 'PrintOps' } }

Register-PSSessionConfiguration -Name PrintOps -Path .\PrintOps.pssc

Benutzer verbinden sich mit Enter-PSSession -ComputerName srv01 -ConfigurationName PrintOps und erhalten genau diese zwei Befehle. Achten Sie darauf, welche Cmdlets Sie freigeben: Alles, was beliebigen Code ausführen (Invoke-Expression, Start-Process ohne Einschränkungen, Add-Type) oder Dateien in beliebige Pfade schreiben kann, macht den Endpunkt wieder zum vollen Admin-Zugang.

9. WinRM selbst

  • Lassen Sie WinRM nur dort lauschen, wo es gebraucht wird, und begrenzen Sie es per Firewall auf Managementhosts (Firewall-Leitfaden).
  • Basic-Authentifizierung und unverschlüsselten Verkehr verbieten (Windows Components > Windows Remote Management (WinRM) > WinRM Service / Client: Allow Basic authentication = Disabled, Allow unencrypted traffic = Disabled). Das sind die Standardwerte; die Baselines erzwingen sie, damit sie nicht abdriften.
  • Allow CredSSP authentication deaktivieren, sofern kein bestimmter Arbeitsablauf es braucht; CredSSP sendet wiederverwendbare Anmeldedaten an den Remotehost.

Checkliste

  • Skriptblockprotokollierung (4104) und Modulprotokollierung (4103) überall aktiv
  • Transkription auf eine nur beschreibbare Freigabe oder Protected Event Logging, wo sensibel
  • PowerShell-Operational-Protokoll mit 256 MB oder mehr, weitergeleitet
  • PowerShell 2.0 entfernt; Alarm bei Ereignis 400 mit EngineVersion 2.0
  • CLM per App Control / AppLocker erzwungen; Admin-Skripte signiert
  • JEA-Endpunkte für delegierte Betriebsaufgaben
  • WinRM: kein Basic, kein unverschlüsselter Verkehr, kein CredSSP, per Firewall begrenzt
  • PowerShell-7-Richtlinien konfiguriert, falls PowerShell 7 installiert ist

Damit bleibt PowerShell für Administratoren voll nutzbar, während die PowerShell eines Angreifers im Klartext protokolliert und der Funktionen beraubt wird, die seine Werkzeuge brauchen.

Häufige Fragen

Sollte ich powershell.exe blockieren?

In der Regel nicht. Das Blockieren der ausführbaren Datei bricht Administration und Management-Agents, und Angreifer können die PowerShell-Engine in anderen Prozessen hosten. Sie gründlich zu protokollieren und den Constrained Language Mode per Anwendungssteuerung zu erzwingen, ist weitaus wirksamer.

Ist die Ausführungsrichtlinie eine Sicherheitsmaßnahme?

Nein. Microsoft dokumentiert die Ausführungsrichtlinie als Schutzfunktion gegen versehentliches Ausführen von Skripten, nicht als Sicherheitsgrenze. Sie lässt sich trivial umgehen, zum Beispiel mit -ExecutionPolicy Bypass. Nutzen Sie sie, aber verlassen Sie sich nicht darauf.

Gelten diese Einstellungen auch für PowerShell 7?

PowerShell 7 hat eigene Richtlinieneinstellungen (in den mit PowerShell 7 ausgelieferten administrativen Vorlagen für PowerShell Core oder in einer powershell.config.json). Es lässt sich so konfigurieren, dass es die Richtlinieneinstellungen von Windows PowerShell übernimmt. Konfigurieren Sie beides, wenn PowerShell 7 bereitgestellt ist.

PowerShell-Sicherheit: Logging, v2-Entfernung, CLM und JEA

Verwandte Leitfäden

Windows-Firewall

Windows-Firewall: Protokollierung und Überwachung

Die Windows-Firewall als Erkennungsquelle: pfirewall.log konfigurieren, WFP-Ereignisse 5156/5157 und Regeländerungen 4946-4950 überwachen und zentral weiterleiten.

Grundlagen