Disclaimer: Due to changes in the MSFT corporate blogging policy, I’m moving all of my content to the following location. Please reference all future content from that location. Thanks.
Note that there is an addendum to this piece for override purposes. That can be found here.
A colleague of mine turned me on to this particular article on ways to use PowerShell to bypass execution policies. It’s worth noting that PowerShell is a powerful tool that was designed to give a lot of flexibility to IT professionals and developers. That said, this type of a tool can also be leveraged by the bad guys. As such, it makes sense to target certain types of behaviors that are not very common under normal circumstance, but can see elevated usages by threat actors when they are moving through your environments. I’ve added four rules to the next version of Security Monitoring to alert on suspicious behavior. Three are (at least after initial rounds of testing) on by default. The fourth is off and if noise is a problem, will likely need to remain off. I would also note that I wouldn’t be surprised if more of these ends up being turned off. PowerShell is used on the back end by a number of applications, and as such, I wouldn’t be surprised to see some of this being done as normal behavior or via design in heavily scripted environment. In that case, you may need to turn these off altogether or simply override for particular machines. This can, however, provide a nice defense in depth posture. It will also help the IA folks reviewing these alerts see what is actually going on in production and decide if these practices should be rethought.
First, as goes without saying, you need Process creation auditing turned on as well as the GPO setting to include command line parameters in audit events set. If you’re already following me or using this solution, you’ve probably already done this. For record, I do keep a public version of the GPOs I’m using here. These are simply auditing GPOs applied at the domain level. But it’s worth emphasizing that a lot of the detection that has been built into this tool requires this auditing to be turned on.
Rule 1: PowerShell script run natively to bypass existing execution policy
In this particular rule, we’re looking for PowerShell scripts being run with a specific execution policy switch. This allows scripts to run regardless of execution policy settings. This can be by design in a user environment, so simply seeing this doesn’t mean that much. That said, I’m tracking 4688 events that are generated by ‘powershell.exe’ with the –ExecutionPolicy switch set to either bypass or unrestricted. This is also something that could generate noise. SCOM is an offender here, and it’s default install path is excluded for noise reduction purposes.
Rule 2: PowerShell used to Invoke a Remote Expression
I would hope that this is not used with much frequency in a typical environment. Effectively, PowerShell can be leveraged to run remote code. Threat actors love this, as they can effectively use their scripts to connect to an http/https share they have online and execute their custom malware. The best part is they can run this in memory only, making it even harder for AV scanners to detect them. Again, we are looking for 4688 events generated by PowerShell. I’m looking for the “Downloadstring” method and an http or https pattern in the command line. I wouldn’t expect to see this one happen often, so for now, it’s on.
Rule 3: PowerShell used to Invoke an Encoded Command
This is another one that I wouldn’t expect to see run that frequently. Basically, you can convert any text to a base 64 encoded string. This again can be normal, as it gets around formatting issues that can plague script writers or people like me who aren’t PowerShell experts. With that said, however, the bad guys can use this to hide what they are doing from security software, AV, or security analysts. As such, this rule will generate an alert whenever PowerShell is run with the –ENC or –EncodedCommand switches. Like the remote expression rule above, I don’t see this as something that will happen a lot, but it’s possible that this is legitimate.
Rule 4: PowerShell Running Only in Memory
Simply put, this is a PowerShell script runs in memory instead of on disk. It’s run using the –NoProfile or –Nop switches. I suspect that this is something that could generate noise. In testing, SCOM was a big one here, which makes sense as MPs run PowerShell scripts. I would not be surprised if other applications such as Exchange generate noise here too.
As always, if you want to test this, reach out to me on Linked In.