PowerShell-Skriptblockprotokollierung (4104): Ein Forensik-Leitfaden
Was Ereignis-ID 4104 aufzeichnet, wie Windows lange Skriptblöcke auf mehrere Ereignisse verteilt, warum Blöcke auf Warnstufe auch ohne vollständige Protokollierung erscheinen und wie man sie in einem Fall auswertet.
Kurzfassung. Die Skriptblockprotokollierung zeichnet den Code, den PowerShell tatsächlich ausgeführt hat, in Ereignis-ID 4104 innerhalb von Microsoft-Windows-PowerShell/Operational auf. Sie erfasst den deobfuskierten Text, sodass ein -EncodedCommand oder ein verketteter Einzeiler in aufgelöster Form gespeichert wird. Lange Blöcke werden auf mehrere 4104-Ereignisse verteilt, die sich eine ScriptBlockId teilen; setzen Sie sie anhand von MessageNumber/MessageTotal wieder zusammen. Selbst bei deaktivierter Richtlinie protokolliert Windows verdächtige Blöcke auf Warnstufe. Öffnen Sie den Parser, um sie in Ihrem Browser zusammenzusetzen und zu dekodieren.
Was 4104 aufzeichnet
Die Skriptblockprotokollierung wurde mit PowerShell 5.0 (Windows 10 / WMF 5.0) eingeführt. Ist sie aktiviert, schreibt die Engine den Quelltext jedes kompilierten Skriptblocks in Ereignis-ID 4104. Microsoft dokumentiert, dass sie Codeblöcke während ihrer Ausführung aufzeichnet und dass dies nach der Deobfuskation geschieht – damit werden die meisten Kodierungs- und Zeichenkettentricks ausgehebelt (Microsoft: about_Logging_Windows, PowerShell ❤ the Blue Team).
Jedes 4104-Ereignis enthält diese EventData-Felder:
| Feld | Bedeutung |
|---|---|
ScriptBlockText | Der Code dieses Teils des Blocks |
ScriptBlockId | Eine GUID, die alle Teile eines Blocks gemeinsam haben |
MessageNumber / MessageTotal | Dieser Teil n von N |
Path | Die Skriptdatei, sofern der Block aus einer .ps1 stammt |
Einen aufgeteilten Block zusammensetzen
Das Windows-Ereignisprotokoll begrenzt die Größe eines einzelnen Ereignisses, daher zerlegt PowerShell einen langen Block in mehrere 4104-Ereignisse. Alle tragen dieselbe ScriptBlockId und sind als MessageNumber von MessageTotal nummeriert. Um das Skript wiederherzustellen, gruppieren Sie nach ScriptBlockId, sortieren nach MessageNumber und verketten den ScriptBlockText. Fehlt ein Teil – weil er aus einem überlaufenden Protokoll herausgerollt ist oder nie gesichert wurde –, hat die Rekonstruktion eine Lücke, und jede Interpretation des Codes muss dies berücksichtigen. Der PowerShell Parser übernimmt diese Gruppierung für Sie und markiert Blöcke mit fehlendem Teil. Siehe Ereignis-ID 4104 und Skriptblockprotokollierung im Glossar.
Blöcke auf Warnstufe ohne Richtlinie
Auch wenn die Richtlinie zur Skriptblockprotokollierung nicht gesetzt ist, protokolliert PowerShell 5 weiterhin Skriptblöcke, deren Inhalt einer internen Liste verdächtiger Begriffe entspricht – auf Warnstufe (Level 3) statt Verbose. Das bedeutet, dass eine Umgebung „ohne Protokollierung“ oft dennoch einen Teilnachweis der interessantesten Aktivitäten enthält (Lee Holmes). Der Parser markiert diese Blöcke auf Warnstufe, damit Sie sie nicht für harmlos halten.
Was Sie damit tun
Werten Sie 4104 zusammen mit dem klassischen Windows-PowerShell-Protokoll und den übrigen Ereignis-IDs aus, dekodieren Sie jeden kodierten Befehl und gleichen Sie die Ergebnisse mit dem PSReadLine-Verlauf und den Transkripten ab. Um einen Ordner mit .evtx-Dateien ohne Installation in eine durchsuchbare, dekodierte Zeitleiste zu verwandeln, analysieren Sie sie im Browser.
FAQ
Was ist Ereignis-ID 4104?
Es ist das Ereignis der Skriptblockprotokollierung im Protokoll Microsoft-Windows-PowerShell/Operational. Jedes 4104-Ereignis zeichnet einen Block PowerShell-Code so auf, wie die Engine ihn kompiliert hat – nachdem ein -EncodedCommand oder eine Zeichenketten-Obfuskation bereits aufgelöst wurde.
Warum sehe ich 4104-Ereignisse auf Warnstufe, obwohl die Skriptblockprotokollierung deaktiviert ist?
PowerShell 5 protokolliert Skriptblöcke, die als verdächtig eingestufte Begriffe enthalten, automatisch auf Warnstufe – selbst wenn die Richtlinie zur Skriptblockprotokollierung deaktiviert ist. Die vollständige Protokollierung jedes Blocks auf Stufe Verbose erfordert die Richtlinie.
Wie werden lange Skripte gespeichert?
Ein langer Skriptblock wird auf mehrere 4104-Ereignisse verteilt, die sich eine ScriptBlockId teilen; jedes trägt MessageNumber von MessageTotal. Setzen Sie sie in der richtigen Reihenfolge zusammen, um den vollständigen Text wiederherzustellen.