PowerShell logging boosts security in the enterprise
Want to track any suspicious PowerShell activity across your network? Use these PowerShell logging techniques to curb potential threats that originate from scripts.
PowerShell gets a lot of bad publicity for being a very common tool for malware authors. Because of its deep integration with Windows and wide-ranging access to the operating system, PowerShell gives an attacker a number of ways to infiltrate and manipulate local and remote machines.
Some security experts have called to remove PowerShell from Windows or to reduce its capabilities, but that's not realistic. PowerShell is an indispensable tool for many system administrators and disabling its functionality would make management work much more difficult. By turning on PowerShell logging, enterprises can catch any suspicious scripting activity across the organization and learn from any security incidents that originated in PowerShell.
Types of PowerShell logging
There are three types of PowerShell logging: module, script block and transcription. You can configure the first two types as events in the Windows PowerShell event log. Transcription logs go to a text file.
Module logging keeps a record of pipeline execution events in PowerShell for specific modules. By default, modules in PowerShell do not log this, as you can see here:
To illustrate what is inside these logs, run Get-SmbConnection from the PowerShell console and then check the event logs on the local machine.
Figure 1. Event 4103 breaks down the specifics when running a PowerShell module.
Figure 1 shows the properties of event ID 4013 from this command. Event details include the parameters used with the command -- such as ThrottleLimit and AsJob -- and the hostname, PowerShell version, runspace ID and user who executed the command.
Setting up script block logging
Microsoft documentation calls a script block "a collection of statements or expressions that can be used as a single unit. A script block can accept arguments and return values." A simple way to show how a script block works is to use the Invoke-Command with the -ScriptBlock parameter:
Figure 2. The Invoke-Command cmdlet can use the -ScriptBlock parameter for more advanced PowerShell scripting.
Script block logging is one of the most useful aspects of PowerShell logging because it records obfuscated code to the event log. This is especially useful because the majority of PowerShell malware uses scrambled code to hide from IT teams.
Script block logging shows up in the event log as event ID 4104. Even without script block logging enabled, Windows still generates events that PowerShell flags as potentially malicious.
Figure 3 shows the result of a script block log generated using the following PowerShell command:
Invoke-Command -ScriptBlock {$a = "Variable";"This is a test $a"}
Figure 3. The Windows event log tracks script block logging with event ID 4104.
How to use transcription logging
PowerShell transcription logging writes any PowerShell commands and console output to a text file for analysis. Users start transcription logging manually with the Start-Transcript and Stop-Transcript commands in PowerShell or through a Group Policy/registry configuration.
A typical transcript file looks like this:
**********************
Windows PowerShell transcript start
Start time: 20180704143442
Username: VAGRANT-10\vagrant
RunAs User: VAGRANT-10\vagrant
Configuration Name:
Machine: VAGRANT-10 (Microsoft Windows NT 10.0.16299.0)
The transcript shows the user running the PowerShell session and other helpful information, such as the process ID, PowerShell version, commands executed and timestamps.
Centralize PowerShell logging with Group Policy
Group Policy makes it easy to configure PowerShell logging for multiple machines. You can find these policies in the Group Policy editor at the following location: Computer Configuration > Administrative Templates > Windows Components > Windows PowerShell
Here, you will see five settings: turn on module logging, turn on PowerShell script block logging, turn on script execution, turn on PowerShell transcription and set the default source path for Update-Help.
Administrators can use the Group Policy editor to start PowerShell logging on multiple machines.
You can enable all the PowerShell logging types and two others: script execution and default source for Update-Help.
The "Turn on PowerShell transcription" setting should interest administrators who want to configure a central location for transcription logs. This setting writes all logs locally, so you can copy them to a folder with PowerShell.
For instance, once you set up this PowerShell script to run on each local machine, it creates a folder named C:\Windows\PSLogging and gives the local Users group permission to write to the share. It also adds a domain security group called Security Admins with full control to manage the logs.
Use PowerShell to copy the contents of the previous day's transcript log folder from each machine listed in Active Directory into a central folder. You can set this up as a scheduled task to run at the start of each day using the following script:
Last words about the benefits of PowerShell logging
PowerShell logging is easy to set up and a good security practice to protect the enterprise. It just takes a few Group Policy changes to start logging PowerShell activity on all your machines.
If the time comes when a malware infection hits your organization via PowerShell, these logs can help determine the origin and assist with the effort to minimize further attacks. For added protection, admins should investigate the use of security tools such as ELK Stack that can help identify malicious activity.