In general, misses can occur for several reasons, although in our experience, misses mostly stem from incorrect/empty PowerShell logs or merely a lack of logging required for advanced detection.
Many of us worry that, even though we have everything in place, we are still missing those key events (and yes, we acknowledge that we should never rely on any single event). No SIEM/SOAR platform is a "set it and forget it" tool, so the platforms generating logs should be reviewed frequently to ensure valid logging is in place. Just like we can use GPO to craft good, formal audit logging or use robust audit functionality in Linux, we can take this a step further and force logging in PowerShell.
When any account initiates PowerShell, there may or may not be a measure of logging occurring. However, there is also the potential for accounts to turn off logging, which goes back to our fear of missing something. The most disturbing element of PowerShell is that it can be used to do just about anything without the need to run other programs. This means that in the hands of an attacker, it provides an incredibly powerful ability to own, control, and manipulate a system without installing malware or doing anything else noticeable. Thus, unless you monitor inside of PowerShell, you are likely to miss what's happening.
This allows PowerShell to detect those key events and to audit any commands issued. Below are simple step-by-step instructions for domain administrators to push out a policy that forces any system in the domain to log all PowerShell activity. This can then be logged via Audit Policy. After describing the Domain/GPO steps, we detail how to force-enable this program on your local machines, including how to enable transcription.
When there is no evidence of action, there is a high likelihood of missing or failing to detect that event that would trigger an investigation. However, we can easily crank up the bare measures into fully recorded histories of how PowerShell was invoked, by which account, and what commands were issued, regardless of the command result.
Run ‚Äògpedit.msc' and navigate to Computer Configuration – Administrative Templates – Windows Components – Windows PowerShell:
We are focusing on these two items at a minimum:
It is important to note that you MUST enter something here. For efficacy, I chose an asterisk (*), essentially saying all modules. However, in the local version, we explicitly forced this using a few specified values. One reason behind choosing an asterisk is that some future applications might use PowerShell in a way we don't expect, or a new module may be added. For this reason, we chose "anything" for safety' sake. This is also key for PCI and HIPAA auditing.
The point is, you can log everything or just some things, depending on your goals. If you are curious about all the modules available to log, run this from an elevated PS shell window: ‘Get-Module -ListAvailable | Select Name'.
Here are just some options that were chosen:
Note that in GPO, you edit this in a policy that is deployed to all systems, not just domain controllers or some platforms.
We still use gpedit.msc. Just note that it pulls up a local version for you to force this change to your system.
Navigate to Computer Configuration – Administrative Templates – Windows Components – Windows PowerShell:
I am using custom options of some interest to me. Remember, however, that an asterisk (*) is a smarter choice.
And, of course, you have to test it to determine if you have logs.
I am going to take it a step further and actually log ANYTHING written in any PS shell. Remember to subscribe or pull these logs as they will not be in your normal PowerShell Event Channel.
When you are collecting your logs, PowerShell is an event channel you can easily define in your collection tool of choice, and it will likely be parsed in a similar fashion to system and security logs.
Transcription logs aren't really meant to go to the SIEM, as they are not likely to be readily parsed and reside in a non-standard location and format from regular Windows Event Channel logs. This doesn't mean, however, that I don't want to collect them! Using a SOAR platform, I might have after-detection responses that include reaching down for all recent transcription logs or even using a frequent task scheduler that moves them to an off-system location for storage and audit review. Regardless of which path you choose, we do recommend retrieving and storing transcription logs. At some point in the future, we will share our results around collecting these with Wazuh or Elastic and how we retrieve them for forensics with Exabeam or Alienvault.
Please feel free to contact us with any questions, concerns, or corrections.