Much of the ‘attack’ style PowerShell uses elements that would be blocked via the use of setting PowerShell to Constrained language mode. There are basically a few ways of setting PowerShell to use Constrained Language mode with the recommended method being to utilize either DeviceGuard or AppLocker in enforced mode (with WMF 5+/PowerShell 5+), however the quicker method is to make use of a System Environment variable called __PSLockDownPolicy to configure this.So the first thing to make note of with regards to __PSLockDownPolicy is that this setting is completely undocumented from a Microsoft perspective. Yes, I’m a Microsoft employee and No this is not official documentation as to how this works from a Product Group but just my observations on how it seems to work from testing. Considering that this is undocumented this typically means unsupported as well so my guess is if you called up / opened a ticket online with CSS odds are you would probably hit a brick wall at some point with regards to doing something not officially supported by us.When I was first looking at this setting the initial thing I was told was that it was pointless as User Environment variables override System Environment Variables i.e. all the attacking process would need to do was run a set __PSLockDownPolicy= to configure this variable to something else more conducive to that user and start a PowerShell session post setting the User Environment variable to a wanted value and they would be able to do whatever they wanted to anyway with Full Language mode again. Well… once I started testing I quickly found this not to be the case. I’ve tested trying to use this as a User Environment variable and it doesn’t even seem to read it, I’ve tried the User Environment variable as a possible method of overriding the System Environment variable and that does not work either. I decided to ProcMon it and the procmon logs show that when PoSH starts it always reads in the system environment variable from the reg key HKLMSystemCurrentControlSetControlSESSION MANAGEREnvironment__PSLockdownPolicy that defines it and never queries for a User Environment variable with this name. So the end story here is that this absolutely works and that it cannot be overridden easily by an attacking piece of code in user mode space.
But there are ways around this according to
Remove-ItemProperty -path “HKLM:SYSTEMCurrentControlSetControlSession ManagerEnvironment” -name __PSLockdownPolicy