Software Restriction Policy - Constrained Language Mode
Excerpt from this article ‘Constrained PowerShell’ https://blogs.msdn.microsoft.com/powershell/2015/06/09/powershell-the-blue-team:
"In version 5, Power Shell now reduces its functionality to "Constrained Mode" for both interactive input and user-authored scripts when it detects that Power Shell scripts have an ‘Allow Mode’ policy applied to them. Constrained Power Shell limits the language mode to Constrained Language (as described in aboutLanguageModes), a mode first introduced for Windows RT.
Constrained Language doesn’t limit the capability of the core Power Shell language – familiar techniques such as variables, loops, and functions are all supported. It does, however, limit the extended language features that can lead to unverifiable code execution such as direct .NET scripting, invocation of Win32 APIs via the Add-Type cmdlet, and interaction with COM objects.
Scripts that are allowed by the AppLocker policy (for example: signed by the enterprise’s trusted code signing certificate, or in a trusted directory) are not subject to Constrained Language. They have access to the extended capabilities of the Power Shell language disallowed by Constrained Language. This includes unverifiable extensions such as .NET scripting, and invocation of Win32 APIs."
Upon launching a PowerShell script as a non-admin on a computer running Windows 7 Pro with SP1 where a Software Restriction Policy is enabled and the security level is set to ‘Disallowed’ and the enforcement is set to apply to ‘All users except local administrators’, the script runs in Constrained Language mode.
The excerpt above states that a script is not subjected to Constrained Language mode if it has been allowed by an AppLocker policy. However, no such provision has been made for Software Restriction Policies (AppLocker’s predecessor), as creating a path rule to the script location with the security level set to ‘Unrestricted’ has no effect, the script continues to run in Constrained Language mode.
I have implemented a workaround which is to create a path rule to ‘%temp%’ with the security level set to ‘unrestricted’. I discovered this workaround on the following sites: https://social.technet.microsoft.com/Forums/en-US/e81bd4e8-d5e0-4aa9-a1af-928e536c2a69/ps-constrainedlanguage-mode-on-windows-10-with-srp?forum=winserverpowershell and https://community.spiceworks.com/topic/1451109-srp-whitelist-causing-odd-behavior-in-powershell-v5
Naturally, unblocking ‘%temp%’ within an SRP is highly undesirable, therefore the workaround suggests creating a separate block-rule for each extension in %temp%, eg: "%temp%*.exe". I have found that this does not work and that executables continue to launch. It appears that the path rule to ‘%temp%’ with the security level set to ‘unrestricted’ takes precedence.
Therefore with no sensible way to implement a Constrained Mode bypass, users of Software Restriction Policies that require a script to launch with Full Language mode have no choice but to make a modification to their SRP with a detrimental impact on security.

6 comments
-
LUVoice commented
And of course, authorised adminstrators need to have the full language capability, so need a better way to allow them.
-
LUVoice commented
Powershell running with 3rd party application whitelisting (awl) tool - all powershell execution starts with the temp file creation, block. I have an authorised script (the script itself is cleared to run through the awl tool, and it is safe - it does not use any unconstrained language features. But there is no command-line option to start in constrained language mode.
I want to avoid the time delay, and the clogging up of our awl tool's log with events, from creating and running these temporary files (%TEMP%\abcdefab.abc.ps1), by being able to call the script in constrained language mode to start with, on the powershell.exe command line.
Is that simple enough?
-
Craig Jones commented
"%temp%\*\" and "%temp%\*.exe" worked for me
-
Steve commented
I would like to see a general way to turn on/off 1) Constrained Mode and 2) exceptions (like signed by the enterprise’s trusted code signing certificate, or in a trusted directory) so we can use this with other app whitelist scenarios or 3rd party software.
Setting the __PSLockdownPolicy system variable (via Group Policy or DSC) gets part way to the first but it is easy for an elevated user to change (at least temporarily). -
Vadims Podāns commented
-
Ilya commented
I'll put my 2 cents: https://social.technet.microsoft.com/Forums/en-US/3aeee993-c74b-4c78-b8a4-d5e50b3a5b9b/wmf-50-languagemode-srp?forum=winserverpowershell
Not all RD module commandlets are worked!