Log-Einträge und Dateien verschlüsseln mit PowerShell und GPO

    Daten verschlüsselnEin neues Feature von Windows 10 und Server 2016 ist Protected Event Logging, das sen­sible Daten im Eventlog ver­schlüsselt. Es nutzt den offenen Standard Crypto­graphic Message Syntax (CMS), den Power­Shell mit eigenen Cmdlets unter­stützt. Damit lassen sich neben Log-Ein­trägen auch Dateien ver- bzw. ent­schlüsseln.

    Auf den ersten Blick mag man sich fragen, warum man die Log-Files von Windows ver­schlüsseln sollte. Den Anstoß für dieses Feature gab die Einführung von Scriptblock Logging in PowerShell 5, das alle einge­gebenen Kommandos im Eventlog speichert. Darunter können sich auch Zugangs­daten befinden, und diese sollten für Unbefugte nicht ohne Weiteres sichtbar sein.

    Aktivierung über Gruppenrichtlinien

    Grundsätzlich handelt es sich bei Protected Event Logging um ein system­weites Feature, das von allen Anwen­dungen und Windows-Diensten genutzt werden kann. Wenn man es unter Windows 10 aktiviert, dann ist aber aktuell PowerShell der einzige Anwender dieser Ver­schlüsselung.

    Um das sichere Logging von Ereignissen zu einzuschalten, sieht Microsoft eine Einstellung in den Gruppen­richtlinien vor. Sie heißt Geschützte Ereignisprotokollierung aktivieren und findet sich unter Computerkonfiguration => Richtlinien => Administrative Vorlagen => Windows-Komponenten => Ereignis­protokollierung.

    Die Verschlüsselung von PowerShell-Einträgen im Event-Log aktiviert man über Gruppenrichtlinien.

    Voraus­setzung, um diese Einstellung erfolgreich aktivieren zu können, ist ein Zertifikat, das speziell für die Dokumenten­ver­schlüsselung ausgestellt wurde. Mit dessen öffentlichem Schlüssel werden dann die Log-Einträge kodiert. Der Editor akzeptiert mehrere Möglich­keiten, um das GPO mit dem Zertifikat zu verknüpfen.

    So kann man dieses auf einem File-Share ablegen und den Pfad dorthin angeben. Wenn das Zertifikat im Store des lokalen Computers vorhanden ist, reicht auch der Finger­abdruck. Als unkomplizierte Methode erweist sich das Exportieren des Zertifikats in Base64-kodierter Form, dessen Inhalt man dann einfach in das Textfeld kopiert.

    Entschlüsseln der Logs mit PowerShell

    Sobald das GPO wirksam ist, kann man die Historie der eingegeben PowerShell-Befehle auf den betreffenden Rechnern nicht mehr lesen. Der Ereignis­anzeige fehlen allerdings die notwendigen Funktionen, um mit Hilfe des privaten Schlüssels die Logs zu dekodieren.

    Die Ereignisanzeige präsentiert nur die verschlüsselten Einträge, dekodieren kann es sie nicht.

    Daher muss man für das Entschlüsseln diese Log-Einträge mit PowerShell in eine lesbare Form bringen. Diesem Zweck dient das Cmdlet Unprotect-CmsMessage, dem Gegenspieler von Protect-CmsMessage.

    Möchte man zum Beispiel den neuesten Eintrag im PowerShell-Log entziffern, dann könnte man diesen über Get-WinEvent abrufen und über eine Pipe an Unprotect-CmsMessage übergeben:

    Entschlüsselung von PowerShell-Logs mit Unprotect-CmsMessage

    Ein vollständiges Script für diesen Zweck findet sich auf dem Blog von Emin Atac.

    Das Problem beim Scriptblock Logging besteht darin, dass längere Befehls­sequenzen auf mehrere Log-Einträge aufgeteilt werden. Daher müsste man in diesem Fall die einzelnen Abschnitte so aggregieren wie hier beschrieben und anschließend an Unprotect-CmsMessage übergeben.

    Dateien verschlüsseln

    Protect-CmsMessage kann man auch verwenden, um beliebige Dateien zu verschlüsseln. Ist ihr Inhalt binär, dann sollte man in zuvor als Base64 aufbereiten.

    Anwendungs­gebiete können auch hier sein, sensible Daten in Scripts oder Passwort­dateien gegen unbefugten Zugriff zu schützen. Gedacht ist diese Technik aber sicher nicht als Alternative zu einem verschlüsselnden Dateisystem oder gar Bitlocker.

    Nachdem PowerShell den Standard Cryptographic Message Syntax verwendet, besteht ein Vorteil dieser Verschlüsselung darin, dass man kodierte Dateien mit alternativen Tools auf anderen Plattformen entschlüsseln kann, etwa mit OpenSSL unter Linux. Daher eignet sich dieses PowerShell-Feature auch für den Austausch vertraulicher Daten zwischen verschiedenen Betriebs­systemen.

    Grundsätzlich ist der gesamte Vorgang relativ einfach. Protect-CmsMessage erwartet über den Parameter Path die Eingabedatei, alternativ kann man den zu verschlüsselnden Inhalt über den Parameter Content oder über eine Pipeline bereitstellen. Die Zieldatei spezifiziert man über OutFile, ansonsten erfolgt die Ausgabe auf stdout.

    Einfache Anwendung von Protect-CmsMessage und Unprotect-CmsMessage

    Als weitere Information erforderlich ist das Zertifikat, welches man benutzen möchte. Diesem Zweck dient der Parameter To, der den Fingerabdruck, den Subject Name oder den Pfad zu einem Zertifikat akzeptiert.

    Umgekehrt benötigt Unprotect-CmsMessage nur den Inhalt zum Entschlüsseln (über Content oder Path), auch ein Weiterleiten über eine Pipe ist möglich. Den Parameter To kann man auslassen, wenn sich das Zertifikat im lokalen Speicher befindet.

    Probleme durch den Zeichensatz

    Aufpassen sollte man auf die Zeichen­kodierung von Dateien, ansonsten wird man sich über ein entstelltes Ergebnis nach der Entschlüsselung wundern. Das ist etwa beim folgenden Vorgehen der Fall:

    Falsche Zeichenkodierung zerstört den Inhalt während der Ver- und Entschlüsselung.

    Um solche uner­wünschten Effekte zu vermeiden, speichert man den Output mit

    Get-Process | Out-File -FilePath process.txt -Encoding utf8

    Falls man bei der ersten Variante mit der Umleitung in eine Datei bleibt, dann sollte man diese spätestens beim Einlesen für die Verschlüsselung auf den richtigen Zeichensatz konvertieren:

    Get-Content -Raw -Encoding UTF8 process.txt |
    Protect-CmsMessage -To "CN=Max Mustermann" -out .\process.enc

    Korrekte Wiederherstellung der verschlüsselten Daten bei Verwendung von UTF-8

    Bei dieser Variante kann man sich die entsprechenden Fähigkeiten von Get-Content zunutze machen.

    Keine Kommentare