Tags: Log-Management, Verschlüsselung, PowerShell
Ein neues Feature von Windows 10 und Server 2016 ist Protected Event Logging, das sensible Daten im Eventlog verschlüsselt. Es nutzt den offenen Standard Cryptographic Message Syntax (CMS), den PowerShell mit eigenen Cmdlets unterstützt. Damit lassen sich neben Log-Einträgen auch Dateien ver- bzw. entschlüsseln.
Auf den ersten Blick mag man sich fragen, warum man die Log-Files von Windows verschlüsseln sollte. Den Anstoß für dieses Feature gab die Einführung von Scriptblock Logging in PowerShell 5, das alle eingegebenen Kommandos im Eventlog speichert. Darunter können sich auch Zugangsdaten 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 systemweites Feature, das von allen Anwendungen und Windows-Diensten genutzt werden kann. Wenn man es unter Windows 10 aktiviert, dann ist aber aktuell PowerShell der einzige Anwender dieser Verschlüsselung.
Um das sichere Logging von Ereignissen einzuschalten, sieht Microsoft eine Einstellung in den Gruppenrichtlinien vor. Sie heißt Geschützte Ereignisprotokollierung aktivieren und findet sich unter Computerkonfiguration => Richtlinien => Administrative Vorlagen => Windows-Komponenten => Ereignisprotokollierung.
Voraussetzung, um diese Einstellung erfolgreich aktivieren zu können, ist ein Zertifikat, das speziell für die Dokumentenverschlüsselung ausgestellt wurde. Mit dessen öffentlichem Schlüssel werden dann die Log-Einträge kodiert. Der Editor akzeptiert mehrere Möglichkeiten, 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 Fingerabdruck. 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 Ereignisanzeige fehlen allerdings die notwendigen Funktionen, um mit Hilfe des privaten Schlüssels die Logs zu dekodieren.
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:
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 Befehlssequenzen 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 ihn zuvor als Base64 aufbereiten.
Anwendungsgebiete können auch hier sein, sensible Daten in Scripts oder Passwortdateien 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 Betriebssystemen.
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.
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 Zeichenkodierung von Dateien, ansonsten wird man sich über ein entstelltes Ergebnis nach der Entschlüsselung wundern. Das ist etwa beim folgenden Vorgehen der Fall:
Um solche unerwü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
Bei dieser Variante kann man sich die entsprechenden Fähigkeiten von Get-Content zunutze machen.
Täglich Know-how für IT-Pros mit unserem Newsletter
Ähnliche Beiträge
- AD-Konten mit DES- und RC4-Algorithmus für Kerberos-Verschlüsselung finden
- PowerShell SecretManagement: Passwörter in KeePass oder SecretStore verwalten
- Invoke-WebRequest: Es konnte kein geschützter SSL/TLS-Kanal erstellt werden
- Deep Scriptblock Logging: PowerShell-Kommandos im Eventlog aufzeichnen
- PowerShell-Logging: Befehle in Transcript-Datei aufzeichnen
Weitere Links