PowerShell-Logging: Befehle in Transcript-Datei aufzeichnen

    PowerShell-Transcripts starten und stoppenUm dem Miss­brauch von PowerShell auf die Schliche zu kommen, kann man sämt­liche aus­geführte Komman­dos und Scripts mit­schneiden. Dafür exi­stieren zwei Mecha­nismen, einer davon schreibt alle Ein- und Aus­gaben in eine Datei. Es empfiehlt sich, die gesam­melten Daten an zentraler Stelle zusammen­zuführen.

    Die Form der Aufzeichnung, bei der PowerShell alle ver­arbeiteten Eingaben sowie den daraus resultierenden Output in einer Datei speichert, beschreibt Microsoft mit "Over-the-shoulder-Transcription". Was dabei mitge­schnitten wird, entspricht nämlich dem, was ein Beobachter sieht, wenn er dem Benutzer während seiner PowerShell-Session über die Schulter schaut.

    Aktivierung über Cmdlet

    Diese Variante gibt es bereits seit den Anfängen von PowerShell und ließ sich in der Vergangenheit nur explizit über die Cmdlets Start-Transcript und Stop-Transcript steuern. Um das Mitschneiden der Befehle automatisch zu aktivieren, musste man den Aufruf von Start-Transcript in das Profil von PowerShell aufnehmen.

    Das ist nicht nur umständlich, wenn man viele Rechner auf diese Weise konfigurieren muss, sondern dieses Verfahren lässt sich von einem Angreifer auch relativ leicht aushebeln. Nützlich kann der explizite Start und Stopp mittels Cmdlet für die Aufzeichnung aber sein, wenn man sie in eigene Scripts aufnimmt, um beobachten zu können, welche Ausgabe diese produzieren.

    Transcripts über GPO aktivieren

    Seit PowerShell 5 besteht die Möglichkeit, Transcripts mittels Gruppen­richtlinien einzuschalten. Die entsprechende Einstellung heißt PowerShell-Aufzeichnung aktivieren und findet sich unter Richtlinien => Administrative Vorlagen => Windows-Komponenten => Windows PowerShell.

    PowerShell-Transcripts über GPO aktivieren. Optional gibt man ein eigenes Verzeichnis an und aktiviert den Zeitstempel.

    Aktiviert man sie unter den beiden Zweigen (Computer- und Benutzer­konfiguration), dann setzt sich die Einstellung auf Computer-Ebene durch.

    Eigene Log-Datei für jede Session

    Standardmäßig legt das Feature für jeden Tag ein Verzeichnis im Profil des Benutzers an und schreibt dort die Einträge für jede Session in eine eigene Textdatei, deren Name aus "PowerShell_transcript" plus dem Hostname des Rechners sowie einer Zufallszahl besteht.

    Für jede Session auf jedem Rechner legt PowerShell eine eigene Log-Datei an.

    Es liegt natürlich nahe, die Aufzeichnungen zentral auf einem freige­gebenen Verzeichnis im Netz abzulegen. Das Cmdlet Start-Transcript bietet den Parameter OutputDirectory, um die Ausgabe vom Default-Verzeichnis auf ein anderes umzulenken. In der GPO-Einstellung für das Aktivieren der Transcripts findet sich für diesen Zweck ein eigenes Eingabefeld.

    Log-Verzeichnis schützen

    In der Regel wird man vermeiden wollen, dass Benutzer den Inhalt dieser Log-Dateien lesen oder gar verändern. Zum einen können sich darin sensible Informationen wie Passwörter befinden, zum anderen würde es das notwendige Schreibrecht einem Angreifer einfach machen, seine Spuren zu verwischen. Daher muss man verhindern, dass Benutzer sich die Dateien und ihren Inhalt anzeigen lassen.

    Zu diesem Zweck empfiehlt Microsoft, die NTFS-Rechte auf dem Fileshare restriktiv zu setzen.

    'Jeder' erhält nur die Rechte 'Lesen' und 'Schreiben'

    Konkret sollte man so vorgehen:

    • Vererbung für das konfigurierte Log-Verzeichnis deaktivieren, alle vorhandenen Berechtigungen entfernen
    • Administratoren erhalten vollen Zugriff
    • Jeder bekommt die Rechte Lesen und Schreiben
    • Ersteller-Besitzer werden alle Rechte entzogen

    Berechtigungen für das Log-Verzeichnis von PowerShell

    Eine weitere Option sowohl bei Start-Transcript als auch bei der GPO-Einstellung besteht darin, für jeden Aufruf einen Header mitzuschreiben. Dieser enthält einen Zeitstempel für den jeweiligen Befehl.

    Transcript mit Header und Zeitstempel für jeden Befehl

    Nimmt man diese Möglichkeit in Anspruch, dann erhöht sich das Volumen der aufgezeichneten Daten erheblich. Nachdem der Header in jeder Datei ohnehin detaillierte Angaben zur jeweiligen Session enthält, wird man normalerweise ohne die zusätzliche Zeitangabe für jede Aktion auskommen.

    GPO wirkt nicht für PowerShell Core

    Die administrative Vorlage PowerShellExecutionPolicy.admx schreibt nur die Registry-Werte für Windows PowerShell, so dass EnableTranscripting keine Auswirkung auf PowerShell Core bzw. PowerShell 7 hat.

    Registry-Eintrag, um Transcripts für PowerShell Core zu aktivieren

    Für diese Versionen muss man daher den erforderlichen Schlüssel in der Registrier­datenbank selbst setzen. Der folgende Inhalt für eine .reg-Datei zeigt, die Namen der beiden DWORD sowie den Pfad, in dem man sie erstellen muss.

    Will man diese Einstellungen auf einer größeren Zahl von Rechnern setzen, dann empfiehlt sich die Anpassung der Registry mit den Group Policy Preferences.

    5 Kommentare

    Bild von Martin
    Martin sagt:
    15. Juni 2019 - 9:06

    Vielen Dank für diesen Artikel. Mir stellt sich nur die Frage, warum "Jeder" auf dem Share Schreibrechte erhält, sollten Leserechte nicht ausreichen und stattdessen "System" Schreibrechte erhalten?

    Bild von Wolfgang Sommergut
    15. Juni 2019 - 13:15

    Falls PowerShell die Transcripts nicht unter dem User-, sondern dem Systemkonto schreibt, dann käme beim Zugriff auf das Fileshare über das Netzwerk der Computer-Account zum Einsatz. In diesem Fall würde statt "Jeder" die Gruppe "Domänencomputer" ausreichen.

    Bild von Martin
    Martin sagt:
    15. Juni 2019 - 13:22

    Vielen Dank! Bei "Jeder" erhält Schreibrechte kräuselt sich mir immer alles, selbst wenn es keine Sicherheitslücke darstellt.

    Bild von Ahmet Oktar
    Ahmet Oktar sagt:
    17. Juni 2019 - 14:27

    Hallo, vielen dank für die Anleitung, in der GPO steht auch ein Eintrag Skriptausführung aktivieren, wenn ich diesen auf deaktiviert setze, sollte die Gefahr eines Skript Trojaners doch gebannt sein oder ?

    Bild von Wolfgang Sommergut
    17. Juni 2019 - 14:59

    Grundsätzlich unterbindet man damit das Ausführen aller Scripts, auch der eigenen. Aber eine hundertprozentige Sicherheit erreicht man dadurch nicht. Siehe dazu meinen Beitrag zur Execution Policy.