Latest posts by Wolfgang Sommergut (see all)
- Group Policies in Windows 10 1909: ADMX download, three new GPO settings - Wed, Nov 27 2019
- Encrypt event logs and files with PowerShell and group policies - Mon, Nov 25 2019
- Issuing certificates for document encryption (Cryptographic Message Syntax) - Thu, Nov 21 2019
You may wonder why you should encrypt Windows log files. This feature was triggered by the introduction of Scriptblock Logging in PowerShell 5, which stores all entered commands in the event log. These commands may also include credentials, which should not be visible to unauthorized persons.
Activation via group policies ^
Basically, Protected Event Logging is a system-wide feature that can be used by all applications and Windows services. If you activate it under Windows 10, PowerShell is currently the only user of this encryption.
To enable secure event logging, Microsoft provides a setting in Group Policy. It is called Enable Protected Event Logging and can be found under Computer Configuration > Policies > Administrative Templates > Windows Components > Event Logging.
To successfully activate this setting, a certificate specifically issued for document encryption [[hier der Link zum Text über das Ausstellen von Zertifikaten für die Dokumentverschlüsselung]] is required. Its public key is used to encode the log entries. The GPO editor accepts several ways to link the policy to the certificate.
You can store it on a file share and specify its path. If the certificate is available in the store of the local computer, the user's fingerprint will also suffice. A simple method is to export the certificate in Base64 encoded form, the contents of which can simply be copied into the text field.
Decrypting logs with PowerShell ^
Once the GPO is in effect, you can no longer read the event log history of the PowerShell commands entered on those machines. However, the Event Viewer lacks the necessary functions to decode the logs using the private key.
Therefore, you must make these log entries readable with PowerShell. The Unprotect-CmsMessage cmdlet, the opposite of Protect-CmsMessage, decrypts them.
For example, if you want to decipher the latest entry in the PowerShell log, you could retrieve it via Get-WinEvent and pipe it to Unprotect-CmsMessage:
$msg = Get-WinEvent Microsoft-Windows-PowerShell/Operational `
-ComputerName myPC -MaxEvents 2 -Credential domain\user
"Last log entry as clear text:"
$msg | select -ExpandProperty Message | Unprotect-CmsMessage
# $msg is always "prompt"
A complete script for this purpose can be found on Emin Atac's blog.
The problem with script block logging is that longer command sequences are split across multiple log entries. Therefore, in this case you would have to aggregate the individual sections and then pass them to Unprotect-CmsMessage.
Encrypting files ^
Protect-CmsMessage can also be used to encrypt any file. If their contents are binary, then you should convert to a Base64 representation first.
Usage scenarios here may also include protecting sensitive data in scripts or password files against unauthorized access. However, this technology is certainly not intended as an alternative to an encrypting file system or even a Bitlocker.
Because PowerShell uses the cryptographic message syntax standard, you can decrypt encoded files using other tools on different platforms, such as OpenSSL on Linux. Therefore, this PowerShell feature is also suitable for exchanging confidential data between different operating systems.
The process is relatively simple. Protect-CmsMessage expects the input file via the Path parameter. Alternatively, you can provide the contents to be encrypted via the Content parameter or via a pipeline. The target file is specified via OutFile; otherwise, the output is stdout.
Other required information includes the certificate you want to use. The To parameter, which accepts the fingerprint, subject name, or path to a certificate, serves this purpose.
Conversely, Unprotect-CmsMessage only needs the content for decryption (via Content or Path); passing it via a pipe is also possible. The To parameter can be omitted if the certificate is in the local store.
Problems with the character set ^
Watch out for the character encoding of files. Otherwise, you will be surprised by a distorted result after decryption. This is the case, for example, with the following procedure:
Get-Process > process.txt
Protect-CmsMessage -Path process.txt -out process.enc -To 61F4C2FFF9CC…
Unprotect-CmsMessage -Path process.enc
To avoid such unwanted effects, save the output using:
Get-Process | Out-File -FilePath process.txt -Encoding utf8
If you prefer the first variant with redirection to a file, then you must convert the content to the correct character set when it is read for encryption:
Get-Content -Raw -Encoding UTF8 process.txt |
Protect-CmsMessage -To "CN=Max Mustermann" -out .\process.enc
With this variant, you can take advantage of the appropriate features of Get-Content.