PowerShell is a built-in scripting language and a command-line executor developed by Microsoft to provide a better interface for system administrators to simplify and automate administrative tasks.

PowerShell's power makes it a useful tool for attackers for fileless attacks that are hard to prevent and detect.


In the previews blog post we've mentioned the different possible stages of a PowerShell attack. In this post, we'll discuss possible mitigations for PowerShell attacks:

  1. Protecting PowerShell scripts
  2. Preventing lateral movement
  3. Detecting PowerShell attack and preventing persistence


PowerShell Security Best Practices


Protect your PowerShell scripts:

The PowerShell script is basically a simple text file with a .ps1 extension. This file will run once you call it in the console. The PowerShell user can control which scripts will run. This can be dangerous when the user has malicious intentions, therefore there are three actions you can perform to minimize malicious scripts:


  1. Set the PowerShell execution policy:

Microsoft restricts PowerShell scripts with an execution policy to prevent users from accidentally executing scripts they shouldn't execute. These restrictions also help prevent people from running malicious scripts in social- engineering campaigns.


To set the execution policy, use the Set-ExecutionPolicy cmdlet, and choose one of the following options:


  1. Restricted: this is the most restrictive option. Choosing this option won't allow configuration files to be loaded and scripts to run. However, you'll still be able to run individual commands in the PowerShell console.
  2. AllSigned: choosing the option will mean that all scripts and configuration files must be digitally signed by a trusted publisher. Signing is done using a code-signing certificate.
  3. RemosteSigned: choosing this option will mean that when a script or a configuration file is downloaded from the Internet, it must be digitally signed. However, scripts and configuration files running locally on your computer can be loaded without being signed.
  4. Unrestricted: choosing this option will mean that all scripts can run, and all configuration files can be loaded. This is the least restrictive, and thereby riskiest, option.


The default execution policy setting is Restricted (except for Windows Server 2012 R2, where it is Remote- Signed). This default policy allows users to run only interactive PowerShell sessions and single commands, regardless of the origin of the scripts of whether they are signed and trusted.


The preferable execution policy for script protection, that will still allow you to use PowerShell is AllSigned.


  1. Create an X.509 Certificate:

After setting the execution policy to AllSigned, you'll need to singe your file. To do that, you'll need to create a code-signing X.509 certificate. The X.509 is a cryptography standard that you can either purchase from a public certificate authority or create it yourself.


  1. Sign the PowerShell script:

After creating the certificate, use it to sign your scripts. You'll need to use the Set-AuthenticodeSignature cmdlet and specify the script file to sign and your certificate when signing the file.

When running a script that is digitally signed, you'll have the option to choose whether it is indeed safe to run it. You can either choose to never run the file, not to run it this time, run it once, or always run it.


Note: if you use a private certificate that you created to sign your files, it's still possible for an attacker to use your certificate to sign malicious scripts. To avoid that and provide further protection, export your code-signing certificate to a .pfx file, and use that file to sign your scripts.


  1. Use AppLocker to disable PowerShell scripts:

AppLocker is a useful way to whitelist applications and scripts. You can use the Script Rules policies to create an allowed rule only for a specific folder. This will ensure that only files from this folder will be executed.

Another possible, but a little less effective option, is to use Executable Rules to limit which file can be executed by its path or signature. By creating signature rules for PowerShell and PowerShell_ISA, you can restrict nonadministrators from running scripts. Note that this method can be easily bypassed by attackers by using tools such as PowerShell Empire.


  1. Configure PowerShell to use 'Constrained Mode':

PowerShell Constrained language is designed to support PowerShell's daily activities yet restrict access to sensitive language elements that can invoke arbitrary Windows APIs. PowerShell Constrained mode is designed to work with application control solutions, which is an effective way to minimize risks to your network.


Constrained language mode limits the capability of PowerShell to support features such as .Net & Windows API calls and COM access. Disabling this functionality will stop most PowerShell attack tools since they rely on these methods.


Prevent Lateral Movement:

Lateral movement is not only used in PowerShell attacks. But, there are several things you can do to minimize the risk for attackers to use PowerShell based lateral movement methods:


  1. Disable WinRM where not needed to prevent PSSession- the PSSession command allows interactive remote PowerShell session, which the user can use to execute commands remotely. This option depends on the Windows Remote Management (WinRM) service. The WinRM must be enabled in order to use this method.
    Set 'Allow remote server management through WinRM' configuration to Disable wherever possible. Where there is no option for this configuration, configure the WinRM in the most secure fashion possible.
  2. Set 'Allow Remote Shell Access' to Disable- This policy setting allows you to manage the configuration of remote access to all supported shells to execute scripts and commands. By disabling it you'll minimize the risk of attackers using it maliciously.
  3. Disable Windows Server Message Block (SMB)- Many of the methods that leverage PowerShell to move laterally are using Windows Server Message Block (SMB). Disabling SMB will prevent attackers from using tools such as PsExec.
  4. Set a least privileges policy- if the attacker has write privileges to PowerShell profile files on a remote computer, he can add malicious code to them.


The different stages of a PowerShell attack


Detect PowerShell attacks and prevent persistence:

PowerShell is known for having significant activity-logging capabilities, that can be used to detect and mitigate against the abuse of this tool. Here are three activity-logging features that administrators can use to analyze PowerShell activity to determine the extent of an intrusion:


  1. Module logging- by setting the module logging to enabled, it will record the execution of the different modules in the PowerShell, including deobfuscate codes and outputs. It is recommended to enter a value of '*' to capture everything for logging purposes.
  2. Script Block logging- when enabling this setting, you'll generate logs when script blocks are invoked. This may be a helpful tool for attack detection but can impose other security risks. Read here about the potential vulnerability when enabling this option.
  3. PowerShell Transcription- when enabling PowerShell Transcription, all input and output from a PowerShell session will be recorded. Note that this will not record scripts or direct commands.



PowerShell is a powerful tool for attackers to use in several ways and stages in an attack. But many of these options can be blocked by setting secure configuration to services and components in your system. Before searching for but tools that can increase your PowerShell security, make sure your system is properly hardened.






You might be interested