Windows 10 comes by default with the latest PowerShell version which is 5.x. This is fine but the problem is that for downward compatibility reasons, version 2 is also still included and active. Version 2 was released in 2009 and a deprecation was announced in August 2017 but it’s unclear when it’s actually going to be retired. If you look in Turn Windows Features On or Off in the Fall Creators Release (1709), you still find it activated.
The issue is that scripts that are run in the PowerShell 2.0 context leave very few traces. If you open the event log and navigate to Application and Services Logs → Microsoft → Windows → PowerShell → Operational, you only see that a script was started but not what it did.
With PowerShell 5, several security enhancements have been introduced which includes logging of suspicious commands (default) and additional logging options that can be configured by GPO (Administrative Templates → Windows Components → Windows PowerShell).
For this reason, PowerShell 2 is attractive for attackers who want to avoid being discovered. All they have to do is to start their code by “powershell -version 2 somescript.ps1”
What to do?
To ensure that you can track powershell code that was executed in your environment, you should execute a PowerShell command on Windows 8.1 and 10 machines that disables version 2:
powershell Disable-WindowsOptionalFeature -Online –FeatureName MicrosoftWindowsPowerShellV2Root –norestart
To validate that this was successful, you may run
powershell Get-WindowsOptionalFeature -Online –FeatureName MicrosoftWindowsPowerShellV2Root or execute powershell -version 2 (Output: “The Windows PowerShell 2 engine is not installed on this computer”)
There’s unfortunately no supported way to switch version 2 off in Window 7.
Consider also configuring the PowerShell GPOs. Here’s a short explanation of the 3 relevant settings:
- “Turn on PowerShell Script Block Logging”: Enables logging of all PowerShell script input to the PowerShell engine. Each block is only listed once (so don’t worry about loops) unless you select the “Log script block invocation start / stop events” (better don’t). It seems to be reasonable to configure at least this setting to be able to trace which code was run.
- “Turn on Module logging”: Requires a configuration of the modules to be included. Generates a large number of events under the ID 4103. I wouldn’t suggest to configure this option in general.
- “Turn on PowerShell Transcription”: Logs the input and output of Windows PowerShell commands to text files. Probably not helpful in most cases.
Unfortunately, you can turn PowerShell 2.0 on again if you have admin privileges and there doesn’t seem to be an easy way to prevent this, therefore only the deprecation will guarantee that hackers can’t take advantage of the 2.0 engine.
Links:
Greater Visibility Through PowerShell Logging, https://www.fireeye.com/blog/threat-research/2016/02/greater_visibilityt.html
PowerShell Security at Enterprise Customers, https://blogs.msdn.microsoft.com/daviddasneves/2017/05/25/powershell-security-at-enterprise-customers/
Windows PowerShell 2.0 Deprecation,
https://blogs.msdn.microsoft.com/powershell/2017/08/24/windows-powershell-2-0-deprecation)