PowerShell is a robust tool that can control almost all components of Windows and applications such as Exchange. It can therefore cause great damage in the hands of attackers. Its Constrained Language mode blocks dangerous features, thereby preventing misuse.

By default, PowerShell operates in Full Language mode, in which all functions are available. This includes access to all language elements, cmdlets, and modules, as well as the file system and the network.

Blocked functions ^

The ability to instantiate COM and .NET objects or to generate new data types (with Add-Type) that have been defined in other languages is a particularly dangerous PowerShell capability. Constrained Language mode blocks these features (except access to permitted .NET classes). It also prevents the declaration of classes, usage of configuration management with DSC, and XAML-based workflows (see Microsoft Docs for a complete list).

Enabling Constrained Language mode ^

A simple way to switch to Constrained Language mode is to set the relevant variable to the required value:

$ExecutionContext.SessionState.LanguageMode = "ConstrainedLanguage"
Displaying and changing the Language Mode via the variable $ExecutionContext.SessionState.LanguageMode

Displaying and changing the Language Mode via the variable $ExecutionContext.SessionState.LanguageMode

It is obvious that setting this variable does not provide any real protection. You may not be able to change it back to FullLanguage in the same session; however, a new PowerShell session will offer the full range of languages features.

Switching to Constrained mode with an environment variable ^

Less easy to overcome is the (undocumented) system environment variable __PSLockDownPolicy, if you set it to the value 4. As a result, PowerShell will start in the secure language mode, regardless of whether it's just a command line or the ISE.

Setting environment variable PSLockDownPolicy interactively

Setting environment variable PSLockDownPolicy interactively

In centrally managed environments, you will probably use Group Policies to set the system variable.

Setting environment variable PSLockDownPolicy via GPO

Setting environment variable PSLockDownPolicy via GPO

A disadvantage of this procedure is that it always affects all users of a computer, including administrators. However, administrators may temporarily remove the environment variable until the GPO becomes effective again. But this is quite cumbersome and definitely not a good solution.

Furthermore, used in this way, it is not a security feature supported by Microsoft and is relatively easy to circumvent, as shown by Matt Graeber in this tweet. Nevertheless, it might thwart most opportunist attacks.

Strict enforcement of Constrained Language mode on a local computer thus requires the use of a software execution restriction, such as AppLocker or Windows Defender Application Control. In a remote session, however, it can be enforced through session configuration.

Automatically detecting an execution constraint ^

Since version 5, PowerShell recognizes automatically whether it should switch to Constrained Language mode based on script rules. To do so, it creates a module and a script (with a name following the pattern __PSSCRIPTPOLICYTEST_LQU1DAME.3DD.PS1) under $env:temp and tries to execute them. If AppLocker or another tool blocks this attempt, PowerShell starts in Constrained Language mode.

The event log shows whether the test scripts were executed successfully

The event log shows whether the test scripts were executed successfully

The effect of this mechanism can easily be seen in AppLocker's event log. AppLocker logs the creation and execution of these test files with the ID 8005 (success) or 8007 (execution blocked) under Applications and Services Log > Microsoft > Windows > AppLocker > MSI and Script.

Configuring AppLocker ^

If you use AppLocker for this task, you have to create a new GPO and then edit it in the GPO editor. Navigate to Computer Configuration > Policies > Windows Settings > Security Settings > Application Control Policies > AppLocker and follow the Configure rule enforcement link. In the dialog that appears, select the Script rules option.

Enabling rule enforcement for scripts in AppLocker

Enabling rule enforcement for scripts in AppLocker

In order for AppLocker to block applications on the target systems, the Application Identity service must be running. It is not active by default and does not start up when the system is booting. You can change it to start type Automatic either interactively using the MMC snapin services or from the command line:

sc config AppIDSvc start=auto
Setting the start type for the Application Identity service to automatic

Setting the start type for the Application Identity service to automatic

For central management of this Windows service, the use of Group Policy is recommended.

Defining rules ^

Finally, rules must be defined that block the start of scripts in the Temp directory. To do this, simply switch to Script Rules below AppLocker and select Create Default Rules from the context menu.

Creating default rules for scripts in AppLocker

Creating default rules for scripts in AppLocker

They allow standard users to execute scripts only from the Windows or Program Files directories, i.e., in locations where users cannot store any files themselves. Administrators are explicitly exempted from this restriction by a separate rule.

Activating Constrained Language mode via SRP ^

AppLocker is a feature found exclusively in the Enterprise and Education editions. The Pro edition can use the Software Restriction Policies (SRP) instead. Again, you just have to ensure that the two test scripts cannot be executed in the %temp% directory. To do this, create a GPO, open it in the editor, and navigate to Computer Configuration > Policies > Windows Settings > Security Settings > Software Restriction Policies.

Enter file extensions for PowerShell in the Software Restriction Policies

Enter file extensions for PowerShell in the Software Restriction Policies

Here, you create a new policy. In the first step, you add the extensions ps1 and psm1 to the list of the designated file types.

Creating a new path rule for the software restriction

Creating a new path rule for the software restriction

Then select Additional Rules > New Path Rule to create a new rule. Here, you enter %temp% as the Path and leave the Security level setting set to Disallowed.

Defining the path rule for the Temp directory

Defining the path rule for the Temp directory

Preventing PowerShell 2.0 circumvention ^

Regardless of whether you choose the environment variable, AppLocker, or Software Restriction Policies, you will need to remove PowerShell 2.0 from the machines on which you want to enforce Constrained Language mode.

PowerShell 2.0 is an optional feature starting with Windows 8 and Server 2012 and is enabled by default

PowerShell 2.0 is an optional feature starting with Windows 8 and Server 2012 and is enabled by default

Constrained Language mode was introduced with PowerShell 3.0 and can easily be bypassed by a hacker switching to an older version. All he would need to do is enter the command:

powershell.exe -version 2.0

You can check whether this old version is still activated on a PC by entering:

Subscribe to 4sysops newsletter!

Get-WindowsOptionalFeature -Online -FeatureName MicrosoftWindowsPowerShellV2

However, you can only uninstall it on Windows 8 and Server 2012 or later, where PowerShell 2.0 is an optional feature.

avatar
2 Comments
  1. Ty 2 years ago

    Is there any value then running both "__PSLockDownPolicy" and applocker at the same time to enforce restriction policies, or is the applocker policies enough?

  2. Steve 7 months ago

    Hi Wolfgang, 

    Are you aware of big corporates running PS in a Constrained Language mode. I appreciate you could put it in a lab or against a few PCs. But is it possible in a large corporate with 10,000+ workstations for an example. What I'm seeing is SCCM is firing a massive number of PS1 files. 

    Do you push this out to say sales , marketing , HR ,Legal etc etc But not the IT crowd per say.

    Regards Steve  

Leave a reply

Please enclose code in pre tags

Your email address will not be published. Required fields are marked *

*

© 4sysops 2006 - 2022

CONTACT US

Please ask IT administration questions in the forums. Any other messages are welcome.

Sending

Log in with your credentials

or    

Forgot your details?

Create Account